Error HeifFile::get_compressed_image_data()

in libheif/file.cc [1017:1150]


Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>* data) const
{
#if ENABLE_PARALLEL_TILE_DECODING
  std::lock_guard<std::mutex> guard(m_read_mutex);
#endif

  if (!image_exists(ID)) {
    return Error(heif_error_Usage_error,
                 heif_suberror_Nonexisting_item_referenced);
  }

  auto infe_box = get_infe_box(ID);
  if (!infe_box) {
    return Error(heif_error_Usage_error,
                 heif_suberror_Nonexisting_item_referenced);
  }


  std::string item_type = infe_box->get_item_type();
  std::string content_type = infe_box->get_content_type();

  // --- get coded image data pointers

  auto items = m_iloc_box->get_items();
  const Box_iloc::Item* item = nullptr;
  for (const auto& i : items) {
    if (i.item_ID == ID) {
      item = &i;
      break;
    }
  }
  if (!item) {
    std::stringstream sstr;
    sstr << "Item with ID " << ID << " has no compressed data";

    return Error(heif_error_Invalid_input,
                 heif_suberror_No_item_data,
                 sstr.str());
  }

  if (item_type == "hvc1") {
    // --- --- --- HEVC
    return get_compressed_image_data_hvc1(ID, data, item);
  }
  else if (item_type == "vvc1") {
    // --- --- --- VVC
    return get_compressed_image_data_vvc(ID, data, item);
  }
  else if (item_type == "av01") {
    return get_compressed_image_data_av1(ID, data, item);
  }
  else if (item_type == "jpeg" ||
           (item_type == "mime" && get_content_type(ID) == "image/jpeg")) {
    return get_compressed_image_data_jpeg(ID, data, item);
  }
  else if (item_type == "j2k1") {
      return get_compressed_image_data_jpeg2000(ID, item, data);
  }
#if WITH_UNCOMPRESSED_CODEC
  else if (item_type == "unci") {
    return get_compressed_image_data_uncompressed(ID, data, item);
  }
#endif
  else if (true ||  // fallback case for all kinds of generic metadata (e.g. 'iptc')
           item_type == "grid" ||
           item_type == "iovl" ||
           item_type == "Exif" ||
           (item_type == "mime" && content_type == "application/rdf+xml")) {
    Error error;
    bool read_uncompressed = true;
    if (item_type == "mime") {
      std::string encoding = infe_box->get_content_encoding();
      if (encoding == "compress_zlib") {
#if HAVE_ZLIB
        read_uncompressed = false;
        std::vector<uint8_t> compressed_data;
        error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, &compressed_data);
        if (error) {
          return error;
        }
        error = decompress_zlib(compressed_data, data);
        if (error) {
          return error;
        }
#else
        return Error(heif_error_Unsupported_feature,
                     heif_suberror_Unsupported_header_compression_method,
                     encoding);
#endif
      }
      else if (encoding == "deflate") {
#if HAVE_ZLIB
        read_uncompressed = false;
        std::vector<uint8_t> compressed_data;
        error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, &compressed_data);
        if (error) {
          return error;
        }
        error = decompress_deflate(compressed_data, data);
        if (error) {
          return error;
        }
#else
        return Error(heif_error_Unsupported_feature,
                     heif_suberror_Unsupported_header_compression_method,
                     encoding);
#endif
      }
      else if (encoding == "br") {
#if HAVE_BROTLI
        read_uncompressed = false;
        std::vector<uint8_t> compressed_data;
        error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, &compressed_data);
        if (error) {
          return error;
        }
        error = decompress_brotli(compressed_data, data);
        if (error) {
          return error;
        }
#else
        return Error(heif_error_Unsupported_feature,
                     heif_suberror_Unsupported_header_compression_method,
                     encoding);
#endif
      }
    }

    if (read_uncompressed) {
      return m_iloc_box->read_data(*item, m_input_stream, m_idat_box, data);
    }
  }
  return Error(heif_error_Unsupported_feature, heif_suberror_Unsupported_codec);
}