Commit bf71aa19 for libheif
commit bf71aa19169c554ae4f8cfd7906d5800ffce0e25
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Thu Mar 5 21:35:54 2026 +0100
check if unci's icef is compatible with tili
diff --git a/libheif/image-items/tiled.cc b/libheif/image-items/tiled.cc
index eaff6917..3afb9f73 100644
--- a/libheif/image-items/tiled.cc
+++ b/libheif/image-items/tiled.cc
@@ -24,6 +24,7 @@
#include <algorithm>
#include "security_limits.h"
#include "codecs/hevc_dec.h"
+#include "codecs/uncompressed/unc_boxes.h"
#include "api_structs.h"
@@ -553,7 +554,24 @@ Error ImageItem_Tiled::initialize_decoder()
return propertiesResult.error();
}
- m_tile_item->set_properties(*propertiesResult);
+ // Filter out per-tile boxes incompatible with tili's shared template
+ auto props = *propertiesResult;
+ for (const auto& box : props) {
+ if (box->get_short_type() == fourcc("icef")) {
+ auto icef = std::dynamic_pointer_cast<Box_icef>(box);
+ if (icef && icef->get_units().size() > 1) {
+ return {heif_error_Invalid_input,
+ heif_suberror_Unspecified,
+ "icef box with multiple units is incompatible with tili shared tile template."};
+ }
+ }
+ }
+ std::erase_if(props, [](const std::shared_ptr<Box>& box) {
+ uint32_t type = box->get_short_type();
+ return type == fourcc("icef") || type == fourcc("sbpm") || type == fourcc("snuc");
+ });
+
+ m_tile_item->set_properties(props);
}
else {
// --- This is the new method
@@ -562,6 +580,22 @@ Error ImageItem_Tiled::initialize_decoder()
auto tile_properties = tilC_box->get_all_child_boxes();
+ // Filter out per-tile boxes incompatible with tili's shared template
+ for (const auto& box : tile_properties) {
+ if (box->get_short_type() == fourcc("icef")) {
+ auto icef = std::dynamic_pointer_cast<Box_icef>(box);
+ if (icef && icef->get_units().size() > 1) {
+ return {heif_error_Invalid_input,
+ heif_suberror_Unspecified,
+ "icef box with multiple units is incompatible with tili shared tile template."};
+ }
+ }
+ }
+ std::erase_if(tile_properties, [](const std::shared_ptr<Box>& box) {
+ uint32_t type = box->get_short_type();
+ return type == fourcc("icef") || type == fourcc("sbpm") || type == fourcc("snuc");
+ });
+
bool have_ispe = false;
for (const auto& property : tile_properties) {
if (property->get_short_type() == fourcc("ispe")) {
@@ -734,6 +768,24 @@ Error ImageItem_Tiled::add_image_tile(uint32_t tile_x, uint32_t tile_y,
continue;
}
+ // icef/sbpm/snuc contain per-tile data incompatible with tili's shared tile template
+ uint32_t ptype = propertyBox->get_short_type();
+ if (ptype == fourcc("icef")) {
+ auto icef = std::dynamic_pointer_cast<Box_icef>(propertyBox);
+ if (icef && icef->get_units().size() > 1) {
+ return {heif_error_Usage_error,
+ heif_suberror_Unspecified,
+ "icef box with multiple units is incompatible with tili shared tile template."};
+ }
+ // Single-unit icef can be safely skipped
+ continue;
+ }
+ if (ptype == fourcc("sbpm") || ptype == fourcc("snuc")) {
+ return {heif_error_Usage_error,
+ heif_suberror_Unspecified,
+ "Cannot store per-tile property (" + fourcc_to_string(ptype) + ") in tili shared tile template."};
+ }
+
// skip properties that exist already
bool exists = std::any_of(tile_properties.begin(),