Commit 09ea4da5 for libheif

commit 09ea4da573985ccc1e47e5d5c7f9d19ae4f6844f
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Sun Dec 28 12:58:20 2025 +0100

    check for cyclic item references during decoding instead of throwing errors during parsing

diff --git a/libheif/api/libheif/heif_decoding.cc b/libheif/api/libheif/heif_decoding.cc
index 4ac272ed..6f0b2cd3 100644
--- a/libheif/api/libheif/heif_decoding.cc
+++ b/libheif/api/libheif/heif_decoding.cc
@@ -246,7 +246,7 @@ heif_error heif_decode_image(const heif_image_handle* in_handle,
                                                                                              colorspace,
                                                                                              chroma,
                                                                                              dec_options,
-                                                                                             false, 0, 0);
+                                                                                             false, 0, 0, {});

   if (!decodingResult) {
     return decodingResult.error_struct(in_handle->image.get());
diff --git a/libheif/api/libheif/heif_tiling.cc b/libheif/api/libheif/heif_tiling.cc
index d322dbc7..4b874e81 100644
--- a/libheif/api/libheif/heif_tiling.cc
+++ b/libheif/api/libheif/heif_tiling.cc
@@ -109,7 +109,8 @@ heif_error heif_image_handle_decode_image_tile(const heif_image_handle* in_handl
                                                                                              colorspace,
                                                                                              chroma,
                                                                                              *dec_options,
-                                                                                             true, x0, y0);
+                                                                                             true, x0, y0,
+                                                                                             {});
   heif_decoding_options_free(dec_options);

   if (!decodingResult) {
diff --git a/libheif/box.cc b/libheif/box.cc
index f4467f9d..ceafd974 100644
--- a/libheif/box.cc
+++ b/libheif/box.cc
@@ -3700,7 +3700,7 @@ Error Box_iref::parse(BitstreamRange& range, const heif_security_limits* limits)
   }


-#if 1
+#if 0
   // Note: This input sanity check first did not work as expected.
   // Its idea was to prevent infinite recursions while decoding when the input file
   // contains cyclic references. However, apparently there are cases where cyclic
@@ -3710,11 +3710,10 @@ Error Box_iref::parse(BitstreamRange& range, const heif_security_limits* limits)
   // | reference with type 'auxl' from ID: 2 to IDs: 1
   // | reference with type 'prem' from ID: 1 to IDs: 2
   //
-  // We now only follow 'dimg' references. This should be free from cyclic references.
-  //
-  // TODO: implement the infinite recursion detection in a different way. E.g. by passing down
-  //       the already processed item-ids while decoding an image and checking whether the current
-  //       item has already been decoded before.
+  // We now test for cyclic references during the image decoding.
+  // We pass down the item IDs that have already been seen during the decoding process.
+  // If we try to decode an image IDs that has already been seen previously, we throw an error.
+  // The advantage is that the error only occurs when we are trying to decode the faulty image.

   // --- check for cyclic references

