Commit ed3aba98 for libheif
commit ed3aba982de376f80ab083fdcbc184f927fd48fd
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Mon Oct 5 17:59:44 2026 +0200
Do not compare the luma bit depth of 'unci' images with several luma components
check_decoded_image_bit_depth() (770b0d8d) compares the bit depth that
the image handle reports with the Y plane of the decoded image. For an
'unci' image, the handle reports the largest bit depth of its luma or
monochrome components, while the Y plane of the decoded image is the
first of them. An image with several such components, of which the first
has fewer bits than a later one (e.g. two monochrome bands with 8 and 16
bits), was therefore refused with "Decoded image does not have the bit
depth signaled in the file". v1.23.5 decoded these images.
A single value cannot describe several components with different bit
depths, which is also why the chroma depth is only compared when Cb and
Cr agree. The luma depth is not compared anymore when the image has more
than one component that is mapped to the Y channel.
For such an image, the bit depth of the handle can still differ from the
bit depth of its first luma plane, as it did in v1.23.5.
diff --git a/libheif/image-items/image_item.cc b/libheif/image-items/image_item.cc
index 303ded2c..f468e9cc 100644
--- a/libheif/image-items/image_item.cc
+++ b/libheif/image-items/image_item.cc
@@ -1669,7 +1669,18 @@ Error ImageItem::check_decoded_image_bit_depth(const HeifPixelImage& img) const
bool mismatch = false;
- if (luma_bpp > 0 && img.has_channel(heif_channel_Y) &&
+ // The handle reports a single luma bit depth. An 'unci' image can have several components
+ // that are mapped to the Y channel (e.g. several monochrome bands) with different bit
+ // depths. A single value cannot describe them (the handle reports the largest one), so the
+ // luma depth is not compared when there are several such components.
+ int num_luma_components = 0;
+ for (const ComponentDescription& component : img.get_component_descriptions()) {
+ if (component.channel == heif_channel_Y && component.has_data_plane) {
+ num_luma_components++;
+ }
+ }
+
+ if (luma_bpp > 0 && num_luma_components <= 1 && img.has_channel(heif_channel_Y) &&
img.get_bits_per_pixel(heif_channel_Y) != luma_bpp) {
mismatch = true;
}