Error fill_cmpd_and_uncC()

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;
}