diff --git a/libheif/context.cc b/libheif/context.cc
index aa263887..a1bcc268 100644
--- a/libheif/context.cc
+++ b/libheif/context.cc
@@ -1283,7 +1283,8 @@ Result<std::shared_ptr<HeifPixelImage>> HeifContext::decode_image(heif_item_id I
                                                                   heif_colorspace out_colorspace,
                                                                   heif_chroma out_chroma,
                                                                   const heif_decoding_options& options,
-                                                                  bool decode_only_tile, uint32_t tx, uint32_t ty) const
+                                                                  bool decode_only_tile, uint32_t tx, uint32_t ty,
+                                                                  std::set<heif_item_id> processed_ids) const
 {
   std::shared_ptr<ImageItem> imgitem;
   if (m_all_images.contains(ID)) {
@@ -1296,7 +1297,7 @@ Result<std::shared_ptr<HeifPixelImage>> HeifContext::decode_image(heif_item_id I
   }


-  auto decodingResult = imgitem->decode_image(options, decode_only_tile, tx, ty);
+  auto decodingResult = imgitem->decode_image(options, decode_only_tile, tx, ty, processed_ids);
   if (!decodingResult) {
     return decodingResult.error();
   }
diff --git a/libheif/context.h b/libheif/context.h
index af1359cc..45554459 100644
--- a/libheif/context.h
+++ b/libheif/context.h
@@ -115,7 +115,8 @@ public:
                                                        heif_colorspace out_colorspace,
                                                        heif_chroma out_chroma,
                                                        const heif_decoding_options& options,
-                                                       bool decode_only_tile, uint32_t tx, uint32_t ty) const;
+                                                       bool decode_only_tile, uint32_t tx, uint32_t ty,
+                                                       std::set<heif_item_id> processed_ids) const;

   Result<std::shared_ptr<HeifPixelImage>> convert_to_output_colorspace(std::shared_ptr<HeifPixelImage> img,
                                                                        heif_colorspace out_colorspace,
diff --git a/libheif/image-items/grid.cc b/libheif/image-items/grid.cc
index a4251557..45a61d60 100644
--- a/libheif/image-items/grid.cc
+++ b/libheif/image-items/grid.cc
@@ -207,13 +207,23 @@ Error ImageItem_Grid::read_grid_spec()


 Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_compressed_image(const heif_decoding_options& options,
-                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                                std::set<heif_item_id> processed_ids) const
 {
+  if (processed_ids.contains(get_id())) {
+    return Error{heif_error_Invalid_input,
+                 heif_suberror_Unspecified,
+                 "'iref' has cyclic references"};
+  }
+
+  processed_ids.insert(get_id());
+
+
   if (decode_tile_only) {
-    return decode_grid_tile(options, tile_x0, tile_y0);
+    return decode_grid_tile(options, tile_x0, tile_y0, processed_ids);
   }
   else {
-    return decode_full_grid_image(options);
+    return decode_full_grid_image(options, processed_ids);
   }
 }

@@ -230,7 +240,7 @@ static void wait_for_jobs(std::deque<std::future<Error> >* jobs) {
 }
 #endif

-Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(const heif_decoding_options& options) const
+Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(const heif_decoding_options& options, std::set<heif_item_id> processed_ids) const
 {
   std::shared_ptr<HeifPixelImage> img; // the decoded image

@@ -369,7 +379,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
           }
         }

-        err = decode_and_paste_tile_image(tileID, x0, y0, img, options, progress_counter, warnings);
+        err = decode_and_paste_tile_image(tileID, x0, y0, img, options, progress_counter, warnings, processed_ids);
         if (err) {
           return err;
         }
@@ -417,7 +427,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
       errs.push_back(std::async(std::launch::async,
                                 &ImageItem_Grid::decode_and_paste_tile_image, this,
                                 data.tileID, data.x_origin, data.y_origin, std::ref(img), options,
-                                std::ref(progress_counter), warnings));
+                                std::ref(progress_counter), warnings, processed_ids));
     }

     // check for decoding errors in remaining tiles
@@ -464,7 +474,8 @@ Error ImageItem_Grid::decode_and_paste_tile_image(heif_item_id tileID, uint32_t
                                                   std::shared_ptr<HeifPixelImage>& inout_image,
                                                   const heif_decoding_options& options,
                                                   int& progress_counter,
-                                                  std::shared_ptr<std::vector<Error> > warnings) const
+                                                  std::shared_ptr<std::vector<Error> > warnings,
+                                                  std::set<heif_item_id> processed_ids) const
 {
   std::shared_ptr<HeifPixelImage> tile_img;
 #if ENABLE_PARALLEL_TILE_DECODING
@@ -489,7 +500,7 @@ Error ImageItem_Grid::decode_and_paste_tile_image(heif_item_id tileID, uint32_t
     return error;
   }

-  auto decodeResult = tileItem->decode_image(options, false, 0, 0);
+  auto decodeResult = tileItem->decode_image(options, false, 0, 0, processed_ids);
   if (!decodeResult) {
     if (!options.strict_decoding) {
       // We ignore broken tiles.
@@ -556,7 +567,8 @@ Error ImageItem_Grid::decode_and_paste_tile_image(heif_item_id tileID, uint32_t
 }


-Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_grid_tile(const heif_decoding_options& options, uint32_t tx, uint32_t ty) const
+Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_grid_tile(const heif_decoding_options& options, uint32_t tx, uint32_t ty,
+                                                                         std::set<heif_item_id> processed_ids) const
 {
   uint32_t idx = ty * m_grid_spec.get_columns() + tx;

@@ -568,7 +580,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_grid_tile(const h
     return error;
   }

-  return tile_item->decode_compressed_image(options, true, tx, ty);
+  return tile_item->decode_compressed_image(options, true, tx, ty, processed_ids);
 }


diff --git a/libheif/image-items/grid.h b/libheif/image-items/grid.h
index e6bcaa45..f82ce11a 100644
--- a/libheif/image-items/grid.h
+++ b/libheif/image-items/grid.h
@@ -130,7 +130,8 @@ public:
   }

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
-                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const override;
+                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                  std::set<heif_item_id> processed_ids) const override;

   heif_brand2 get_compatible_brand() const override;

@@ -161,14 +162,15 @@ private:

   Error read_grid_spec();

-  Result<std::shared_ptr<HeifPixelImage>> decode_full_grid_image(const heif_decoding_options& options) const;
+  Result<std::shared_ptr<HeifPixelImage>> decode_full_grid_image(const heif_decoding_options& options, std::set<heif_item_id> processed_ids) const;

-  Result<std::shared_ptr<HeifPixelImage>> decode_grid_tile(const heif_decoding_options& options, uint32_t tx, uint32_t ty) const;
+  Result<std::shared_ptr<HeifPixelImage>> decode_grid_tile(const heif_decoding_options& options, uint32_t tx, uint32_t ty, std::set<heif_item_id> processed_ids) const;

   Error decode_and_paste_tile_image(heif_item_id tileID, uint32_t x0, uint32_t y0,
                                     std::shared_ptr<HeifPixelImage>& inout_image,
                                     const heif_decoding_options& options, int& progress_counter,
-                                    std::shared_ptr<std::vector<Error> > warnings) const;
+                                    std::shared_ptr<std::vector<Error> > warnings,
+                                    std::set<heif_item_id> processed_ids) const;
 };


