Commit 8dd25615 for libheif

commit 8dd2561526db9942bb153c4d9e36cfee718bb581
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Sun Feb 8 23:27:03 2026 +0100

    unci: fix tiled mixed-interleave and simplify decode_tile() signature

diff --git a/libheif/codecs/uncompressed/unc_codec.cc b/libheif/codecs/uncompressed/unc_codec.cc
index 89f4734f..aeb6e309 100644
--- a/libheif/codecs/uncompressed/unc_codec.cc
+++ b/libheif/codecs/uncompressed/unc_codec.cc
@@ -538,7 +538,7 @@ Error UncompressedImageCodec::decode_uncompressed_image_tile(const HeifContext*
     return err;
   }

-  return decoder->decode_tile(tile_data, img, 0, 0, tile_x0, tile_y0);
+  return decoder->decode_tile(tile_data, img, 0, 0);
 }


diff --git a/libheif/codecs/uncompressed/unc_decoder.cc b/libheif/codecs/uncompressed/unc_decoder.cc
index cb4295f1..9b1096c9 100644
--- a/libheif/codecs/uncompressed/unc_decoder.cc
+++ b/libheif/codecs/uncompressed/unc_decoder.cc
@@ -271,16 +271,13 @@ Error unc_decoder::decode_image(const DataExtent& extent,

   for (uint32_t tile_y0 = 0; tile_y0 < m_height; tile_y0 += tile_height)
     for (uint32_t tile_x0 = 0; tile_x0 < m_width; tile_x0 += tile_width) {
-      uint32_t tile_x = tile_x0 / tile_width;
-      uint32_t tile_y = tile_y0 / tile_height;
-
       std::vector<uint8_t> tile_data;
-      Error error = fetch_tile_data(extent, properties, tile_x, tile_y, tile_data);
+      Error error = fetch_tile_data(extent, properties, tile_x0 / tile_width, tile_y0 / tile_height, tile_data);
       if (error) {
         return error;
       }

-      error = decode_tile(tile_data, img, tile_x0, tile_y0, tile_x, tile_y);
+      error = decode_tile(tile_data, img, tile_x0, tile_y0);
       if (error) {
         return error;
       }
diff --git a/libheif/codecs/uncompressed/unc_decoder.h b/libheif/codecs/uncompressed/unc_decoder.h
index 33cb5250..1c304eea 100644
--- a/libheif/codecs/uncompressed/unc_decoder.h
+++ b/libheif/codecs/uncompressed/unc_decoder.h
@@ -48,8 +48,7 @@ public:

   virtual Error decode_tile(const std::vector<uint8_t>& tile_data,
                             std::shared_ptr<HeifPixelImage>& img,
-                            uint32_t out_x0, uint32_t out_y0,
-                            uint32_t tile_x, uint32_t tile_y) = 0;
+                            uint32_t out_x0, uint32_t out_y0) = 0;

   Error decode_image(const DataExtent& extent,
                      const UncompressedImageCodec::unci_properties& properties,
diff --git a/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc
index 92dffe26..4ed1a4e7 100644
--- a/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc
@@ -90,8 +90,7 @@ std::vector<uint64_t> unc_decoder_component_interleave::get_tile_data_sizes() co

 Error unc_decoder_component_interleave::decode_tile(const std::vector<uint8_t>& tile_data,
                                                      std::shared_ptr<HeifPixelImage>& img,
-                                                     uint32_t out_x0, uint32_t out_y0,
-                                                     uint32_t tile_x, uint32_t tile_y)
+                                                     uint32_t out_x0, uint32_t out_y0)
 {
   UncompressedBitReader srcBits(tile_data);

diff --git a/libheif/codecs/uncompressed/unc_decoder_component_interleave.h b/libheif/codecs/uncompressed/unc_decoder_component_interleave.h
index bd387913..73508e0c 100644
--- a/libheif/codecs/uncompressed/unc_decoder_component_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_component_interleave.h
@@ -38,8 +38,7 @@ public:

   Error decode_tile(const std::vector<uint8_t>& tile_data,
                     std::shared_ptr<HeifPixelImage>& img,
-                    uint32_t out_x0, uint32_t out_y0,
-                    uint32_t tile_x, uint32_t tile_y) override;
+                    uint32_t out_x0, uint32_t out_y0) override;
 };


diff --git a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc
index 437d45fe..969e7b9a 100644
--- a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc
@@ -62,18 +62,17 @@ std::vector<uint64_t> unc_decoder_mixed_interleave::get_tile_data_sizes() const

 Error unc_decoder_mixed_interleave::decode_tile(const std::vector<uint8_t>& tile_data,
                                                  std::shared_ptr<HeifPixelImage>& img,
-                                                 uint32_t out_x0, uint32_t out_y0,
-                                                 uint32_t tile_x, uint32_t tile_y)
+                                                 uint32_t out_x0, uint32_t out_y0)
 {
   UncompressedBitReader srcBits(tile_data);

-  processTile(srcBits, tile_y, tile_x, out_x0, out_y0);
+  processTile(srcBits, out_x0, out_y0);

   return Error::Ok;
 }


