Skip to content

Commit

Permalink
fix heif_image_handle_has_alpha_channel() for unci images (strukturag…
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Jan 30, 2025
1 parent 1a131f9 commit c0574b7
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 8 deletions.
34 changes: 28 additions & 6 deletions libheif/codecs/uncompressed/unc_codec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,22 +241,42 @@ static Error uncompressed_image_type_is_supported(const std::shared_ptr<const Bo

Error UncompressedImageCodec::get_heif_chroma_uncompressed(const std::shared_ptr<const Box_uncC>& uncC,
const std::shared_ptr<const Box_cmpd>& cmpd,
heif_chroma* out_chroma, heif_colorspace* out_colourspace)
heif_chroma* out_chroma, heif_colorspace* out_colourspace,
bool* out_has_alpha)
{
bool dummy_has_alpha;
if (out_has_alpha == nullptr) {
out_has_alpha = &dummy_has_alpha;
}

*out_chroma = heif_chroma_undefined;
*out_colourspace = heif_colorspace_undefined;
*out_has_alpha = false;

Error error = check_header_validity(std::nullopt, cmpd, uncC);
if (error) {
return error;
}

if (isKnownUncompressedFrameConfigurationBoxProfile(uncC)) {
*out_chroma = heif_chroma_444;
*out_colourspace = heif_colorspace_RGB;
return Error::Ok;

if (uncC != nullptr && uncC->get_version() == 1) {
switch (uncC->get_profile()) {
case fourcc("rgb3"): {
*out_chroma = heif_chroma_444;
*out_colourspace = heif_colorspace_RGB;
*out_has_alpha = false;
return Error::Ok;
}
case fourcc("abgr"): {
*out_chroma = heif_chroma_444;
*out_colourspace = heif_colorspace_RGB;
*out_has_alpha = true;
return Error::Ok;
}
}
}


// each 1-bit represents an existing component in the image
uint16_t componentSet = 0;

Expand All @@ -276,6 +296,8 @@ Error UncompressedImageCodec::get_heif_chroma_uncompressed(const std::shared_ptr
componentSet |= (1 << component_type);
}

*out_has_alpha = (componentSet & (1 << component_type_alpha)) != 0;

if (componentSet == ((1 << component_type_red) | (1 << component_type_green) | (1 << component_type_blue)) ||
componentSet == ((1 << component_type_red) | (1 << component_type_green) | (1 << component_type_blue) | (1 << component_type_alpha))) {
*out_chroma = heif_chroma_444;
Expand Down Expand Up @@ -448,7 +470,7 @@ Result<std::shared_ptr<HeifPixelImage>> UncompressedImageCodec::create_image(con
heif_chroma chroma = heif_chroma_undefined;
heif_colorspace colourspace = heif_colorspace_undefined;

Error error = get_heif_chroma_uncompressed(uncC, cmpd, &chroma, &colourspace);
Error error = get_heif_chroma_uncompressed(uncC, cmpd, &chroma, &colourspace, nullptr);
if (error) {
return error;
}
Expand Down
3 changes: 2 additions & 1 deletion libheif/codecs/uncompressed/unc_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class UncompressedImageCodec
static Error get_heif_chroma_uncompressed(const std::shared_ptr<const Box_uncC>& uncC,
const std::shared_ptr<const Box_cmpd>& cmpd,
heif_chroma* out_chroma,
heif_colorspace* out_colourspace);
heif_colorspace* out_colourspace,
bool* out_has_alpha);

static Result<std::shared_ptr<HeifPixelImage>> create_image(std::shared_ptr<const Box_cmpd>,
std::shared_ptr<const Box_uncC>,
Expand Down
14 changes: 13 additions & 1 deletion libheif/codecs/uncompressed/unc_dec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Error Decoder_uncompressed::get_coded_image_colorspace(heif_colorspace* out_colo
return Error::Ok;
}
else if (m_cmpd) {
UncompressedImageCodec::get_heif_chroma_uncompressed(m_uncC, m_cmpd, out_chroma, out_colorspace);
UncompressedImageCodec::get_heif_chroma_uncompressed(m_uncC, m_cmpd, out_chroma, out_colorspace, nullptr);
return Error::Ok;
}
else {
Expand All @@ -149,3 +149,15 @@ Error Decoder_uncompressed::get_coded_image_colorspace(heif_colorspace* out_colo
"Missing 'cmpd' box."};
}
}


bool Decoder_uncompressed::has_alpha_component() const
{
heif_colorspace dummy_colorspace;
heif_chroma dummy_chroma;
bool has_alpha;

UncompressedImageCodec::get_heif_chroma_uncompressed(m_uncC, m_cmpd, &dummy_chroma, &dummy_colorspace, &has_alpha);

return has_alpha;
}
2 changes: 2 additions & 0 deletions libheif/codecs/uncompressed/unc_dec.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class Decoder_uncompressed : public Decoder

Error get_coded_image_colorspace(heif_colorspace*, heif_chroma*) const override;

bool has_alpha_component() const;

Result<std::vector<uint8_t>> read_bitstream_configuration_data() const override;

private:
Expand Down
4 changes: 4 additions & 0 deletions libheif/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,10 @@ bool HeifContext::has_alpha(heif_item_id ID) const
return true;
}

if (img->has_coded_alpha_channel()) {
return true;
}

heif_colorspace colorspace;
heif_chroma chroma;
Error err = img->get_coded_image_colorspace(&colorspace, &chroma);
Expand Down
2 changes: 2 additions & 0 deletions libheif/image-items/image_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ class ImageItem : public ErrorBuffer

bool is_premultiplied_alpha() const { return m_premultiplied_alpha; }

// Whether the image has an alpha channel coded in the main image (not as an auxiliary image)
virtual bool has_coded_alpha_channel() const { return false; }

// --- depth channel

Expand Down
6 changes: 6 additions & 0 deletions libheif/image-items/unc_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,9 @@ Error ImageItem_uncompressed::on_load_file()

return Error::Ok;
}


bool ImageItem_uncompressed::has_coded_alpha_channel() const
{
return m_decoder->has_alpha_component();
}
2 changes: 2 additions & 0 deletions libheif/image-items/unc_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class ImageItem_uncompressed : public ImageItem
// Instead of storing alpha in a separate unci, this is put into the main image item
const char* get_auxC_alpha_channel_type() const override { return nullptr; }

bool has_coded_alpha_channel() const override;

const heif_color_profile_nclx* get_forced_output_nclx() const override { return nullptr; }

bool is_ispe_essential() const override { return true; }
Expand Down

0 comments on commit c0574b7

Please sign in to comment.