Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions libheif/api/libheif/heif_experimental.cc
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,11 @@ void heif_pyramid_layer_info_release(heif_pyramid_layer_info* infos)
heif_error heif_image_add_channel(heif_image* image,
heif_channel channel,
int width, int height,
heif_channel_datatype datatype, int bit_depth)
heif_channel_datatype datatype,
int bit_depth,
size_t* out_index)
{
if (auto err = image->image->add_channel(channel, width, height, datatype, bit_depth, nullptr)) {
if (auto err = image->image->add_channel(channel, width, height, datatype, bit_depth, nullptr, out_index)) {
return err.error_struct(image->image.get());
}
else {
Expand Down Expand Up @@ -470,3 +472,23 @@ heif_error heif_context_add_tiled_image(heif_context* ctx,
return heif_error_success;
}
#endif

int16_t* heif_image_get_channel_int16(heif_image* image,
size_t channel_index,
size_t* out_stride)
{
if (!out_stride) {
return nullptr;
}

if (!image || !image->image) {
*out_stride = 0;
return nullptr;
}

size_t stride;
uint8_t* p = image->image->get_plane(channel_index, &stride);

*out_stride = stride / sizeof(int16_t);
return reinterpret_cast<int16_t*>(p);
}
7 changes: 5 additions & 2 deletions libheif/api/libheif/heif_experimental.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ heif_error heif_image_add_channel(heif_image* image,
enum heif_channel channel,
int width, int height,
enum heif_channel_datatype datatype,
int bit_depth);
int bit_depth,
size_t* out_index);




LIBHEIF_API
Expand Down Expand Up @@ -289,7 +292,7 @@ uint64_t* heif_image_get_channel_uint64(heif_image*,

LIBHEIF_API
int16_t* heif_image_get_channel_int16(heif_image*,
enum heif_channel channel,
size_t channel_index,
size_t* out_stride);

LIBHEIF_API
Expand Down
41 changes: 37 additions & 4 deletions libheif/codecs/uncompressed/unc_codec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -980,20 +980,27 @@ Error fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
}
else if (colourspace == heif_colorspace_monochrome) {
Box_cmpd::Component monoComponent = {component_type_monochrome};
cmpd->add_component(monoComponent);
for (size_t i = 0; i < image->get_channel_count(); i++) {
cmpd->add_component(monoComponent);
}

if (save_alpha_channel && image->has_channel(heif_channel_Alpha)) {
Box_cmpd::Component alphaComponent = {component_type_alpha};
cmpd->add_component(alphaComponent);
}

int bpp = image->get_bits_per_pixel(heif_channel_Y);
Box_uncC::Component component0 = {0, (uint8_t) (bpp), component_format_unsigned, 0};
uncC->add_component(component0);
heif_uncompressed_component_format format = to_unc_component_format(image, heif_channel_Y);
Box_uncC::Component component0 = {0, (uint8_t) (bpp), (uint8_t) format, 0};
for (size_t i = 0; i < image->get_channel_count(); i++) {
// TODO: don't assume all channels have the same bpp and format
uncC->add_component(component0);
}

if (save_alpha_channel && image->has_channel(heif_channel_Alpha)) {
heif_uncompressed_component_format format_alpha = to_unc_component_format(image, heif_channel_Alpha);
bpp = image->get_bits_per_pixel(heif_channel_Alpha);
Box_uncC::Component component1 = {1, (uint8_t) (bpp), component_format_unsigned, 0};
Box_uncC::Component component1 = {1, (uint8_t) (bpp), (uint8_t) format_alpha, 0};
uncC->add_component(component1);
}

Expand All @@ -1018,3 +1025,29 @@ Error fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd,
}
return Error::Ok;
}

heif_uncompressed_component_format to_unc_component_format(heif_channel_datatype channel_datatype)
{
switch (channel_datatype) {
case heif_channel_datatype_signed_integer:
return component_format_signed;

case heif_channel_datatype_floating_point:
return component_format_float;

case heif_channel_datatype_complex_number:
return component_format_complex;

case heif_channel_datatype_unsigned_integer:
case heif_channel_datatype_undefined:
default:
return component_format_unsigned;
}
}

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);
heif_uncompressed_component_format component_format = to_unc_component_format(datatype);
return component_format;
}
3 changes: 3 additions & 0 deletions libheif/codecs/uncompressed/unc_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ bool map_uncompressed_component_to_channel(const std::shared_ptr<const Box_cmpd>
Box_uncC::Component component,
heif_channel *channel);

heif_uncompressed_component_format to_unc_component_format(heif_channel_datatype);

heif_uncompressed_component_format to_unc_component_format(const std::shared_ptr<const HeifPixelImage>&, heif_channel);

class UncompressedImageCodec
{
Expand Down
14 changes: 3 additions & 11 deletions libheif/image-items/unc_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,18 +288,10 @@ Result<std::vector<uint8_t>> encode_image_tile(const std::shared_ptr<const HeifP
{
uint64_t offset = 0;
std::vector<heif_channel> channels;
if (src_image->has_channel(heif_channel_Alpha))
{
channels = {heif_channel_Y, heif_channel_Alpha};
}
else
{
channels = {heif_channel_Y};
}
for (heif_channel channel : channels)
{
size_t channel_count = src_image->get_channel_count();
for (size_t i = 0; i < channel_count; i++) {
size_t src_stride;
const uint8_t* src_data = src_image->get_plane(channel, &src_stride);
const uint8_t* src_data = src_image->get_plane(i, &src_stride);
uint64_t out_size = static_cast<uint64_t>(src_image->get_height()) * src_stride;
data.resize(data.size() + out_size);
memcpy(data.data() + offset, src_data, out_size);
Expand Down
Loading
Loading