diff --git a/libheif/image-items/iden.cc b/libheif/image-items/iden.cc
index f11b8869..8e771cfa 100644
--- a/libheif/image-items/iden.cc
+++ b/libheif/image-items/iden.cc
@@ -36,8 +36,18 @@ ImageItem_iden::ImageItem_iden(HeifContext* ctx, heif_item_id id)


 Result<std::shared_ptr<HeifPixelImage>> ImageItem_iden::decode_compressed_image(const heif_decoding_options& options,
-                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                                std::set<heif_item_id> processed_ids) const
 {
+  if (processed_ids.contains(get_id())) {
+    return Error{heif_error_Invalid_input,
+                 heif_suberror_Unspecified,
+                 "'iref' has cyclic references"};
+  }
+
+  processed_ids.insert(get_id());
+
+
   std::shared_ptr<HeifPixelImage> img;

   // find the ID of the image this image is derived from
@@ -52,12 +62,18 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_iden::decode_compressed_image(

   std::vector<heif_item_id> image_references = iref_box->get_references(get_id(), fourcc("dimg"));

-  if ((int) image_references.size() != 1) {
+  if (image_references.size() > 1) {
     return Error(heif_error_Invalid_input,
                  heif_suberror_Unspecified,
                  "'iden' image with more than one reference image");
   }

+  if (image_references.empty()) {
+    return Error(heif_error_Invalid_input,
+                 heif_suberror_Unspecified,
+                 "'iden' image without 'dimg' reference");
+  }
+

   heif_item_id reference_image_id = image_references[0];

@@ -77,7 +93,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_iden::decode_compressed_image(
     return error;
   }

-  return imgitem->decode_image(options, decode_tile_only, tile_x0, tile_y0);
+  return imgitem->decode_image(options, decode_tile_only, tile_x0, tile_y0, processed_ids);
 }


diff --git a/libheif/image-items/iden.h b/libheif/image-items/iden.h
index ff91aa6c..dcde1862 100644
--- a/libheif/image-items/iden.h
+++ b/libheif/image-items/iden.h
@@ -59,7 +59,8 @@ public:
   }

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
-                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const override;
+                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                  std::set<heif_item_id> processed_ids) const override;

   heif_brand2 get_compatible_brand() const override;

