in libheif/codecs/uncompressed_image.cc [989:1180]
Error fill_cmpd_and_uncC(std::shared_ptr<Box_cmpd>& cmpd, std::shared_ptr<Box_uncC>& uncC, const std::shared_ptr<HeifPixelImage>& image)
{
const heif_colorspace colourspace = image->get_colorspace();
if (colourspace == heif_colorspace_YCbCr) {
if (!(image->has_channel(heif_channel_Y) && image->has_channel(heif_channel_Cb) && image->has_channel(heif_channel_Cr)))
{
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Invalid colourspace / channel combination - YCbCr");
}
Box_cmpd::Component yComponent = {component_type_Y};
cmpd->add_component(yComponent);
Box_cmpd::Component cbComponent = {component_type_Cb};
cmpd->add_component(cbComponent);
Box_cmpd::Component crComponent = {component_type_Cr};
cmpd->add_component(crComponent);
uint8_t bpp_y = image->get_bits_per_pixel(heif_channel_Y);
Box_uncC::Component component0 = {0, bpp_y, component_format_unsigned, 0};
uncC->add_component(component0);
uint8_t bpp_cb = image->get_bits_per_pixel(heif_channel_Cb);
Box_uncC::Component component1 = {1, bpp_cb, component_format_unsigned, 0};
uncC->add_component(component1);
uint8_t bpp_cr = image->get_bits_per_pixel(heif_channel_Cr);
Box_uncC::Component component2 = {2, bpp_cr, component_format_unsigned, 0};
uncC->add_component(component2);
if (image->get_chroma_format() == heif_chroma_444)
{
uncC->set_sampling_type(sampling_mode_no_subsampling);
}
else if (image->get_chroma_format() == heif_chroma_422)
{
uncC->set_sampling_type(sampling_mode_422);
}
else if (image->get_chroma_format() == heif_chroma_420)
{
uncC->set_sampling_type(sampling_mode_420);
}
else
{
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Unsupported YCbCr sub-sampling type");
}
uncC->set_interleave_type(interleave_mode_component);
uncC->set_block_size(0);
uncC->set_components_little_endian(false);
uncC->set_block_pad_lsb(false);
uncC->set_block_little_endian(false);
uncC->set_block_reversed(false);
uncC->set_pad_unknown(false);
uncC->set_pixel_size(0);
uncC->set_row_align_size(0);
uncC->set_tile_align_size(0);
uncC->set_number_of_tile_columns(1);
uncC->set_number_of_tile_rows(1);
}
else if (colourspace == heif_colorspace_RGB)
{
if (!((image->get_chroma_format() == heif_chroma_444) ||
(image->get_chroma_format() == heif_chroma_interleaved_RGB) ||
(image->get_chroma_format() == heif_chroma_interleaved_RGBA) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBB_BE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBB_LE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_BE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE))) {
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Unsupported colourspace / chroma combination - RGB");
}
Box_cmpd::Component rComponent = {component_type_red};
cmpd->add_component(rComponent);
Box_cmpd::Component gComponent = {component_type_green};
cmpd->add_component(gComponent);
Box_cmpd::Component bComponent = {component_type_blue};
cmpd->add_component(bComponent);
if ((image->get_chroma_format() == heif_chroma_interleaved_RGBA) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_BE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE) ||
(image->has_channel(heif_channel_Alpha)))
{
Box_cmpd::Component alphaComponent = {component_type_alpha};
cmpd->add_component(alphaComponent);
}
if ((image->get_chroma_format() == heif_chroma_interleaved_RGB) ||
(image->get_chroma_format() == heif_chroma_interleaved_RGBA) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBB_BE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBB_LE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_BE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE))
{
uncC->set_interleave_type(interleave_mode_pixel);
int bpp = image->get_bits_per_pixel(heif_channel_interleaved);
uint8_t component_align = 1;
if (bpp == 8)
{
component_align = 0;
}
else if (bpp > 8)
{
component_align = 2;
}
Box_uncC::Component component0 = {0, (uint8_t)(bpp), component_format_unsigned, component_align};
uncC->add_component(component0);
Box_uncC::Component component1 = {1, (uint8_t)(bpp), component_format_unsigned, component_align};
uncC->add_component(component1);
Box_uncC::Component component2 = {2, (uint8_t)(bpp), component_format_unsigned, component_align};
uncC->add_component(component2);
if ((image->get_chroma_format() == heif_chroma_interleaved_RGBA) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_BE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE))
{
Box_uncC::Component component3 = {
3, (uint8_t)(bpp), component_format_unsigned, component_align};
uncC->add_component(component3);
}
} else {
uncC->set_interleave_type(interleave_mode_component);
int bpp_red = image->get_bits_per_pixel(heif_channel_R);
Box_uncC::Component component0 = {0, (uint8_t)(bpp_red), component_format_unsigned, 0};
uncC->add_component(component0);
int bpp_green = image->get_bits_per_pixel(heif_channel_G);
Box_uncC::Component component1 = {1, (uint8_t)(bpp_green), component_format_unsigned, 0};
uncC->add_component(component1);
int bpp_blue = image->get_bits_per_pixel(heif_channel_B);
Box_uncC::Component component2 = {2, (uint8_t)(bpp_blue), component_format_unsigned, 0};
uncC->add_component(component2);
if(image->has_channel(heif_channel_Alpha))
{
int bpp_alpha = image->get_bits_per_pixel(heif_channel_Alpha);
Box_uncC::Component component3 = {3, (uint8_t)(bpp_alpha), component_format_unsigned, 0};
uncC->add_component(component3);
}
}
uncC->set_sampling_type(sampling_mode_no_subsampling);
uncC->set_block_size(0);
if ((image->get_chroma_format() == heif_chroma_interleaved_RRGGBB_LE) ||
(image->get_chroma_format() == heif_chroma_interleaved_RRGGBBAA_LE))
{
uncC->set_components_little_endian(true);
} else {
uncC->set_components_little_endian(false);
}
uncC->set_block_pad_lsb(false);
uncC->set_block_little_endian(false);
uncC->set_block_reversed(false);
uncC->set_pad_unknown(false);
uncC->set_pixel_size(0);
uncC->set_row_align_size(0);
uncC->set_tile_align_size(0);
uncC->set_number_of_tile_columns(1);
uncC->set_number_of_tile_rows(1);
}
else if (colourspace == heif_colorspace_monochrome)
{
Box_cmpd::Component monoComponent = {component_type_monochrome};
cmpd->add_component(monoComponent);
if (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);
if (image->has_channel(heif_channel_Alpha))
{
bpp = image->get_bits_per_pixel(heif_channel_Alpha);
Box_uncC::Component component1 = {1, (uint8_t)(bpp), component_format_unsigned, 0};
uncC->add_component(component1);
}
uncC->set_sampling_type(sampling_mode_no_subsampling);
uncC->set_interleave_type(interleave_mode_component);
uncC->set_block_size(0);
uncC->set_components_little_endian(false);
uncC->set_block_pad_lsb(false);
uncC->set_block_little_endian(false);
uncC->set_block_reversed(false);
uncC->set_pad_unknown(false);
uncC->set_pixel_size(0);
uncC->set_row_align_size(0);
uncC->set_tile_align_size(0);
uncC->set_number_of_tile_columns(1);
uncC->set_number_of_tile_rows(1);
}
else
{
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_data_version,
"Unsupported colourspace");
}
return Error::Ok;
}