Commit 702f08a1 for libheif
commit 702f08a12dde0b443629e7a0ac531ca95896e537
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Sun Feb 8 16:18:44 2026 +0100
unci: extract unc_encoder_factory from unc_encoder
diff --git a/libheif/codecs/uncompressed/unc_encoder.cc b/libheif/codecs/uncompressed/unc_encoder.cc
index 5a357d3b..a0c1d1f3 100644
--- a/libheif/codecs/uncompressed/unc_encoder.cc
+++ b/libheif/codecs/uncompressed/unc_encoder.cc
@@ -51,24 +51,31 @@ heif_uncompressed_component_format to_unc_component_format(heif_channel_datatype
}
-Result<const unc_encoder*> unc_encoder::get_unc_encoder(const std::shared_ptr<const HeifPixelImage>& prototype_image,
- const heif_encoding_options& options)
+unc_encoder::unc_encoder()
{
- static unc_encoder_rgb3_rgba enc_rgb3_rgba;
- static unc_encoder_rgb_hdr_packed_interleave enc_rgb10_12;
- static unc_encoder_rrggbb enc_rrggbb;
- static unc_encoder_planar enc_planar;
+ m_cmpd = std::make_shared<Box_cmpd>();
+ m_uncC = std::make_shared<Box_uncC>();
+}
+
+
+Result<std::unique_ptr<const unc_encoder> > unc_encoder_factory::get_unc_encoder(const std::shared_ptr<const HeifPixelImage>& prototype_image,
+ const heif_encoding_options& options)
+{
+ static unc_encoder_factory_rgb3_rgba enc_rgb3_rgba;
+ static unc_encoder_factory_rgb_hdr_packed_interleave enc_rgb10_12;
+ static unc_encoder_factory_rrggbb enc_rrggbb;
+ static unc_encoder_factory_planar enc_planar;
- static const unc_encoder* encoders[] {
+ static const unc_encoder_factory* encoders[]{
&enc_rgb3_rgba,
&enc_rgb10_12,
&enc_rrggbb,
&enc_planar
};
- for (const unc_encoder* enc : encoders) {
+ for (const unc_encoder_factory* enc : encoders) {
if (enc->can_encode(prototype_image, options)) {
- return {enc};
+ return {enc->create(prototype_image, options)};
}
}
@@ -80,7 +87,6 @@ Result<const unc_encoder*> unc_encoder::get_unc_encoder(const std::shared_ptr<co
}
-
heif_uncompressed_component_format to_unc_component_format(const std::shared_ptr<const HeifPixelImage>& image, heif_channel channel)
{
heif_channel_datatype datatype = image->get_datatype(channel);
@@ -90,9 +96,9 @@ heif_uncompressed_component_format to_unc_component_format(const std::shared_ptr
Result<Encoder::CodedImageData> unc_encoder::encode_full_image(const std::shared_ptr<const HeifPixelImage>& src_image,
- const heif_encoding_options& options)
+ const heif_encoding_options& options)
{
- auto uncEncoder = get_unc_encoder(src_image, options);
+ auto uncEncoder = unc_encoder_factory::get_unc_encoder(src_image, options);
if (uncEncoder.error()) {
return uncEncoder.error();
}
@@ -122,21 +128,18 @@ Result<Encoder::CodedImageData> unc_encoder::encode_static(const std::shared_ptr
// --- generate configuration property boxes
- std::shared_ptr<Box_uncC> uncC = std::make_shared<Box_uncC>();
- std::shared_ptr<Box_cmpd> cmpd = std::make_shared<Box_cmpd>();
-
- this->fill_cmpd_and_uncC(cmpd, uncC, src_image, options);
+ auto uncC = this->get_uncC();
Encoder::CodedImageData codedImageData;
codedImageData.properties.push_back(uncC);
if (!uncC->is_minimized()) {
- codedImageData.properties.push_back(cmpd);
+ codedImageData.properties.push_back(this->get_cmpd());
}
// --- encode image
- Result<std::vector<uint8_t> > codedBitstreamResult = encode_tile(src_image, options);
+ Result<std::vector<uint8_t> > codedBitstreamResult = this->encode_tile(src_image);
if (!codedBitstreamResult) {
return codedBitstreamResult.error();
}
@@ -145,5 +148,3 @@ Result<Encoder::CodedImageData> unc_encoder::encode_static(const std::shared_ptr
return codedImageData;
}
-
-
diff --git a/libheif/codecs/uncompressed/unc_encoder.h b/libheif/codecs/uncompressed/unc_encoder.h
index 11ba02bd..6d500afa 100644
--- a/libheif/codecs/uncompressed/unc_encoder.h
+++ b/libheif/codecs/uncompressed/unc_encoder.h
@@ -34,28 +34,41 @@ class HeifPixelImage;
class unc_encoder
{
public:
- virtual ~unc_encoder() = default;
-
- virtual bool can_encode(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const = 0;
+ unc_encoder();
- virtual void fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& out_cmpd,
- std::shared_ptr<Box_uncC>& out_uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const = 0;
+ virtual ~unc_encoder() = default;
- [[nodiscard]] virtual std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const = 0;
+ std::shared_ptr<Box_cmpd> get_cmpd() const { return m_cmpd; }
+ std::shared_ptr<Box_uncC> get_uncC() const { return m_uncC; }
- static Result<const unc_encoder*> get_unc_encoder(const std::shared_ptr<const HeifPixelImage>& prototype_image,
- const heif_encoding_options& options);
+ [[nodiscard]] virtual std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image) const = 0;
Result<Encoder::CodedImageData> encode_static(const std::shared_ptr<const HeifPixelImage>& src_image,
const heif_encoding_options& options) const;
static Result<Encoder::CodedImageData> encode_full_image(const std::shared_ptr<const HeifPixelImage>& src_image,
const heif_encoding_options& options);
+
+protected:
+ std::shared_ptr<Box_cmpd> m_cmpd;
+ std::shared_ptr<Box_uncC> m_uncC;
+};
+
+
+class unc_encoder_factory
+{
+public:
+ virtual ~unc_encoder_factory() = default;
+
+ static Result<std::unique_ptr<const unc_encoder> > get_unc_encoder(const std::shared_ptr<const HeifPixelImage>& prototype_image,
+ const heif_encoding_options& options);
+
+ virtual bool can_encode(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const = 0;
+
+ virtual std::unique_ptr<const unc_encoder> create(const std::shared_ptr<const HeifPixelImage>& prototype_image,
+ const heif_encoding_options& options) const = 0;
};
#endif //LIBHEIF_UNC_ENCODER_H
diff --git a/libheif/codecs/uncompressed/unc_encoder_planar.cc b/libheif/codecs/uncompressed/unc_encoder_planar.cc
index 31d1daad..5c60dff8 100644
--- a/libheif/codecs/uncompressed/unc_encoder_planar.cc
+++ b/libheif/codecs/uncompressed/unc_encoder_planar.cc
@@ -21,7 +21,7 @@
#include "unc_boxes.h"
-bool unc_encoder_planar::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
+bool unc_encoder_factory_planar::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
const heif_encoding_options& options) const
{
if (image->has_channel(heif_channel_interleaved)) {
@@ -32,6 +32,14 @@ bool unc_encoder_planar::can_encode(const std::shared_ptr<const HeifPixelImage>&
}
+std::unique_ptr<const unc_encoder> unc_encoder_factory_planar::create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
+{
+ return std::make_unique<unc_encoder_planar>(image, options);
+}
+
+
+
heif_uncompressed_component_type heif_channel_to_component_type(heif_channel channel)
{
switch (channel) {
@@ -42,8 +50,9 @@ heif_uncompressed_component_type heif_channel_to_component_type(heif_channel cha
case heif_channel_G: return heif_uncompressed_component_type::component_type_green;
case heif_channel_B: return heif_uncompressed_component_type::component_type_blue;
case heif_channel_Alpha: return heif_uncompressed_component_type::component_type_alpha;
- case heif_channel_interleaved: assert(false); break;
- case heif_channel_filter_array: return heif_uncompressed_component_type::component_type_filter_array;
+ case heif_channel_interleaved: assert(false);
+ break;
+ case heif_channel_filter_array: return heif_uncompressed_component_type::component_type_filter_array;
case heif_channel_depth: return heif_uncompressed_component_type::component_type_depth;
case heif_channel_disparity: return heif_uncompressed_component_type::component_type_disparity;
}
@@ -95,19 +104,18 @@ std::vector<channel_component> get_channels(const std::shared_ptr<const HeifPixe
return channels;
}
-void unc_encoder_planar::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
- std::shared_ptr<Box_uncC>& uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+
+unc_encoder_planar::unc_encoder_planar(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options)
{
auto channels = get_channels(image);
// if we have any component > 8 bits, we enable this
bool little_endian = false;
- uint16_t index=0;
+ uint16_t index = 0;
for (channel_component channelcomponent : channels) {
- cmpd->add_component({channelcomponent.component_type});
+ m_cmpd->add_component({channelcomponent.component_type});
uint8_t bpp = image->get_bits_per_pixel(channelcomponent.channel);
uint8_t component_align_size = static_cast<uint8_t>((bpp + 7) / 8);
@@ -120,27 +128,26 @@ void unc_encoder_planar::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
little_endian = true; // TODO: depending on the host endianness
}
- uncC->add_component({index, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({index, bpp, component_format_unsigned, component_align_size});
index++;
}
- uncC->set_interleave_type(interleave_mode_component);
- uncC->set_components_little_endian(little_endian);
+ m_uncC->set_interleave_type(interleave_mode_component);
+ m_uncC->set_components_little_endian(little_endian);
if (image->get_chroma_format() == heif_chroma_420) {
- uncC->set_sampling_type(2);
+ m_uncC->set_sampling_type(2);
}
else if (image->get_chroma_format() == heif_chroma_422) {
- uncC->set_sampling_type(1);
+ m_uncC->set_sampling_type(1);
}
else {
- uncC->set_sampling_type(0);
+ m_uncC->set_sampling_type(0);
}
}
-std::vector<uint8_t> unc_encoder_planar::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image,
- const heif_encoding_options& options) const
+std::vector<uint8_t> unc_encoder_planar::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image) const
{
std::vector<uint8_t> data;
@@ -161,7 +168,7 @@ std::vector<uint8_t> unc_encoder_planar::encode_tile(const std::shared_ptr<const
// output all component planes
- uint64_t out_data_start_pos=0;
+ uint64_t out_data_start_pos = 0;
for (channel_component channelcomponent : channels) {
int bpp = src_image->get_bits_per_pixel(channelcomponent.channel);
diff --git a/libheif/codecs/uncompressed/unc_encoder_planar.h b/libheif/codecs/uncompressed/unc_encoder_planar.h
index b8ba7ce3..3609b319 100644
--- a/libheif/codecs/uncompressed/unc_encoder_planar.h
+++ b/libheif/codecs/uncompressed/unc_encoder_planar.h
@@ -18,21 +18,24 @@
#include "unc_encoder.h"
-
class unc_encoder_planar : public unc_encoder
{
+public:
+ unc_encoder_planar(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options);
+
+ [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image) const override;
+};
+
+
+class unc_encoder_factory_planar : public unc_encoder_factory
+{
public:
[[nodiscard]] bool can_encode(const std::shared_ptr<const HeifPixelImage>& image,
const heif_encoding_options& options) const override;
- void fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& out_cmpd,
- std::shared_ptr<Box_uncC>& out_uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
-
- [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
+ std::unique_ptr<const unc_encoder> create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const override;
};
-
-#endif //LIBHEIF_UNC_ENCODER_PLANAR_H
\ No newline at end of file
+#endif //LIBHEIF_UNC_ENCODER_PLANAR_H
diff --git a/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.cc b/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.cc
index 72fd08b4..0e681286 100644
--- a/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.cc
+++ b/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.cc
@@ -27,8 +27,8 @@
#include "unc_types.h"
-bool unc_encoder_rgb3_rgba::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+bool unc_encoder_factory_rgb3_rgba::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
{
if (image->get_colorspace() != heif_colorspace_RGB) {
return false;
@@ -44,29 +44,34 @@ bool unc_encoder_rgb3_rgba::can_encode(const std::shared_ptr<const HeifPixelImag
}
-void unc_encoder_rgb3_rgba::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
- std::shared_ptr<Box_uncC>& uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+std::unique_ptr<const unc_encoder> unc_encoder_factory_rgb3_rgba::create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
+{
+ return std::make_unique<unc_encoder_rgb3_rgba>(image, options);
+}
+
+
+unc_encoder_rgb3_rgba::unc_encoder_rgb3_rgba(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options)
{
- cmpd->add_component({component_type_red});
- cmpd->add_component({component_type_green});
- cmpd->add_component({component_type_blue});
+ m_cmpd->add_component({component_type_red});
+ m_cmpd->add_component({component_type_green});
+ m_cmpd->add_component({component_type_blue});
bool save_alpha = image->has_alpha();
if (save_alpha) {
- cmpd->add_component({component_type_alpha});
+ m_cmpd->add_component({component_type_alpha});
}
uint8_t bpp = image->get_bits_per_pixel(heif_channel_interleaved);
if (bpp == 8) {
if (save_alpha) {
- uncC->set_profile(fourcc("rgba"));
+ m_uncC->set_profile(fourcc("rgba"));
}
else {
- uncC->set_profile(fourcc("rgb3"));
+ m_uncC->set_profile(fourcc("rgb3"));
}
}
@@ -75,19 +80,18 @@ void unc_encoder_rgb3_rgba::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
component_align_size = 1;
}
- uncC->set_interleave_type(interleave_mode_pixel);
- uncC->set_sampling_type(0);
- uncC->add_component({0, bpp, component_format_unsigned, component_align_size});
- uncC->add_component({1, bpp, component_format_unsigned, component_align_size});
- uncC->add_component({2, bpp, component_format_unsigned, component_align_size});
+ m_uncC->set_interleave_type(interleave_mode_pixel);
+ m_uncC->set_sampling_type(0);
+ m_uncC->add_component({0, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({1, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({2, bpp, component_format_unsigned, component_align_size});
if (save_alpha) {
- uncC->add_component({3, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({3, bpp, component_format_unsigned, component_align_size});
}
}
-std::vector<uint8_t> unc_encoder_rgb3_rgba::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image,
- const heif_encoding_options& options) const
+std::vector<uint8_t> unc_encoder_rgb3_rgba::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image) const
{
std::vector<uint8_t> data;
diff --git a/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.h b/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.h
index 2fd4c325..2c196287 100644
--- a/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.h
+++ b/libheif/codecs/uncompressed/unc_encoder_rgb3_rgba.h
@@ -25,18 +25,22 @@
class unc_encoder_rgb3_rgba : public unc_encoder
{
+public:
+ unc_encoder_rgb3_rgba(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options);
+
+ [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image) const override;
+};
+
+
+class unc_encoder_factory_rgb3_rgba : public unc_encoder_factory
+{
public:
[[nodiscard]] bool can_encode(const std::shared_ptr<const HeifPixelImage>& image,
const heif_encoding_options& options) const override;
- void fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& out_cmpd,
- std::shared_ptr<Box_uncC>& out_uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
-
- [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
+ std::unique_ptr<const unc_encoder> create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const override;
};
-
#endif //LIBHEIF_UNC_ENCODER_RGB3_RGBA_H
diff --git a/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.cc b/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.cc
index 1265a061..993bd7eb 100644
--- a/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.cc
+++ b/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.cc
@@ -20,8 +20,8 @@
#include "unc_types.h"
-bool unc_encoder_rgb_hdr_packed_interleave::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+bool unc_encoder_factory_rgb_hdr_packed_interleave::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
{
if (image->get_colorspace() != heif_colorspace_RGB) {
return false;
@@ -43,33 +43,37 @@ bool unc_encoder_rgb_hdr_packed_interleave::can_encode(const std::shared_ptr<con
}
-void unc_encoder_rgb_hdr_packed_interleave::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
- std::shared_ptr<Box_uncC>& uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+std::unique_ptr<const unc_encoder> unc_encoder_factory_rgb_hdr_packed_interleave::create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
{
- cmpd->add_component({component_type_red});
- cmpd->add_component({component_type_green});
- cmpd->add_component({component_type_blue});
+ return std::make_unique<unc_encoder_rgb_hdr_packed_interleave>(image, options);
+}
+
+
+unc_encoder_rgb_hdr_packed_interleave::unc_encoder_rgb_hdr_packed_interleave(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options)
+{
+ m_cmpd->add_component({component_type_red});
+ m_cmpd->add_component({component_type_green});
+ m_cmpd->add_component({component_type_blue});
uint8_t bpp = image->get_bits_per_pixel(heif_channel_interleaved);
uint8_t nBits = static_cast<uint8_t>(3 * bpp);
uint8_t bytes_per_pixel = static_cast<uint8_t>((nBits + 7) / 8);
- uncC->set_interleave_type(interleave_mode_pixel);
- uncC->set_pixel_size(bytes_per_pixel);
- uncC->set_sampling_type(0);
- uncC->set_components_little_endian(true);
+ m_uncC->set_interleave_type(interleave_mode_pixel);
+ m_uncC->set_pixel_size(bytes_per_pixel);
+ m_uncC->set_sampling_type(0);
+ m_uncC->set_components_little_endian(true);
- uncC->add_component({0, bpp, component_format_unsigned, 0});
- uncC->add_component({1, bpp, component_format_unsigned, 0});
- uncC->add_component({2, bpp, component_format_unsigned, 0});
+ m_uncC->add_component({0, bpp, component_format_unsigned, 0});
+ m_uncC->add_component({1, bpp, component_format_unsigned, 0});
+ m_uncC->add_component({2, bpp, component_format_unsigned, 0});
}
-std::vector<uint8_t> unc_encoder_rgb_hdr_packed_interleave::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image,
- const heif_encoding_options& options) const
+std::vector<uint8_t> unc_encoder_rgb_hdr_packed_interleave::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image) const
{
std::vector<uint8_t> data;
@@ -80,6 +84,7 @@ std::vector<uint8_t> unc_encoder_rgb_hdr_packed_interleave::encode_tile(const st
size_t src_stride;
const auto* src_data = reinterpret_cast<const uint16_t*>(src_image->get_plane(heif_channel_interleaved, &src_stride));
+ src_stride /= 2;
uint64_t out_size = static_cast<uint64_t>(src_image->get_height()) * src_image->get_width() * bytes_per_pixel;
data.resize(out_size);
diff --git a/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.h b/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.h
index e4db5c13..3dd69646 100644
--- a/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.h
+++ b/libheif/codecs/uncompressed/unc_encoder_rgb_hdr_packed_interleave.h
@@ -20,18 +20,22 @@
class unc_encoder_rgb_hdr_packed_interleave : public unc_encoder
{
+public:
+ unc_encoder_rgb_hdr_packed_interleave(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options);
+
+ [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image) const override;
+};
+
+
+class unc_encoder_factory_rgb_hdr_packed_interleave : public unc_encoder_factory
+{
public:
[[nodiscard]] bool can_encode(const std::shared_ptr<const HeifPixelImage>& image,
const heif_encoding_options& options) const override;
- void fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& out_cmpd,
- std::shared_ptr<Box_uncC>& out_uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
-
- [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
+ std::unique_ptr<const unc_encoder> create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const override;
};
-
#endif //LIBHEIF_UNC_ENCODER_RGB10_12_H
diff --git a/libheif/codecs/uncompressed/unc_encoder_rrggbb.cc b/libheif/codecs/uncompressed/unc_encoder_rrggbb.cc
index a64f6ded..26d3e1aa 100644
--- a/libheif/codecs/uncompressed/unc_encoder_rrggbb.cc
+++ b/libheif/codecs/uncompressed/unc_encoder_rrggbb.cc
@@ -27,8 +27,8 @@
#include "unc_types.h"
-bool unc_encoder_rrggbb::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+bool unc_encoder_factory_rrggbb::can_encode(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
{
if (image->get_colorspace() != heif_colorspace_RGB) {
return false;
@@ -48,19 +48,24 @@ bool unc_encoder_rrggbb::can_encode(const std::shared_ptr<const HeifPixelImage>&
}
-void unc_encoder_rrggbb::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
- std::shared_ptr<Box_uncC>& uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const
+std::unique_ptr<const unc_encoder> unc_encoder_factory_rrggbb::create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const
+{
+ return std::make_unique<unc_encoder_rrggbb>(image, options);
+}
+
+
+unc_encoder_rrggbb::unc_encoder_rrggbb(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options)
{
- cmpd->add_component({component_type_red});
- cmpd->add_component({component_type_green});
- cmpd->add_component({component_type_blue});
+ m_cmpd->add_component({component_type_red});
+ m_cmpd->add_component({component_type_green});
+ m_cmpd->add_component({component_type_blue});
bool save_alpha = image->has_alpha();
if (save_alpha) {
- cmpd->add_component({component_type_alpha});
+ m_cmpd->add_component({component_type_alpha});
}
bool little_endian = (image->get_chroma_format() == heif_chroma_interleaved_RRGGBB_LE ||
@@ -73,21 +78,20 @@ void unc_encoder_rrggbb::fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
component_align_size = 0;
}
- uncC->set_interleave_type(interleave_mode_pixel);
- uncC->set_sampling_type(0);
- uncC->set_components_little_endian(little_endian);
+ m_uncC->set_interleave_type(interleave_mode_pixel);
+ m_uncC->set_sampling_type(0);
+ m_uncC->set_components_little_endian(little_endian);
- uncC->add_component({0, bpp, component_format_unsigned, component_align_size});
- uncC->add_component({1, bpp, component_format_unsigned, component_align_size});
- uncC->add_component({2, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({0, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({1, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({2, bpp, component_format_unsigned, component_align_size});
if (save_alpha) {
- uncC->add_component({3, bpp, component_format_unsigned, component_align_size});
+ m_uncC->add_component({3, bpp, component_format_unsigned, component_align_size});
}
}
-std::vector<uint8_t> unc_encoder_rrggbb::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image,
- const heif_encoding_options& options) const
+std::vector<uint8_t> unc_encoder_rrggbb::encode_tile(const std::shared_ptr<const HeifPixelImage>& src_image) const
{
std::vector<uint8_t> data;
diff --git a/libheif/codecs/uncompressed/unc_encoder_rrggbb.h b/libheif/codecs/uncompressed/unc_encoder_rrggbb.h
index 4e0e0ab1..431cb19e 100644
--- a/libheif/codecs/uncompressed/unc_encoder_rrggbb.h
+++ b/libheif/codecs/uncompressed/unc_encoder_rrggbb.h
@@ -25,17 +25,22 @@
class unc_encoder_rrggbb : public unc_encoder
{
+public:
+ unc_encoder_rrggbb(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options);
+
+ [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image) const override;
+};
+
+
+class unc_encoder_factory_rrggbb : public unc_encoder_factory
+{
public:
[[nodiscard]] bool can_encode(const std::shared_ptr<const HeifPixelImage>& image,
const heif_encoding_options& options) const override;
- void fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& out_cmpd,
- std::shared_ptr<Box_uncC>& out_uncC,
- const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
-
- [[nodiscard]] std::vector<uint8_t> encode_tile(const std::shared_ptr<const HeifPixelImage>& image,
- const heif_encoding_options& options) const override;
+ std::unique_ptr<const unc_encoder> create(const std::shared_ptr<const HeifPixelImage>& image,
+ const heif_encoding_options& options) const override;
};
diff --git a/libheif/image-items/unc_image.cc b/libheif/image-items/unc_image.cc
index 8e09644a..0ab5d0b9 100644
--- a/libheif/image-items/unc_image.cc
+++ b/libheif/image-items/unc_image.cc
@@ -92,7 +92,7 @@ Result<Encoder::CodedImageData> ImageItem_uncompressed::encode(const std::shared
const heif_encoding_options& options,
heif_image_input_class input_class)
{
- Result<const unc_encoder*> uncEncoder = unc_encoder::get_unc_encoder(src_image, options);
+ Result<std::unique_ptr<const unc_encoder>> uncEncoder = unc_encoder_factory::get_unc_encoder(src_image, options);
if (!uncEncoder) {
return {uncEncoder.error()};
}
@@ -118,7 +118,7 @@ Result<std::shared_ptr<ImageItem_uncompressed>> ImageItem_uncompressed::add_unci
}
- Result<const unc_encoder*> uncEncoder = unc_encoder::get_unc_encoder(prototype, *encoding_options);
+ Result<std::unique_ptr<const unc_encoder>> uncEncoder = unc_encoder_factory::get_unc_encoder(prototype, *encoding_options);
if (!uncEncoder) {
return {uncEncoder.error()};
}
@@ -131,7 +131,7 @@ Result<std::shared_ptr<ImageItem_uncompressed>> ImageItem_uncompressed::add_unci
heif_item_id unci_id = ctx->get_heif_file()->add_new_image(fourcc("unci"));
auto unci_image = std::make_shared<ImageItem_uncompressed>(ctx, unci_id);
unci_image->set_resolution(parameters->image_width, parameters->image_height);
- unci_image->m_unc_encoder = *uncEncoder;
+ unci_image->m_unc_encoder = std::move(*uncEncoder);
unci_image->m_encoding_options = *encoding_options;
ctx->insert_image_item(unci_id, unci_image);
@@ -142,19 +142,10 @@ Result<std::shared_ptr<ImageItem_uncompressed>> ImageItem_uncompressed::add_unci
// --- generate configuration property boxes
- Result<const unc_encoder*> encoderResult = unc_encoder::get_unc_encoder(prototype, *encoding_options);
- if (encoderResult.error()) {
- return encoderResult.error();
- }
-
- std::shared_ptr<Box_uncC> uncC = std::make_shared<Box_uncC>();
- std::shared_ptr<Box_cmpd> cmpd = std::make_shared<Box_cmpd>();
-
- (*encoderResult)->fill_cmpd_and_uncC(cmpd, uncC, prototype, *encoding_options);
-
+ auto uncC = unci_image->m_unc_encoder->get_uncC();
unci_image->add_property(uncC, true);
if (!uncC->is_minimized()) {
- unci_image->add_property(cmpd, true);
+ unci_image->add_property(unci_image->m_unc_encoder->get_cmpd(), true);
}
@@ -240,7 +231,7 @@ Error ImageItem_uncompressed::add_image_tile(uint32_t tile_x, uint32_t tile_y, c
// TODO: drop alpha
}
- Result<std::vector<uint8_t>> codedBitstreamResult = m_unc_encoder->encode_tile(image, m_encoding_options);
+ Result<std::vector<uint8_t>> codedBitstreamResult = m_unc_encoder->encode_tile(image);
if (!codedBitstreamResult) {
return codedBitstreamResult.error();
}
diff --git a/libheif/image-items/unc_image.h b/libheif/image-items/unc_image.h
index 50c286fb..889f7255 100644
--- a/libheif/image-items/unc_image.h
+++ b/libheif/image-items/unc_image.h
@@ -32,6 +32,7 @@
#include <vector>
#include <memory>
#include <set>
+#include "codecs/uncompressed/unc_encoder.h"
class unc_encoder;
class HeifContext;
@@ -98,7 +99,7 @@ private:
std::shared_ptr<class Decoder_uncompressed> m_decoder;
std::shared_ptr<class Encoder_uncompressed> m_encoder;
- const unc_encoder* m_unc_encoder = nullptr;
+ std::unique_ptr<const unc_encoder> m_unc_encoder;
heif_encoding_options m_encoding_options;
/*