-void unc_decoder_mixed_interleave::processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column, uint32_t out_x0, uint32_t out_y0)
+void unc_decoder_mixed_interleave::processTile(UncompressedBitReader& srcBits, uint32_t out_x0, uint32_t out_y0)
 {
   bool haveProcessedChromaForThisTile = false;
   for (ChannelListEntry& entry : channelList) {
@@ -100,8 +99,8 @@ void unc_decoder_mixed_interleave::processTile(UncompressedBitReader& srcBits, u
       }
       else {
         for (uint32_t tile_y = 0; tile_y < entry.tile_height; tile_y++) {
-          uint64_t dst_row_offset = entry.getDestinationRowOffset(tile_row, tile_y);
-          processComponentRow(entry, srcBits, dst_row_offset, tile_column);
+          uint64_t dst_row_offset = uint64_t{(out_y0 + tile_y)} * entry.dst_plane_stride;
+          processComponentTileRow(entry, srcBits, dst_row_offset + out_x0 * entry.bytes_per_component_sample);
         }
       }
     }
diff --git a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h
index 0b177cce..92fe3296 100644
--- a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h
@@ -36,11 +36,9 @@ public:

   Error decode_tile(const std::vector<uint8_t>& tile_data,
                     std::shared_ptr<HeifPixelImage>& img,
-                    uint32_t out_x0, uint32_t out_y0,
-                    uint32_t tile_x, uint32_t tile_y) override;
+                    uint32_t out_x0, uint32_t out_y0) override;

-  void processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column,
-                   uint32_t out_x0, uint32_t out_y0);
+  void processTile(UncompressedBitReader& srcBits, uint32_t out_x0, uint32_t out_y0);
 };


diff --git a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc
index e9d9ed70..87566b98 100644
--- a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc
@@ -68,16 +68,15 @@ std::vector<uint64_t> unc_decoder_pixel_interleave::get_tile_data_sizes() const

 Error unc_decoder_pixel_interleave::decode_tile(const std::vector<uint8_t>& tile_data,
                                                  std::shared_ptr<HeifPixelImage>& img,
-                                                 uint32_t out_x0, uint32_t out_y0,
-                                                 uint32_t tile_x, uint32_t tile_y)
+                                                 uint32_t out_x0, uint32_t out_y0)
 {
   UncompressedBitReader srcBits(tile_data);

-  return processTile(srcBits, tile_y, tile_x, out_x0, out_y0);
+  return processTile(srcBits, out_x0, out_y0);
 }


-Error unc_decoder_pixel_interleave::processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column, uint32_t out_x0, uint32_t out_y0)
+Error unc_decoder_pixel_interleave::processTile(UncompressedBitReader& srcBits, uint32_t out_x0, uint32_t out_y0)
 {
   for (uint32_t tile_y = 0; tile_y < m_tile_height; tile_y++) {
     srcBits.markRowStart();
diff --git a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h
index 370b2e37..dcdd96ff 100644
--- a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h
@@ -36,11 +36,9 @@ public:

   Error decode_tile(const std::vector<uint8_t>& tile_data,
                     std::shared_ptr<HeifPixelImage>& img,
-                    uint32_t out_x0, uint32_t out_y0,
-                    uint32_t tile_x, uint32_t tile_y) override;
+                    uint32_t out_x0, uint32_t out_y0) override;

-  [[nodiscard]] Error processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column,
-                                  uint32_t out_x0, uint32_t out_y0);
+  [[nodiscard]] Error processTile(UncompressedBitReader& srcBits, uint32_t out_x0, uint32_t out_y0);
 };


diff --git a/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc
index 3b03ed9d..fafa2b08 100644
--- a/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc
@@ -68,18 +68,17 @@ std::vector<uint64_t> unc_decoder_row_interleave::get_tile_data_sizes() const

 Error unc_decoder_row_interleave::decode_tile(const std::vector<uint8_t>& tile_data,
                                                std::shared_ptr<HeifPixelImage>& img,
-                                               uint32_t out_x0, uint32_t out_y0,
-                                               uint32_t tile_x, uint32_t tile_y)
+                                               uint32_t out_x0, uint32_t out_y0)
 {
   UncompressedBitReader srcBits(tile_data);

-  processTile(srcBits, tile_y, tile_x, out_x0, out_y0);
+  processTile(srcBits, out_x0, out_y0);

   return Error::Ok;
 }


-void unc_decoder_row_interleave::processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column, uint32_t out_x0, uint32_t out_y0)
+void unc_decoder_row_interleave::processTile(UncompressedBitReader& srcBits, uint32_t out_x0, uint32_t out_y0)
 {
   for (uint32_t tile_y = 0; tile_y < m_tile_height; tile_y++) {
     for (ChannelListEntry& entry : channelList) {
diff --git a/libheif/codecs/uncompressed/unc_decoder_row_interleave.h b/libheif/codecs/uncompressed/unc_decoder_row_interleave.h
index 44fcaff9..c0f72ee0 100644
--- a/libheif/codecs/uncompressed/unc_decoder_row_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_row_interleave.h
@@ -38,12 +38,10 @@ public:

   Error decode_tile(const std::vector<uint8_t>& tile_data,
                     std::shared_ptr<HeifPixelImage>& img,
-                    uint32_t out_x0, uint32_t out_y0,
-                    uint32_t tile_x, uint32_t tile_y) override;
+                    uint32_t out_x0, uint32_t out_y0) override;

 private:
-  void processTile(UncompressedBitReader& srcBits, uint32_t tile_row, uint32_t tile_column,
-                   uint32_t out_x0, uint32_t out_y0);
+  void processTile(UncompressedBitReader& srcBits, uint32_t out_x0, uint32_t out_y0);
 };