Commit 0f17e1cd for libheif
commit 0f17e1cd25ee94d4b96a9db1db1f77b6f6d43cb0
Author: Joachim Bauch <bauch@struktur.de>
Date: Thu Oct 30 14:17:15 2025 +0100
Ignore missing / incomplete tiles if not strict decoding.
diff --git a/libheif/image-items/grid.cc b/libheif/image-items/grid.cc
index 49375ba9..515afbe9 100644
--- a/libheif/image-items/grid.cc
+++ b/libheif/image-items/grid.cc
@@ -302,6 +302,7 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
int progress_counter = 0;
bool cancelled = false;
+ std::vector<Error> warnings;
for (uint32_t y = 0; y < grid.get_rows() && !cancelled; y++) {
uint32_t x0 = 0;
@@ -312,11 +313,33 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
std::shared_ptr<const ImageItem> tileImg = get_context()->get_image(tileID, true);
if (!tileImg) {
+ if (!options.strict_decoding && reference_idx != 0) {
+ // Skip missing tiles (unless it's the first one).
+ warnings.push_back(Error{
+ heif_error_Invalid_input,
+ heif_suberror_Missing_grid_images,
+ });
+ reference_idx++;
+ x0 += tile_width;
+ continue;
+ }
+
return Error{heif_error_Invalid_input,
heif_suberror_Missing_grid_images,
"Nonexistent grid image referenced"};
}
if (auto error = tileImg->get_item_error()) {
+ if (!options.strict_decoding && reference_idx != 0) {
+ // Skip missing tiles (unless it's the first one).
+ warnings.push_back(Error{
+ heif_error_Invalid_input,
+ heif_suberror_Missing_grid_images,
+ });
+ reference_idx++;
+ x0 += tile_width;
+ continue;
+ }
+
return error;
}
@@ -431,6 +454,8 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem_Grid::decode_full_grid_image(c
return Error{heif_error_Canceled, heif_suberror_Unspecified, "Decoding the image was canceled"};
}
+ img->add_warnings(warnings);
+
return img;
}
@@ -442,6 +467,11 @@ Error ImageItem_Grid::decode_and_paste_tile_image(heif_item_id tileID, uint32_t
std::shared_ptr<HeifPixelImage> tile_img;
auto tileItem = get_context()->get_image(tileID, true);
+ if (!tileItem && !options.strict_decoding) {
+ // We ignore missing images.
+ return Error::Ok;
+ }
+
assert(tileItem);
if (auto error = tileItem->get_item_error()) {
return error;