Commit 302677ac for libheif

commit 302677ac16af81722d1e30cf1be4ffa5219bbfcf
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Wed Mar 4 14:07:33 2026 +0100

    heifio: add decoder for raw input files

diff --git a/examples/heif_enc.cc b/examples/heif_enc.cc
index 73d52411..dffcdc8c 100644
--- a/examples/heif_enc.cc
+++ b/examples/heif_enc.cc
@@ -48,6 +48,7 @@
 #include "heifio/decoder_jpeg.h"
 #include "heifio/decoder_png.h"
 #include "heifio/decoder_tiff.h"
+#include "heifio/decoder_raw.h"
 #include "heifio/decoder_y4m.h"

 #include "benchmark.h"
@@ -151,6 +152,9 @@ heif_output_nclx_color_profile_preset output_color_profile_preset = heif_output_

 std::string property_pitm_description;

+RawImageParameters raw_input_params;
+bool force_raw_input = false;
+
 // for benchmarking

 #if !defined(_MSC_VER)
@@ -206,6 +210,11 @@ const int OPTION_SET_OMAF_IMAGE_PROJECTION = 1038;
 #endif
 const int OPTION_ADD_COMPATIBLE_BRAND = 1039;
 const int OPTION_UNIF = 1040;
+const int OPTION_RAW_WIDTH = 1041;
+const int OPTION_RAW_HEIGHT = 1042;
+const int OPTION_RAW_TYPE = 1043;
+const int OPTION_RAW_ENDIAN = 1044;
+const int OPTION_RAW = 1045;

 static option long_options[] = {
     {(char* const) "help",                    no_argument,       0,              'h'},
@@ -279,6 +288,11 @@ static option long_options[] = {
 #endif
     {(char* const) "add-compatible-brand",        required_argument,       nullptr, OPTION_ADD_COMPATIBLE_BRAND},
     {(char* const) "unif",                      no_argument,             nullptr, OPTION_UNIF},
+    {(char* const) "raw",                    no_argument,             nullptr, OPTION_RAW},
+    {(char* const) "raw-width",               required_argument,       nullptr, OPTION_RAW_WIDTH},
+    {(char* const) "raw-height",              required_argument,       nullptr, OPTION_RAW_HEIGHT},
+    {(char* const) "raw-type",                required_argument,       nullptr, OPTION_RAW_TYPE},
+    {(char* const) "raw-endian",              required_argument,       nullptr, OPTION_RAW_ENDIAN},
     {0, 0,                                                           0,  0}
 };

@@ -356,6 +370,13 @@ void show_help(const char* argv0)
             << "  -P, --params                   show all encoder parameters and exit, input file not required or used.\n"
             << "  -p NAME=VALUE                  set encoder parameter\n"
             << "\n"
+            << "raw input:\n"
+            << "      --raw                      force raw pixel data input (for files without .raw/.img suffix)\n"
+            << "      --raw-width #              width of raw input image (computed from file size if omitted)\n"
+            << "      --raw-height #             height of raw input image (computed from file size if omitted)\n"
+            << "      --raw-type TYPE            pixel data type: uint8, sint8, uint16, sint16, uint32, sint32, float32, float64\n"
+            << "      --raw-endian ENDIAN        byte order of input data: little (default), big\n"
+            << "\n"
             << "color profile:\n"
             << "      --color-profile NAME       use a color profile preset for the output. Valid values are:\n"
             << "                                    custom:     (default) use the provided matrix_coefficients, colour_primaries, transfer_characteristic\n"
@@ -709,7 +730,7 @@ InputImage load_image(const std::string& input_filename, int output_bit_depth)

   enum
   {
-    PNG, JPEG, Y4M, TIFF
+    PNG, JPEG, Y4M, TIFF, RAW
   } filetype = JPEG;
   if (suffix == "png") {
     filetype = PNG;
@@ -720,6 +741,13 @@ InputImage load_image(const std::string& input_filename, int output_bit_depth)
   else if (suffix == "tif" || suffix == "tiff") {
     filetype = TIFF;
   }
+  else if (suffix == "raw" || suffix == "img") {
+    filetype = RAW;
+  }
+
+  if (force_raw_input) {
+    filetype = RAW;
+  }

   if (filetype == PNG) {
     heif_error err = loadPNG(input_filename.c_str(), output_bit_depth, &input_image);
@@ -744,6 +772,13 @@ InputImage load_image(const std::string& input_filename, int output_bit_depth)
     }
   }
 #endif
+  else if (filetype == RAW) {
+    heif_error err = loadRAW(input_filename.c_str(), raw_input_params, &input_image);
+    if (err.code != heif_error_Ok) {
+      std::cerr << "Can not load raw input image: " << err.message << '\n';
+      exit(1);
+    }
+  }
   else {
     heif_error err = loadJPEG(input_filename.c_str(), &input_image);
     if (err.code != heif_error_Ok) {
@@ -1644,6 +1679,24 @@ int main(int argc, char** argv)
       case OPTION_UNIF:
         option_unif = true;
         break;
+      case OPTION_RAW:
+        force_raw_input = true;
+        break;
+      case OPTION_RAW_WIDTH:
+        raw_input_params.width = atoi(optarg);
+        break;
+      case OPTION_RAW_HEIGHT:
+        raw_input_params.height = atoi(optarg);
+        break;
+      case OPTION_RAW_TYPE:
+        if (!parse_raw_pixel_type(optarg, &raw_input_params.datatype, &raw_input_params.bit_depth)) {
+          std::cerr << "Unknown raw pixel type: " << optarg << "\n";
+          exit(5);
+        }
+        break;
+      case OPTION_RAW_ENDIAN:
+        raw_input_params.big_endian = (std::string(optarg) == "big");
+        break;
     }
   }

diff --git a/heifio/CMakeLists.txt b/heifio/CMakeLists.txt
index 920eeca5..b1aa607a 100644
--- a/heifio/CMakeLists.txt
+++ b/heifio/CMakeLists.txt
@@ -3,6 +3,8 @@ include_directories(${libheif_BINARY_DIR} ${libheif_SOURCE_DIR}/libheif/api ${li

 add_library(heifio STATIC
         decoder.h
+        decoder_raw.cc
+        decoder_raw.h
         decoder_y4m.cc
         decoder_y4m.h
         encoder.h