Commit b1943651 for libheif
commit b194365135784e41716a0e5b432d7f79c867ec1d
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Tue Feb 24 00:13:20 2026 +0100
improve decoded image size check to make it work with non-visual unci images (#1709)
diff --git a/libheif/api/libheif/heif_image.cc b/libheif/api/libheif/heif_image.cc
index e19af209..d0af524d 100644
--- a/libheif/api/libheif/heif_image.cc
+++ b/libheif/api/libheif/heif_image.cc
@@ -68,35 +68,15 @@ int heif_image_get_height(const heif_image* img, heif_channel channel)
int heif_image_get_primary_width(const heif_image* img)
{
- return uint32_to_int(img->image->get_primary_width());
- if (img->image->get_colorspace() == heif_colorspace_RGB) {
- if (img->image->get_chroma_format() == heif_chroma_444) {
- return uint32_to_int(img->image->get_width(heif_channel_G));
- }
- else {
- return uint32_to_int(img->image->get_width(heif_channel_interleaved));
- }
- }
- else {
- return uint32_to_int(img->image->get_width(heif_channel_Y));
- }
+ uint32_t primary_component = img->image->get_primary_component();
+ return uint32_to_int(img->image->get_width(primary_component));
}
int heif_image_get_primary_height(const heif_image* img)
{
- return uint32_to_int(img->image->get_primary_height());
- if (img->image->get_colorspace() == heif_colorspace_RGB) {
- if (img->image->get_chroma_format() == heif_chroma_444) {
- return uint32_to_int(img->image->get_height(heif_channel_G));
- }
- else {
- return uint32_to_int(img->image->get_height(heif_channel_interleaved));
- }
- }
- else {
- return uint32_to_int(img->image->get_height(heif_channel_Y));
- }
+ uint32_t primary_component = img->image->get_primary_component();
+ return uint32_to_int(img->image->get_height(primary_component));
}
diff --git a/libheif/context.cc b/libheif/context.cc
index 8ad18ee3..a2be4750 100644
--- a/libheif/context.cc
+++ b/libheif/context.cc
@@ -1313,16 +1313,17 @@ Result<std::shared_ptr<HeifPixelImage>> HeifContext::decode_image(heif_item_id I
// --- check that the decoded image has the claimed size (only check if transformations are applied)
- if (!options.ignore_transformations &&
- !(img->get_colorspace() == heif_colorspace_nonvisual ||
- img->get_colorspace() == heif_colorspace_undefined) &&
- (imgitem->get_width() != img->get_primary_width() ||
- imgitem->get_height() != img->get_primary_height())) {
- return Error{
- heif_error_Invalid_input,
- heif_suberror_Invalid_image_size,
- "Decoded image does not have the claimed size."
- };
+ if (!options.ignore_transformations) {
+ uint32_t primary_component = img->get_primary_component();
+
+ if (imgitem->get_width() != img->get_width(primary_component) ||
+ imgitem->get_height() != img->get_height(primary_component)) {
+ return Error{
+ heif_error_Invalid_input,
+ heif_suberror_Invalid_image_size,
+ "Decoded image does not have the claimed size."
+ };
+ }
}
// --- convert to output chroma format
diff --git a/libheif/pixelimage.cc b/libheif/pixelimage.cc
index 113c6a5e..ccc42cc1 100644
--- a/libheif/pixelimage.cc
+++ b/libheif/pixelimage.cc
@@ -716,6 +716,59 @@ uint32_t HeifPixelImage::get_height(enum heif_channel channel) const
}
+uint32_t HeifPixelImage::get_width(uint32_t component_idx) const
+{
+ if (component_idx >= m_planes.size()) {
+ return 0;
+ }
+
+ return m_planes[component_idx].m_width;
+}
+
+
+uint32_t HeifPixelImage::get_height(uint32_t component_idx) const
+{
+ if (component_idx >= m_planes.size()) {
+ return 0;
+ }
+
+ return m_planes[component_idx].m_height;
+}
+
+
+uint32_t HeifPixelImage::get_primary_component() const
+{
+ // first pass: search for color channel
+
+ for (uint32_t idx=0; idx<m_planes.size(); idx++) {
+ if (m_planes[idx].m_channel == heif_channel_interleaved) {
+ return idx;
+ }
+
+ switch (m_planes[idx].m_component_type) {
+ case component_type_Y:
+ case component_type_monochrome:
+ case component_type_red:
+ case component_type_green:
+ case component_type_blue:
+ case component_type_cyan:
+ case component_type_magenta:
+ case component_type_yellow:
+ case component_type_key_black:
+ case component_type_filter_array:
+ case component_type_palette:
+ return idx;
+
+ default:
+ ; // NOP
+ }
+ }
+
+ // second pass: allow anything
+
+ return 0;
+}
+#if 0
uint32_t HeifPixelImage::get_primary_width() const
{
if (m_colorspace == heif_colorspace_RGB) {
@@ -746,7 +799,7 @@ uint32_t HeifPixelImage::get_primary_height() const
return get_height(heif_channel_Y);
}
}
-
+#endif
std::set<heif_channel> HeifPixelImage::get_channel_set() const
{
diff --git a/libheif/pixelimage.h b/libheif/pixelimage.h
index f11a4a60..396c10a6 100644
--- a/libheif/pixelimage.h
+++ b/libheif/pixelimage.h
@@ -239,15 +239,21 @@ public:
uint32_t get_height(heif_channel channel) const;
+ uint32_t get_width(uint32_t component_idx) const;
+
+ uint32_t get_height(uint32_t component_idx) const;
+
bool has_odd_width() const { return !!(m_width & 1); }
bool has_odd_height() const { return !!(m_height & 1); }
// TODO: currently only defined for colorspace RGB, YCbCr, Monochrome
- uint32_t get_primary_width() const;
+ //uint32_t get_primary_width() const;
// TODO: currently only defined for colorspace RGB, YCbCr, Monochrome
- uint32_t get_primary_height() const;
+ //uint32_t get_primary_height() const;
+
+ uint32_t get_primary_component() const;
heif_chroma get_chroma_format() const { return m_chroma; }