Error UncompressedImageCodec::decode_uncompressed_image()

in libheif/codecs/uncompressed_image.cc [862:987]


Error UncompressedImageCodec::decode_uncompressed_image(const HeifContext* context,
                                                        heif_item_id ID,
                                                        std::shared_ptr<HeifPixelImage>& img,
                                                        const std::vector<uint8_t>& source_data)
{
  if (source_data.empty()) {
    return {heif_error_Invalid_input,
            heif_suberror_Unspecified,
            "Uncompressed image data is empty"};
  }

  // Get the properties for this item
  // We need: ispe, cmpd, uncC
  std::vector<std::shared_ptr<Box>> item_properties;
  Error error = context->get_heif_file()->get_properties(ID, item_properties);
  if (error) {
    printf("failed to get properties\n");
    return error;
  }

  uint32_t width = 0;
  uint32_t height = 0;
  bool found_ispe = false;
  std::shared_ptr<Box_cmpd> cmpd;
  std::shared_ptr<Box_uncC> uncC;
  std::shared_ptr<Box_cmpC> cmpC;
  std::shared_ptr<Box_icbr> icbr;

  for (const auto& prop : item_properties) {
    auto ispe = std::dynamic_pointer_cast<Box_ispe>(prop);
    if (ispe) {
      width = ispe->get_width();
      height = ispe->get_height();
      error = context->check_resolution(width, height);
      if (error) {
        return error;
      }

      found_ispe = true;
    }

    auto maybe_cmpd = std::dynamic_pointer_cast<Box_cmpd>(prop);
    if (maybe_cmpd) {
      cmpd = maybe_cmpd;
    }

    auto maybe_uncC = std::dynamic_pointer_cast<Box_uncC>(prop);
    if (maybe_uncC) {
      uncC = maybe_uncC;
    }

    auto maybe_cmpC = std::dynamic_pointer_cast<Box_cmpC>(prop);
    if (maybe_cmpC) {
      cmpC = maybe_cmpC;
    }

    auto maybe_icbr = std::dynamic_pointer_cast<Box_icbr>(prop);
    if (maybe_icbr) {
      icbr = maybe_icbr;
    }

  }


  // if we miss a required box, show error
  if (!found_ispe) {
    return Error(heif_error_Unsupported_feature,
                 heif_suberror_Unsupported_data_version,
                 "Missing required ispe box for uncompressed codec");
  }
  if (!uncC) {
    return Error(heif_error_Unsupported_feature,
                 heif_suberror_Unsupported_data_version,
                 "Missing required uncC box for uncompressed codec");
  }
  if (!cmpd && (uncC->get_version() !=1)) {
    return Error(heif_error_Unsupported_feature,
                 heif_suberror_Unsupported_data_version,
                 "Missing required cmpd or uncC version 1 box for uncompressed codec");
}

  // check if we support the type of image

  error = uncompressed_image_type_is_supported(uncC, cmpd);
  if (error) {
    printf("unsupported image type\n");
    return error;
  }

  img = std::make_shared<HeifPixelImage>();
  heif_chroma chroma;
  heif_colorspace colourspace;
  error = get_heif_chroma_uncompressed(uncC, cmpd, &chroma, &colourspace);
  if (error) {
    printf("failed to get chroma uncompressed\n");
    return error;
  }
  img->create(width, height,
              colourspace,
              chroma);

  for (Box_uncC::Component component : uncC->get_components()) {
    heif_channel channel;
    if (map_uncompressed_component_to_channel(cmpd, uncC, component, &channel)) {
      if ((channel == heif_channel_Cb) || (channel == heif_channel_Cr)) {
        img->add_plane(channel, (width / chroma_h_subsampling(chroma)), (height / chroma_v_subsampling(chroma)), component.component_bit_depth);
      } else {
        img->add_plane(channel, width, height, component.component_bit_depth);
      }
    }
  }

  AbstractDecoder *decoder = makeDecoder(width, height, cmpd, uncC);
  if (decoder != nullptr) {
    Error result = decoder->decode(source_data, img);
    delete decoder;
    return result;
  } else {
    printf("bad interleave mode - we should have detected this earlier: %d\n", uncC->get_interleave_type());
    std::stringstream sstr;
    sstr << "Uncompressed interleave_type of " << ((int) uncC->get_interleave_type()) << " is not implemented yet";
    return Error(heif_error_Unsupported_feature,
                heif_suberror_Unsupported_data_version,
               sstr.str());
  }
}