Commit 291f9775 for libheif

commit 291f9775cd9cf351eccd62241d795812590cf09b
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Sat May 2 14:19:58 2026 +0200

    pixelimage: typed component getters now return stride in bytes

diff --git a/libheif/api/libheif/heif_uncompressed.h b/libheif/api/libheif/heif_uncompressed.h
index a406ff26..72d68b0f 100644
--- a/libheif/api/libheif/heif_uncompressed.h
+++ b/libheif/api/libheif/heif_uncompressed.h
@@ -323,6 +323,9 @@ heif_error heif_image_add_component(heif_image* image,
                                     int bit_depth,
                                     uint32_t* out_component_idx);

+// All component-data getters return the row stride in bytes via out_stride
+// (regardless of the element type). When using a typed pointer for indexing,
+// divide the stride by sizeof(element).
 LIBHEIF_API
 const uint8_t* heif_image_get_component_readonly(const heif_image*, uint32_t component_idx, size_t* out_stride);

diff --git a/libheif/pixelimage.cc b/libheif/pixelimage.cc
index fcc6a0d2..2259af6b 100644
--- a/libheif/pixelimage.cc
+++ b/libheif/pixelimage.cc
@@ -1203,6 +1203,7 @@ void HeifPixelImage::fill_plane(heif_channel dst_channel, uint16_t value)
     uint16_t* dst;
     size_t dst_stride = 0;
     dst = get_channel<uint16_t>(dst_channel, &dst_stride);
