Commit 72afe3d4 for libheif
commit 72afe3d4c9f91a2102e5c6cb59812bc35205fba9
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Sat Apr 4 16:05:27 2026 +0200
unci: map uncC index to component id (wip)
diff --git a/libheif/codecs/uncompressed/unc_codec.cc b/libheif/codecs/uncompressed/unc_codec.cc
index cddb2681..a6dcbb91 100644
--- a/libheif/codecs/uncompressed/unc_codec.cc
+++ b/libheif/codecs/uncompressed/unc_codec.cc
@@ -204,6 +204,7 @@ static Error validate_component_indices(const std::vector<uint32_t>& indices,
Result<std::shared_ptr<HeifPixelImage>> UncompressedImageCodec::create_image(const unci_properties& properties,
uint32_t width,
uint32_t height,
+ std::vector<uint32_t>& uncC_index_to_comp_ids,
const heif_security_limits* limits)
{
auto cmpd = properties.cmpd;
@@ -252,6 +253,7 @@ Result<std::shared_ptr<HeifPixelImage>> UncompressedImageCodec::create_image(con
}
cmpd_index_to_comp_ids[component.component_index].push_back(*result);
+ uncC_index_to_comp_ids.push_back(*result);
}
else {
Result<uint32_t> result = img->add_component(width,
@@ -265,6 +267,7 @@ Result<std::shared_ptr<HeifPixelImage>> UncompressedImageCodec::create_image(con
}
cmpd_index_to_comp_ids[component.component_index].push_back(*result);
+ uncC_index_to_comp_ids.push_back(*result);
}
}
@@ -371,15 +374,16 @@ Error UncompressedImageCodec::decode_uncompressed_image_tile(const HeifContext*
// Remember which components reference which cmpd indices.
// There can be several component ids referencing the same cmpd index.
std::vector<std::vector<uint32_t>> cmpd_index_to_comp_ids;
+ std::vector<uint32_t> uncC_index_to_comp_ids;
- Result<std::shared_ptr<HeifPixelImage>> createImgResult = create_image(properties, tile_width, tile_height, context->get_security_limits());
+ Result<std::shared_ptr<HeifPixelImage>> createImgResult = create_image(properties, tile_width, tile_height, uncC_index_to_comp_ids, context->get_security_limits());
if (!createImgResult) {
return createImgResult.error();
}
img = *createImgResult;
- auto decoderResult = unc_decoder_factory::get_unc_decoder(ispe->get_width(), ispe->get_height(), cmpd, uncC);
+ auto decoderResult = unc_decoder_factory::get_unc_decoder(ispe->get_width(), ispe->get_height(), cmpd, uncC, uncC_index_to_comp_ids);
if (!decoderResult) {
return decoderResult.error();
}
diff --git a/libheif/codecs/uncompressed/unc_codec.h b/libheif/codecs/uncompressed/unc_codec.h
index 28ca6c60..9fea542b 100644
--- a/libheif/codecs/uncompressed/unc_codec.h
+++ b/libheif/codecs/uncompressed/unc_codec.h
@@ -86,6 +86,7 @@ public:
static Result<std::shared_ptr<HeifPixelImage>> create_image(const unci_properties& properties,
uint32_t width,
uint32_t height,
+ std::vector<uint32_t>& uncC_index_to_comp_ids,
const heif_security_limits* limits);
static Error check_header_validity(std::optional<const std::shared_ptr<const Box_ispe>>,
diff --git a/libheif/codecs/uncompressed/unc_decoder.cc b/libheif/codecs/uncompressed/unc_decoder.cc
index 1d15eaa9..41f66668 100644
--- a/libheif/codecs/uncompressed/unc_decoder.cc
+++ b/libheif/codecs/uncompressed/unc_decoder.cc
@@ -43,11 +43,13 @@
unc_decoder::unc_decoder(uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC)
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids)
: m_width(width),
m_height(height),
m_cmpd(cmpd),
- m_uncC(uncC)
+ m_uncC(uncC),
+ m_uncC_index_to_comp_ids(uncC_index_to_comp_ids)
{
m_tile_height = m_height / m_uncC->get_number_of_tile_rows();
m_tile_width = m_width / m_uncC->get_number_of_tile_columns();
@@ -410,7 +412,9 @@ Error check_hard_limits(const std::shared_ptr<const Box_uncC>& uncC)
Result<std::unique_ptr<unc_decoder> > unc_decoder_factory::get_unc_decoder(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC)
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids
+)
{
static unc_decoder_factory_component_interleave dec_component;
static unc_decoder_factory_bytealign_component_interleave dec_bytealign_component;
@@ -426,7 +430,7 @@ Result<std::unique_ptr<unc_decoder> > unc_decoder_factory::get_unc_decoder(
for (const unc_decoder_factory* dec : decoders) {
if (dec->can_decode(uncC)) {
- return {dec->create(width, height, cmpd, uncC)};
+ return {dec->create(width, height, cmpd, uncC, uncC_index_to_comp_ids)};
}
}
@@ -456,7 +460,9 @@ Result<std::shared_ptr<HeifPixelImage> > unc_decoder::decode_full_image(
return {global_limit_error};
}
- Result<std::shared_ptr<HeifPixelImage> > createImgResult = UncompressedImageCodec::create_image(properties, width, height, limits);
+ std::vector<uint32_t> uncC_index_to_comp_ids;
+
+ Result<std::shared_ptr<HeifPixelImage> > createImgResult = UncompressedImageCodec::create_image(properties, width, height, uncC_index_to_comp_ids, limits);
if (!createImgResult) {
return createImgResult.error();
}
@@ -464,7 +470,7 @@ Result<std::shared_ptr<HeifPixelImage> > unc_decoder::decode_full_image(
auto img = *createImgResult;
- auto decoderResult = unc_decoder_factory::get_unc_decoder(width, height, cmpd, uncC);
+ auto decoderResult = unc_decoder_factory::get_unc_decoder(width, height, cmpd, uncC, uncC_index_to_comp_ids);
if (!decoderResult) {
return decoderResult.error();
}
diff --git a/libheif/codecs/uncompressed/unc_decoder.h b/libheif/codecs/uncompressed/unc_decoder.h
index 3106c6ba..75d19efe 100644
--- a/libheif/codecs/uncompressed/unc_decoder.h
+++ b/libheif/codecs/uncompressed/unc_decoder.h
@@ -62,7 +62,8 @@ public:
protected:
unc_decoder(uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC);
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids);
virtual std::vector<uint64_t> get_tile_data_sizes() const = 0;
@@ -80,6 +81,7 @@ protected:
const uint32_t m_height;
const std::shared_ptr<const Box_cmpd> m_cmpd;
const std::shared_ptr<const Box_uncC> m_uncC;
+ const std::vector<uint32_t> m_uncC_index_to_comp_ids;
uint32_t m_tile_height;
uint32_t m_tile_width;
};
@@ -93,7 +95,8 @@ public:
static Result<std::unique_ptr<unc_decoder>> get_unc_decoder(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC);
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids);
protected:
static bool check_common_requirements(const std::shared_ptr<const Box_uncC>& uncC);
@@ -105,7 +108,8 @@ protected:
virtual std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const = 0;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const = 0;
};
#endif
diff --git a/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.cc
index 625df8fd..8cf2525d 100644
--- a/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.cc
@@ -33,8 +33,9 @@
unc_decoder_block_component_interleave::unc_decoder_block_component_interleave(
uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC)
- : unc_decoder(width, height, cmpd, uncC)
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids)
+ : unc_decoder(width, height, cmpd, uncC, uncC_index_to_comp_ids)
{
}
@@ -96,6 +97,10 @@ Error unc_decoder_block_component_interleave::decode_tile(const std::vector<uint
comp[i].shift = 0;
}
+ comp[i].dst_plane = img->get_component(m_uncC_index_to_comp_ids[i], &comp[i].dst_plane_stride);
+ comp[i].use = true;
+
+#if 0
heif_channel channel;
comp[i].use = map_uncompressed_component_to_channel(m_cmpd, c, &channel);
if (comp[i].use) {
@@ -105,6 +110,7 @@ Error unc_decoder_block_component_interleave::decode_tile(const std::vector<uint
comp[i].dst_plane = nullptr;
comp[i].dst_plane_stride = 0;
}
+#endif
}
const uint8_t* src = tile_data.data();
@@ -222,7 +228,8 @@ bool unc_decoder_factory_block_component_interleave::can_decode(const std::share
std::unique_ptr<unc_decoder> unc_decoder_factory_block_component_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_block_component_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_block_component_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.h b/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.h
index 597f1d74..a040413d 100644
--- a/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_block_component_interleave.h
@@ -31,7 +31,8 @@ class unc_decoder_block_component_interleave : public unc_decoder
public:
unc_decoder_block_component_interleave(uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC);
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids);
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -49,7 +50,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_BLOCK_COMPONENT_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.cc
index 848b6186..9e75f6f1 100644
--- a/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.cc
@@ -33,8 +33,9 @@
unc_decoder_block_pixel_interleave::unc_decoder_block_pixel_interleave(
uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC)
- : unc_decoder(width, height, cmpd, uncC)
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids)
+ : unc_decoder(width, height, cmpd, uncC, uncC_index_to_comp_ids)
{
}
@@ -88,7 +89,7 @@ Error unc_decoder_block_pixel_interleave::decode_tile(const std::vector<uint8_t>
const auto& c = components[i];
comp[i].bytes_per_sample = (c.component_bit_depth + 7) / 8;
comp[i].mask = (uint64_t{1} << c.component_bit_depth) - 1;
-
+#if 0
heif_channel channel;
comp[i].use = map_uncompressed_component_to_channel(m_cmpd, c, &channel);
if (comp[i].use) {
@@ -98,6 +99,9 @@ Error unc_decoder_block_pixel_interleave::decode_tile(const std::vector<uint8_t>
comp[i].dst_plane = nullptr;
comp[i].dst_plane_stride = 0;
}
+#endif
+ comp[i].use = true;
+ comp[i].dst_plane = img->get_component(m_uncC_index_to_comp_ids[i], &comp[i].dst_plane_stride);
}
// Compute bit shifts within the block.
@@ -228,7 +232,8 @@ bool unc_decoder_factory_block_pixel_interleave::can_decode(const std::shared_pt
std::unique_ptr<unc_decoder> unc_decoder_factory_block_pixel_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_block_pixel_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_block_pixel_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.h b/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.h
index a9dfe6b9..122160db 100644
--- a/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_block_pixel_interleave.h
@@ -31,7 +31,8 @@ class unc_decoder_block_pixel_interleave : public unc_decoder
public:
unc_decoder_block_pixel_interleave(uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC);
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids);
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -49,7 +50,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_BLOCK_PIXEL_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.cc
index 77f67ba2..098142fb 100644
--- a/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.cc
@@ -33,8 +33,9 @@
unc_decoder_bytealign_component_interleave::unc_decoder_bytealign_component_interleave(
uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC)
- : unc_decoder(width, height, cmpd, uncC)
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids)
+ : unc_decoder(width, height, cmpd, uncC, uncC_index_to_comp_ids)
{
}
@@ -85,6 +86,7 @@ Error unc_decoder_bytealign_component_interleave::decode_tile(const std::vector<
comp[i].bytes_per_sample = (c.component_bit_depth + 7) / 8;
comp[i].use = true; // map_uncompressed_component_to_channel(m_cmpd, c, &channel);
+#if 0
if (comp[i].use) {
comp[i].dst_plane = img->get_component(c.component_index, &comp[i].dst_plane_stride);
assert(comp[i].dst_plane != nullptr);
@@ -93,6 +95,9 @@ Error unc_decoder_bytealign_component_interleave::decode_tile(const std::vector<
comp[i].dst_plane = nullptr;
comp[i].dst_plane_stride = 0;
}
+#endif
+
+ comp[i].dst_plane = img->get_component(m_uncC_index_to_comp_ids[i], &comp[i].dst_plane_stride);
}
const uint8_t* src = tile_data.data();
@@ -273,7 +278,8 @@ bool unc_decoder_factory_bytealign_component_interleave::can_decode(const std::s
std::unique_ptr<unc_decoder> unc_decoder_factory_bytealign_component_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_bytealign_component_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_bytealign_component_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.h b/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.h
index 4a2326ab..c52b9f2b 100644
--- a/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_bytealign_component_interleave.h
@@ -31,7 +31,8 @@ class unc_decoder_bytealign_component_interleave : public unc_decoder
public:
unc_decoder_bytealign_component_interleave(uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC);
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids);
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -49,7 +50,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_BYTEALIGN_COMPONENT_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc
index e57c0714..d94f6bdb 100644
--- a/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_component_interleave.cc
@@ -168,7 +168,8 @@ bool unc_decoder_factory_component_interleave::can_decode(const std::shared_ptr<
std::unique_ptr<unc_decoder> unc_decoder_factory_component_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_component_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_component_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_component_interleave.h b/libheif/codecs/uncompressed/unc_decoder_component_interleave.h
index c32ab6ea..731e261c 100644
--- a/libheif/codecs/uncompressed/unc_decoder_component_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_component_interleave.h
@@ -32,8 +32,9 @@ class unc_decoder_component_interleave : public unc_decoder_legacybase
public:
unc_decoder_component_interleave(uint32_t width, uint32_t height,
std::shared_ptr<const Box_cmpd> cmpd,
- std::shared_ptr<const Box_uncC> uncC) :
- unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC)) {}
+ std::shared_ptr<const Box_uncC> uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) :
+ unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC), uncC_index_to_comp_ids) {}
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -51,7 +52,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_COMPONENT_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_decoder_legacybase.cc b/libheif/codecs/uncompressed/unc_decoder_legacybase.cc
index af706ae5..99920685 100644
--- a/libheif/codecs/uncompressed/unc_decoder_legacybase.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_legacybase.cc
@@ -44,8 +44,9 @@
unc_decoder_legacybase::unc_decoder_legacybase(uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC)
- : unc_decoder(width, height, cmpd, uncC)
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids)
+ : unc_decoder(width, height, cmpd, uncC, uncC_index_to_comp_ids)
{
}
@@ -58,9 +59,11 @@ void unc_decoder_legacybase::ensureChannelList(std::shared_ptr<HeifPixelImage>&
void unc_decoder_legacybase::buildChannelList(std::shared_ptr<HeifPixelImage>& img)
{
+ uint32_t uncC_index = 0;
for (Box_uncC::Component component : m_uncC->get_components()) {
- ChannelListEntry entry = buildChannelListEntry(component.component_index, component, img);
+ ChannelListEntry entry = buildChannelListEntry(uncC_index, component, img);
channelList.push_back(entry);
+ uncC_index++;
}
}
@@ -134,13 +137,13 @@ void unc_decoder_legacybase::processComponentTileRow(ChannelListEntry& entry, Un
}
-unc_decoder_legacybase::ChannelListEntry unc_decoder_legacybase::buildChannelListEntry(uint32_t component_idx,
+unc_decoder_legacybase::ChannelListEntry unc_decoder_legacybase::buildChannelListEntry(uint32_t component_id,
Box_uncC::Component component,
std::shared_ptr<HeifPixelImage>& img)
{
ChannelListEntry entry;
entry.use_channel = map_uncompressed_component_to_channel(m_cmpd, component, &(entry.channel));
- entry.dst_plane = img->get_component(component_idx, &(entry.dst_plane_stride));
+ entry.dst_plane = img->get_component(m_uncC_index_to_comp_ids[component_id], &(entry.dst_plane_stride));
entry.tile_width = m_tile_width;
entry.tile_height = m_tile_height;
entry.other_chroma_dst_plane_stride = 0; // will be overwritten below if used
diff --git a/libheif/codecs/uncompressed/unc_decoder_legacybase.h b/libheif/codecs/uncompressed/unc_decoder_legacybase.h
index 79b93fcc..a6ffd9ea 100644
--- a/libheif/codecs/uncompressed/unc_decoder_legacybase.h
+++ b/libheif/codecs/uncompressed/unc_decoder_legacybase.h
@@ -142,7 +142,8 @@ public:
protected:
unc_decoder_legacybase(uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC);
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids);
class ChannelListEntry
{
diff --git a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc
index bcb67501..f21199fe 100644
--- a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.cc
@@ -154,7 +154,8 @@ bool unc_decoder_factory_mixed_interleave::can_decode(const std::shared_ptr<cons
std::unique_ptr<unc_decoder> unc_decoder_factory_mixed_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_mixed_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_mixed_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h
index 2f37c859..4e441401 100644
--- a/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_mixed_interleave.h
@@ -30,8 +30,8 @@
class unc_decoder_mixed_interleave : public unc_decoder_legacybase
{
public:
- unc_decoder_mixed_interleave(uint32_t width, uint32_t height, std::shared_ptr<const Box_cmpd> cmpd, std::shared_ptr<const Box_uncC> uncC) :
- unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC)) {}
+ unc_decoder_mixed_interleave(uint32_t width, uint32_t height, std::shared_ptr<const Box_cmpd> cmpd, std::shared_ptr<const Box_uncC> uncC, const std::vector<uint32_t>& uncC_index_to_comp_ids) :
+ unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC), uncC_index_to_comp_ids) {}
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -51,7 +51,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_MIXED_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc
index 79886e7c..de7169d6 100644
--- a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.cc
@@ -133,7 +133,8 @@ bool unc_decoder_factory_pixel_interleave::can_decode(const std::shared_ptr<cons
std::unique_ptr<unc_decoder> unc_decoder_factory_pixel_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_pixel_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_pixel_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h
index bee123fa..45aa55ae 100644
--- a/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_pixel_interleave.h
@@ -30,8 +30,8 @@
class unc_decoder_pixel_interleave : public unc_decoder_legacybase
{
public:
- unc_decoder_pixel_interleave(uint32_t width, uint32_t height, std::shared_ptr<const Box_cmpd> cmpd, std::shared_ptr<const Box_uncC> uncC) :
- unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC)) {}
+ unc_decoder_pixel_interleave(uint32_t width, uint32_t height, std::shared_ptr<const Box_cmpd> cmpd, std::shared_ptr<const Box_uncC> uncC, const std::vector<uint32_t>& uncC_index_to_comp_ids) :
+ unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC), uncC_index_to_comp_ids) {}
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -51,7 +51,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_PIXEL_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc b/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc
index f90603c9..e8dc47c9 100644
--- a/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_decoder_row_interleave.cc
@@ -124,7 +124,8 @@ bool unc_decoder_factory_row_interleave::can_decode(const std::shared_ptr<const
std::unique_ptr<unc_decoder> unc_decoder_factory_row_interleave::create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const
{
- return std::make_unique<unc_decoder_row_interleave>(width, height, cmpd, uncC);
+ return std::make_unique<unc_decoder_row_interleave>(width, height, cmpd, uncC, uncC_index_to_comp_ids);
}
diff --git a/libheif/codecs/uncompressed/unc_decoder_row_interleave.h b/libheif/codecs/uncompressed/unc_decoder_row_interleave.h
index 90d111b6..6c028e83 100644
--- a/libheif/codecs/uncompressed/unc_decoder_row_interleave.h
+++ b/libheif/codecs/uncompressed/unc_decoder_row_interleave.h
@@ -31,8 +31,8 @@ class unc_decoder_row_interleave : public unc_decoder_legacybase
{
public:
unc_decoder_row_interleave(uint32_t width, uint32_t height,
- std::shared_ptr<const Box_cmpd> cmpd, std::shared_ptr<const Box_uncC> uncC) :
- unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC)) {}
+ std::shared_ptr<const Box_cmpd> cmpd, std::shared_ptr<const Box_uncC> uncC, const std::vector<uint32_t>& uncC_index_to_comp_ids) :
+ unc_decoder_legacybase(width, height, std::move(cmpd), std::move(uncC), uncC_index_to_comp_ids) {}
std::vector<uint64_t> get_tile_data_sizes() const override;
@@ -54,7 +54,8 @@ private:
std::unique_ptr<unc_decoder> create(
uint32_t width, uint32_t height,
const std::shared_ptr<const Box_cmpd>& cmpd,
- const std::shared_ptr<const Box_uncC>& uncC) const override;
+ const std::shared_ptr<const Box_uncC>& uncC,
+ const std::vector<uint32_t>& uncC_index_to_comp_ids) const override;
};
#endif // LIBHEIF_UNC_DECODER_ROW_INTERLEAVE_H
diff --git a/libheif/codecs/uncompressed/unc_encoder_component_interleave.cc b/libheif/codecs/uncompressed/unc_encoder_component_interleave.cc
index a161492b..f8027f5a 100644
--- a/libheif/codecs/uncompressed/unc_encoder_component_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_encoder_component_interleave.cc
@@ -37,17 +37,17 @@ bool unc_encoder_factory_component_interleave::can_encode(const std::shared_ptr<
// If any component is not byte-aligned, we use the bit-packing path which
// reads samples as uint32_t, limiting all components to 32 bpp.
bool any_non_aligned = false;
- uint32_t num_components = image->get_number_of_used_components();
- for (uint32_t idx = 0; idx < num_components; idx++) {
- uint16_t bpp = image->get_component_bits_per_pixel(idx);
+ auto component_ids = image->get_used_component_ids();
+ for (uint32_t id : component_ids) {
+ uint16_t bpp = image->get_component_bits_per_pixel(id);
if (bpp % 8 != 0) {
any_non_aligned = true;
}
}
if (any_non_aligned) {
- for (uint32_t idx = 0; idx < num_components; idx++) {
- if (image->get_component_bits_per_pixel(idx) > 32) {
+ for (uint32_t id : component_ids) {
+ if (image->get_component_bits_per_pixel(id) > 32) {
return false;
}
}
@@ -55,8 +55,8 @@ bool unc_encoder_factory_component_interleave::can_encode(const std::shared_ptr<
if (!any_non_aligned) {
// All components are byte-aligned. Only accept typical integer widths.
- for (uint32_t idx = 0; idx < num_components; idx++) {
- uint16_t bpp = image->get_component_bits_per_pixel(idx);
+ for (uint32_t id : component_ids) {
+ uint16_t bpp = image->get_component_bits_per_pixel(id);
switch (bpp) {
case 8:
case 16:
@@ -87,17 +87,19 @@ unc_encoder_component_interleave::unc_encoder_component_interleave(const std::sh
: unc_encoder(image)
{
bool is_nonvisual = (image->get_colorspace() == heif_colorspace_nonvisual);
- uint32_t num_components = image->get_number_of_used_components();
+ //uint32_t num_components = image->get_number_of_used_components();
- for (uint32_t idx = 0; idx < num_components; idx++) {
+ auto componentIds = image->get_used_planar_component_ids();
+
+ for (uint32_t id : componentIds) {
heif_unci_component_type comp_type;
heif_channel ch = heif_channel_Y; // default for nonvisual
if (is_nonvisual) {
- comp_type = static_cast<heif_unci_component_type>(image->get_component_type(idx));
+ comp_type = static_cast<heif_unci_component_type>(image->get_component_type(id));
}
else {
- ch = image->get_component_channel(idx);
+ ch = image->get_component_channel(id);
if (ch == heif_channel_Y && !image->has_channel(heif_channel_Cb)) {
comp_type = heif_unci_component_type_monochrome;
}
@@ -106,11 +108,11 @@ unc_encoder_component_interleave::unc_encoder_component_interleave(const std::sh
}
}
- uint16_t bpp = image->get_component_bits_per_pixel(idx);
- auto comp_format = to_unc_component_format(image->get_component_datatype(idx));
+ uint16_t bpp = image->get_component_bits_per_pixel(id);
+ auto comp_format = to_unc_component_format(image->get_component_datatype(id));
bool aligned = (bpp % 8 == 0);
- m_components.push_back({idx, ch, comp_type, comp_format, bpp, aligned});
+ m_components.push_back({id, ch, comp_type, comp_format, bpp, aligned});
}
// Build cmpd/uncC boxes
diff --git a/libheif/pixelimage.cc b/libheif/pixelimage.cc
index 55c5e4f5..485780fc 100644
--- a/libheif/pixelimage.cc
+++ b/libheif/pixelimage.cc
@@ -2383,6 +2383,20 @@ std::vector<uint32_t> HeifPixelImage::get_used_component_ids() const
}
+std::vector<uint32_t> HeifPixelImage::get_used_planar_component_ids() const
+{
+ std::vector<uint32_t> indices;
+
+ for (const auto& plane : m_planes) {
+ if (plane.m_component_ids.size() == 1) {
+ indices.push_back(plane.m_component_ids[0]);
+ }
+ }
+
+ return indices;
+}
+
+
uint8_t* HeifPixelImage::get_component(uint32_t component_idx, size_t* out_stride)
{
return get_component_data<uint8_t>(component_idx, out_stride);
diff --git a/libheif/pixelimage.h b/libheif/pixelimage.h
index c19dd8af..75e2df95 100644
--- a/libheif/pixelimage.h
+++ b/libheif/pixelimage.h
@@ -501,6 +501,8 @@ public:
// Returns the sorted list of component_indices of all planes that have pixel data.
std::vector<uint32_t> get_used_component_ids() const;
+ std::vector<uint32_t> get_used_planar_component_ids() const;
+
uint8_t* get_component(uint32_t component_idx, size_t* out_stride);
const uint8_t* get_component(uint32_t component_idx, size_t* out_stride) const;