Commit bed5192b for libheif
commit bed5192b3fc3c69025c792136604ce3df61f1005
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Fri Mar 20 23:42:44 2026 +0100
heif-enc: add options to transform input image
diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc
index 6666d87c..bb4b486b 100644
--- a/examples/heif_enc.cc
+++ b/examples/heif_enc.cc
@@ -125,6 +125,7 @@ bool encode_sequence = false;
bool option_unif = false;
bool use_video_handler = false;
bool option_component_content_ids = false;
+heif_orientation transform = heif_orientation_normal;
std::string option_mime_item_type;
std::string option_mime_item_file;
std::string option_mime_item_name;
@@ -163,6 +164,17 @@ std::string property_pitm_description;
RawImageParameters raw_input_params;
bool force_raw_input = false;
+std::optional<long> parse_int(const char* s)
+{
+ char* end;
+ long val = strtol(s, &end, 10);
+ if (*end != '\0' || end == s) {
+ return {};
+ }
+ return val;
+}
+
+
// for benchmarking
#if !defined(_MSC_VER)
@@ -223,6 +235,9 @@ const int OPTION_RAW_HEIGHT = 1042;
const int OPTION_RAW_TYPE = 1043;
const int OPTION_RAW_ENDIAN = 1044;
const int OPTION_RAW = 1045;
+const int OPTION_DO_ROTATE = 1046;
+const int OPTION_DO_FLIP_H = 1047;
+const int OPTION_DO_FLIP_V = 1048;
#if HEIF_ENABLE_EXPERIMENTAL_FEATURES
@@ -365,6 +380,9 @@ static option long_options[] = {
{(char* const) "clli", required_argument, 0, OPTION_SET_CLLI},
{(char* const) "pasp", required_argument, 0, OPTION_SET_PASP},
{(char* const) "premultiplied-alpha", no_argument, &premultiplied_alpha, 1},
+ {(char* const) "rotate-cw", required_argument, 0, OPTION_DO_ROTATE},
+ {(char* const) "flip-h", no_argument, 0, OPTION_DO_FLIP_H},
+ {(char* const) "flip-v", no_argument, 0, OPTION_DO_FLIP_V},
{(char* const) "plugin-directory", required_argument, 0, OPTION_PLUGIN_DIRECTORY},
{(char* const) "benchmark", no_argument, &run_benchmark, 1},
{(char* const) "enable-metadata-compression", required_argument, 0, OPTION_METADATA_COMPRESSION},
@@ -510,6 +528,8 @@ void show_help(const char* argv0)
<< " --enable-two-colr-boxes will write both an ICC and an nclx color profile if both are present\n"
<< " --clli MaxCLL,MaxPALL add 'content light level information' property to all encoded images\n"
<< " --pasp h,v set pixel aspect ratio property to all encoded images\n"
+ << " --rotate-cw # rotate input image by 0, 90, 180, 270 degrees (clock-wise)\n"
+ << " --flip-h / --flip-v flip input image horizontally or vertically\n"
<< "\n"
<< "tiling:\n"
<< " --cut-tiles # cuts the input image into square tiles of the given width\n"
@@ -1767,6 +1787,29 @@ int main(int argc, char** argv)
}
break;
}
+ case OPTION_DO_ROTATE: {
+ auto angle = parse_int(optarg);
+ if (!angle || (*angle != 0 && *angle != 90 && *angle != 180 && *angle != 270)) {
+ std::cerr << "Invalid rotation angle. Must be 0, 90, 180, or 270.\n";
+ return 5;
+ }
+ if (*angle == 90) {
+ transform = heif_orientation_concat(transform, heif_orientation_rotate_90_cw);
+ }
+ else if (*angle == 180) {
+ transform = heif_orientation_concat(transform, heif_orientation_rotate_180);
+ }
+ else if (*angle == 270) {
+ transform = heif_orientation_concat(transform, heif_orientation_rotate_270_cw);
+ }
+ break;
+ }
+ case OPTION_DO_FLIP_H:
+ transform = heif_orientation_concat(transform, heif_orientation_flip_horizontally);
+ break;
+ case OPTION_DO_FLIP_V:
+ transform = heif_orientation_concat(transform, heif_orientation_flip_vertically);
+ break;
case OPTION_ADD_MIME_ITEM:
option_mime_item_type = optarg;
break;
@@ -2298,7 +2341,7 @@ int do_encode_images(heif_context* context, heif_encoder* encoder, heif_encoding
options->save_alpha_channel = (uint8_t) master_alpha;
options->output_nclx_profile = nclx;
- options->image_orientation = input_image.orientation;
+ options->image_orientation = heif_orientation_concat(input_image.orientation, transform);
if (premultiplied_alpha) {
heif_image_set_premultiplied_alpha(image.get(), premultiplied_alpha);