diff --git a/libheif/image-items/image_item.cc b/libheif/image-items/image_item.cc
index 84eab178..dc16a374 100644
--- a/libheif/image-items/image_item.cc
+++ b/libheif/image-items/image_item.cc
@@ -679,7 +679,8 @@ void ImageItem::set_color_profile_icc(const std::shared_ptr<const color_profile_


 Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_image(const heif_decoding_options& options,
-                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                std::set<heif_item_id> processed_ids) const
 {
   // --- check whether image size (according to 'ispe') exceeds maximum

@@ -704,7 +705,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_image(const heif_decod

   // --- decode image

-  Result<std::shared_ptr<HeifPixelImage>> decodingResult = decode_compressed_image(options, decode_tile_only, tile_x0, tile_y0);
+  Result<std::shared_ptr<HeifPixelImage>> decodingResult = decode_compressed_image(options, decode_tile_only, tile_x0, tile_y0, processed_ids);
   if (!decodingResult) {
     return decodingResult.error();
   }
@@ -802,7 +803,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_image(const heif_decod
       return alpha_image->get_item_error();
     }

-    auto alphaDecodingResult = alpha_image->decode_image(options, decode_tile_only, tile_x0, tile_y0);
+    auto alphaDecodingResult = alpha_image->decode_image(options, decode_tile_only, tile_x0, tile_y0, processed_ids);
     if (!alphaDecodingResult) {
       return alphaDecodingResult.error();
     }
@@ -927,8 +928,18 @@ Result<std::vector<uint8_t>> ImageItem::read_bitstream_configuration_data_overri
 #endif

 Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_compressed_image(const heif_decoding_options& options,
-                                                                           bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                           bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                           std::set<heif_item_id> processed_ids) const
 {
+  if (processed_ids.contains(m_id)) {
+    return Error{heif_error_Invalid_input,
+                 heif_suberror_Unspecified,
+                 "'iref' has cyclic references"};
+  }
+
+  processed_ids.insert(m_id);
+
+
   DataExtent extent;
   extent.set_from_image_item(get_file(), get_id());

diff --git a/libheif/image-items/image_item.h b/libheif/image-items/image_item.h
index cac1f283..a5ac0ac3 100644
--- a/libheif/image-items/image_item.h
+++ b/libheif/image-items/image_item.h
@@ -305,11 +305,13 @@ public:

   virtual Result<std::shared_ptr<HeifPixelImage>> decode_image(const heif_decoding_options& options,
                                                                bool decode_tile_only, uint32_t tile_x0,
-                                                               uint32_t tile_y0) const;
+                                                               uint32_t tile_y0,
+                                                               std::set<heif_item_id> processed_ids) const;

   virtual Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
                                                                           bool decode_tile_only, uint32_t tile_x0,
-                                                                          uint32_t tile_y0) const;
+                                                                          uint32_t tile_y0,
+                                                                          std::set<heif_item_id> processed_ids) const;

   Result<std::vector<std::shared_ptr<Box>>> get_properties() const;

@@ -464,14 +466,15 @@ public:

   Result<std::shared_ptr<HeifPixelImage>> decode_image(const heif_decoding_options& options,
                                                        bool decode_tile_only, uint32_t tile_x0,
-                                                       uint32_t tile_y0) const override
+                                                       uint32_t tile_y0,
+                                                       std::set<heif_item_id> processed_ids) const override
   {
     return m_item_error;
   }

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
                                                                   bool decode_tile_only, uint32_t tile_x0,
-                                                                  uint32_t tile_y0) const override
+                                                                  uint32_t tile_y0, std::set<heif_item_id> processed_ids) const override
   {
     return m_item_error;
   }