+    dst_stride /= sizeof(uint16_t);

     for (uint32_t y = 0; y < height; y++) {
       for (uint32_t x = 0; x < width * num_interleaved; x++) {
@@ -2019,6 +2020,7 @@ Error HeifPixelImage::scale_nearest_neighbor(std::shared_ptr<HeifPixelImage>& ou
       uint16_t* out_data = out_img->get_channel<uint16_t>(heif_channel_interleaved, &out_stride);

       in_stride /= 2;
+      out_stride /= 2;

       for (uint32_t y = 0; y < out_h; y++) {
         uint32_t iy = y * m_height / height;
@@ -2075,6 +2077,7 @@ Error HeifPixelImage::scale_nearest_neighbor(std::shared_ptr<HeifPixelImage>& ou
         uint16_t* out_data = out_img->get_channel<uint16_t>(channel, &out_stride);

         in_stride /= 2;
+        out_stride /= 2;

         for (uint32_t y = 0; y < out_h; y++) {
           uint32_t iy = y * m_height / height;
diff --git a/libheif/pixelimage.h b/libheif/pixelimage.h
index 1b46fe31..1b207d68 100644
--- a/libheif/pixelimage.h
+++ b/libheif/pixelimage.h
@@ -439,7 +439,7 @@ public:
     }

     if (out_stride) {
-      *out_stride = static_cast<int>(comp->stride / sizeof(T));
+      *out_stride = static_cast<int>(comp->stride);
     }

     return static_cast<T*>(comp->mem);
@@ -516,7 +516,7 @@ public:
     }

     if (out_stride) {
-      *out_stride = comp->stride / sizeof(T);
+      *out_stride = comp->stride;
     }
     return static_cast<T*>(comp->mem);
   }
diff --git a/tests/pixel_data_types.cc b/tests/pixel_data_types.cc
index 244295c2..96446313 100644
--- a/tests/pixel_data_types.cc
+++ b/tests/pixel_data_types.cc
@@ -37,6 +37,7 @@ TEST_CASE( "uint32_t" )

   size_t stride;
   uint32_t* data = image.get_channel<uint32_t>(heif_channel_Y, &stride);
+  stride /= sizeof(uint32_t);

   REQUIRE(stride >= 3);
   REQUIRE(image.get_width(heif_channel_Y) == 3);
@@ -63,6 +64,7 @@ TEST_CASE( "uint32_t" )
   rot = *rotationResult;

   data = rot->get_channel<uint32_t>(heif_channel_Y, &stride);
+  stride /= sizeof(uint32_t);

   REQUIRE(data[0*stride + 0] == 1000);
   REQUIRE(data[0*stride + 1] == 2000);
@@ -102,6 +104,7 @@ TEST_CASE( "uint32_t" )
   REQUIRE(crop->get_height(heif_channel_Y) == 1);

   data = crop->get_channel<uint32_t>(heif_channel_Y, &stride);
+  stride /= sizeof(uint32_t);

   REQUIRE(data[0*stride + 0] == 0);
   REQUIRE(data[0*stride + 1] == 2000);
@@ -114,6 +117,7 @@ TEST_CASE( "uint32_t" )
   REQUIRE(crop->get_height(heif_channel_Y) == 2);

   data = crop->get_channel<uint32_t>(heif_channel_Y, &stride);
+  stride /= sizeof(uint32_t);

   REQUIRE(data[0*stride + 0] == 0);
   REQUIRE(data[0*stride + 1] == 0xFFFFFFFFu);
@@ -132,6 +136,7 @@ TEST_CASE( "complex64_t" )

   size_t stride;
   heif_complex64* data = image.get_channel<heif_complex64>(heif_channel_Y, &stride);
+  stride /= sizeof(heif_complex64);

   REQUIRE(stride >= 3);
   REQUIRE(image.get_width(heif_channel_Y) == 3);
@@ -166,6 +171,7 @@ TEST_CASE( "image datatype through public API" )
   size_t stride;
   uint32_t* data = heif_image_get_component_uint32(image, comp_idx, &stride);
   REQUIRE(data != nullptr);
+  stride /= sizeof(uint32_t);

   REQUIRE(stride >= 3);
   REQUIRE(heif_image_get_component_bits_per_pixel(image, comp_idx) == 32);
diff --git a/tests/uncompressed_encode_multicomponent.cc b/tests/uncompressed_encode_multicomponent.cc
index 4481e153..bfd3fd76 100644
--- a/tests/uncompressed_encode_multicomponent.cc
+++ b/tests/uncompressed_encode_multicomponent.cc
@@ -261,6 +261,7 @@ static heif_image* create_and_fill_image(heif_component_datatype datatype, int b
     size_t stride = 0;
     T* data = get_component_ptr<T>(image, id, &stride);
     REQUIRE(data != nullptr);
+    stride /= sizeof(T);
     REQUIRE(stride >= kWidth);

     for (uint32_t y = 0; y < kHeight; y++) {
@@ -322,6 +323,7 @@ static void verify_image_data(const heif_image* image)
     size_t stride = 0;
     const T* data = get_component_ptr_readonly<T>(image, c, &stride);
     REQUIRE(data != nullptr);
+    stride /= sizeof(T);

     for (uint32_t y = 0; y < kHeight; y++) {
       for (uint32_t x = 0; x < kWidth; x++) {
@@ -472,6 +474,7 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
     size_t stride = 0;
     uint16_t* data = heif_image_get_component_uint16(image, idx0, &stride);
     REQUIRE(data != nullptr);
+    stride /= sizeof(uint16_t);
     for (uint32_t y = 0; y < kH; y++) {
       for (uint32_t x = 0; x < kW; x++) {
         data[y * stride + x] = static_cast<uint16_t>(y * kW + x + 100);
@@ -484,6 +487,7 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
     size_t stride = 0;
     uint16_t* data = heif_image_get_component_uint16(image, idx1, &stride);
     REQUIRE(data != nullptr);
+    stride /= sizeof(uint16_t);
     for (uint32_t y = 0; y < kH; y++) {
       for (uint32_t x = 0; x < kW; x++) {
         data[y * stride + x] = static_cast<uint16_t>((y * kW + x + 200) & kMaxVal14);
@@ -529,6 +533,7 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
     size_t stride = 0;
     const uint16_t* data = heif_image_get_component_uint16_readonly(decoded, idx0, &stride);
     REQUIRE(data != nullptr);
+    stride /= sizeof(uint16_t);
     for (uint32_t y = 0; y < kH; y++) {
       for (uint32_t x = 0; x < kW; x++) {
         uint16_t expected = static_cast<uint16_t>(y * kW + x + 100);
@@ -543,6 +548,7 @@ TEST_CASE("Mixed bpp: 16-bit and 14-bit components")
     size_t stride = 0;
     const uint16_t* data = heif_image_get_component_uint16_readonly(decoded, idx1, &stride);
     REQUIRE(data != nullptr);
+    stride /= sizeof(uint16_t);
     for (uint32_t y = 0; y < kH; y++) {
       for (uint32_t x = 0; x < kW; x++) {
         uint16_t expected = static_cast<uint16_t>((y * kW + x + 200) & kMaxVal14);