diff --git a/libheif/image-items/mask_image.cc b/libheif/image-items/mask_image.cc
index 206efe5c..328d1797 100644
--- a/libheif/image-items/mask_image.cc
+++ b/libheif/image-items/mask_image.cc
@@ -128,7 +128,8 @@ Error MaskImageCodec::decode_mask_image(const HeifContext* context,


 Result<std::shared_ptr<HeifPixelImage>> ImageItem_mask::decode_compressed_image(const heif_decoding_options& options,
-                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                                std::set<heif_item_id> processed_ids) const
 {
   std::shared_ptr<HeifPixelImage> img;

diff --git a/libheif/image-items/mask_image.h b/libheif/image-items/mask_image.h
index b1f58f81..b748d57e 100644
--- a/libheif/image-items/mask_image.h
+++ b/libheif/image-items/mask_image.h
@@ -98,7 +98,8 @@ public:
   int get_chroma_bits_per_pixel() const override { return 0; }

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
-                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const override;
+                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                  std::set<heif_item_id> processed_ids) const override;

   Result<Encoder::CodedImageData> encode(const std::shared_ptr<HeifPixelImage>& image,
                                          heif_encoder* encoder,
diff --git a/libheif/image-items/overlay.cc b/libheif/image-items/overlay.cc
index 1f5d3a92..168eb0a8 100644
--- a/libheif/image-items/overlay.cc
+++ b/libheif/image-items/overlay.cc
@@ -273,14 +273,25 @@ Error ImageItem_Overlay::read_overlay_spec()


 Result<std::shared_ptr<HeifPixelImage>> ImageItem_Overlay::decode_compressed_image(const heif_decoding_options& options,
-                                                                                   bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                                   bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                                   std::set<heif_item_id> processed_ids) const
 {
-  return decode_overlay_image(options);
+  return decode_overlay_image(options, processed_ids);
 }


-Result<std::shared_ptr<HeifPixelImage>> ImageItem_Overlay::decode_overlay_image(const heif_decoding_options& options) const
+Result<std::shared_ptr<HeifPixelImage>> ImageItem_Overlay::decode_overlay_image(const heif_decoding_options& options,
+                                                                                std::set<heif_item_id> processed_ids) const
 {
+  if (processed_ids.contains(get_id())) {
+    return Error{heif_error_Invalid_input,
+                 heif_suberror_Unspecified,
+                 "'iref' has cyclic references"};
+  }
+
+  processed_ids.insert(get_id());
+
+
   std::shared_ptr<HeifPixelImage> img;

   uint32_t w = m_overlay_spec.get_canvas_width();
@@ -332,7 +343,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Overlay::decode_overlay_image(
       return error;
     }

-    auto decodeResult = imgItem->decode_image(options, false, 0,0);
+    auto decodeResult = imgItem->decode_image(options, false, 0,0, processed_ids);
     if (!decodeResult) {
       return decodeResult.error();
     }
diff --git a/libheif/image-items/overlay.h b/libheif/image-items/overlay.h
index 8c6e6138..fbaa0c8a 100644
--- a/libheif/image-items/overlay.h
+++ b/libheif/image-items/overlay.h
@@ -117,7 +117,8 @@ public:
   }

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
-                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const override;
+                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                  std::set<heif_item_id> processed_ids) const override;


   // --- iovl specific
@@ -130,7 +131,8 @@ private:

   Error read_overlay_spec();

-  Result<std::shared_ptr<HeifPixelImage>> decode_overlay_image(const heif_decoding_options& options) const;
+  Result<std::shared_ptr<HeifPixelImage>> decode_overlay_image(const heif_decoding_options& options,
+                                                               std::set<heif_item_id> processed_ids) const;
 };


diff --git a/libheif/image-items/tiled.cc b/libheif/image-items/tiled.cc
index 95b00bc1..dce157cc 100644
--- a/libheif/image-items/tiled.cc
+++ b/libheif/image-items/tiled.cc
@@ -759,7 +759,8 @@ void ImageItem_Tiled::process_before_write()

 Result<std::shared_ptr<HeifPixelImage>>
 ImageItem_Tiled::decode_compressed_image(const heif_decoding_options& options,
-                                        bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                         bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                         std::set<heif_item_id> processed_ids) const
 {
   if (decode_tile_only) {
     return decode_grid_tile(options, tile_x0, tile_y0);
diff --git a/libheif/image-items/tiled.h b/libheif/image-items/tiled.h
index 66d3ecc2..a9863ad6 100644
--- a/libheif/image-items/tiled.h
+++ b/libheif/image-items/tiled.h
@@ -181,7 +181,8 @@ public:
   }

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
-                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const override;
+                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                  std::set<heif_item_id> processed_ids) const override;

   heif_brand2 get_compatible_brand() const override;

diff --git a/libheif/image-items/unc_image.cc b/libheif/image-items/unc_image.cc
index 55ada00d..a0616d65 100644
--- a/libheif/image-items/unc_image.cc
+++ b/libheif/image-items/unc_image.cc
@@ -76,7 +76,8 @@ ImageItem_uncompressed::ImageItem_uncompressed(HeifContext* ctx)


 Result<std::shared_ptr<HeifPixelImage>> ImageItem_uncompressed::decode_compressed_image(const heif_decoding_options& options,
-                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
+                                                                                bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                                std::set<heif_item_id> processed_ids) const
 {
   std::shared_ptr<HeifPixelImage> img;

diff --git a/libheif/image-items/unc_image.h b/libheif/image-items/unc_image.h
index 7d02b7fd..a4d8b130 100644
--- a/libheif/image-items/unc_image.h
+++ b/libheif/image-items/unc_image.h
@@ -60,7 +60,8 @@ public:
   // Code from encode_uncompressed_image() has been moved to here.

   Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const heif_decoding_options& options,
-                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const override;
+                                                                  bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0,
+                                                                  std::set<heif_item_id> processed_ids) const override;

   heif_image_tiling get_heif_image_tiling() const override;