Skip to content

Commit

Permalink
handle iden derived images
Browse files Browse the repository at this point in the history
  • Loading branch information
bradh committed Jan 17, 2024
1 parent 3e5b81d commit 3b1cc73
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 4 deletions.
2 changes: 2 additions & 0 deletions go/heif/heif.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ const (

SuberrorInvalidRegionData = C.heif_suberror_Invalid_region_data

SuberrorMissingIrefReference = C.heif_suberror_missing_iref_reference

SuberrorWrongTileImagePixelDepth = C.heif_suberror_Wrong_tile_image_pixel_depth

SuberrorUnknownNCLXColorPrimaries = C.heif_suberror_Unknown_NCLX_color_primaries
Expand Down
2 changes: 2 additions & 0 deletions libheif/error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ const char* Error::get_error_string(heif_suberror_code err)
return "Unknown NCLX matrix coefficients";
case heif_suberror_Invalid_region_data:
return "Invalid region item data";
case heif_suberror_missing_iref_reference:
return "'iref' box does not include a referenced item";
case heif_suberror_Invalid_J2K_codestream:
return "Invalid JPEG 2000 codestream";

Expand Down
51 changes: 49 additions & 2 deletions libheif/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -398,15 +398,15 @@ Error HeifFile::parse_heif_file(BitstreamRange& range)


Error HeifFile::check_for_ref_cycle(heif_item_id ID,
std::shared_ptr<Box_iref>& iref_box) const
const std::shared_ptr<Box_iref>& iref_box) const
{
std::unordered_set<heif_item_id> parent_items;
return check_for_ref_cycle_recursion(ID, iref_box, parent_items);
}


Error HeifFile::check_for_ref_cycle_recursion(heif_item_id ID,
std::shared_ptr<Box_iref>& iref_box,
const std::shared_ptr<Box_iref>& iref_box,
std::unordered_set<heif_item_id>& parent_items) const {
if (parent_items.find(ID) != parent_items.end()) {
return Error(heif_error_Invalid_input,
Expand Down Expand Up @@ -697,6 +697,43 @@ int HeifFile::jpeg_get_bits_per_pixel(heif_item_id imageID) const
return -1;
}

Error HeifFile::get_source_image_id(const heif_item_id from_ID, heif_item_id *to_ID) const
{
// At this point iref is required (see ISO/IEC 23008-12:2022 Section 6.6.2.1)
if (!m_iref_box) {
return Error(heif_error_Invalid_input,
heif_suberror_No_iref_box);
}
Error error = check_for_ref_cycle(from_ID, m_iref_box);
if (error) {
return error;
}
std::vector<uint32_t> references = m_iref_box->get_references(from_ID, fourcc_to_uint32("dimg"));
if (references.size() != 1) {
return Error(heif_error_Invalid_input,
heif_suberror_missing_iref_reference);
}
heif_item_id id = references[0];

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

auto infe_box = get_infe(id);
if (!infe_box) {
return Error(heif_error_Usage_error,
heif_suberror_Nonexisting_item_referenced);
}

std::string item_type = infe_box->get_item_type();
if (item_type == "iden") {
return get_source_image_id(id, to_ID);
}
*to_ID = id;

return Error::Ok;
}

Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>* data) const
{
Expand All @@ -719,6 +756,16 @@ Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>*
std::string item_type = infe_box->get_item_type();
std::string content_type = infe_box->get_content_type();

if (item_type == "iden") {
// we want to return the image data for the source image
heif_item_id to_ID = 0;
Error error = get_source_image_id(ID, &to_ID);
if (error.error_code != heif_error_Ok) {
return error;
}
ID = to_ID;
}

// --- get coded image data pointers

auto items = m_iloc_box->get_items();
Expand Down
6 changes: 4 additions & 2 deletions libheif/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,17 @@ class HeifFile
Error parse_heif_file(BitstreamRange& bitstream);

Error check_for_ref_cycle(heif_item_id ID,
std::shared_ptr<Box_iref>& iref_box) const;
const std::shared_ptr<Box_iref>& iref_box) const;

Error check_for_ref_cycle_recursion(heif_item_id ID,
std::shared_ptr<Box_iref>& iref_box,
const std::shared_ptr<Box_iref>& iref_box,
std::unordered_set<heif_item_id>& parent_items) const;

std::shared_ptr<Box_infe> get_infe(heif_item_id ID) const;

int jpeg_get_bits_per_pixel(heif_item_id imageID) const;

Error get_source_image_id(const heif_item_id to_ID, heif_item_id *from_ID) const;
};

#endif
3 changes: 3 additions & 0 deletions libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ enum heif_suberror_code
// Invalid specification of region item
heif_suberror_Invalid_region_data = 136,

// An item was referenced, but the iref entry didn't include it
heif_suberror_missing_iref_reference = 137,

// Invalid JPEG 2000 codestream - usually a missing marker
heif_suberror_Invalid_J2K_codestream = 140,

Expand Down
1 change: 1 addition & 0 deletions libheif/heif_emscripten.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ EMSCRIPTEN_BINDINGS(libheif) {
.value("heif_suberror_Item_reference_cycle", heif_suberror_Item_reference_cycle)
.value("heif_suberror_Invalid_pixi_box", heif_suberror_Invalid_pixi_box)
.value("heif_suberror_Invalid_region_data", heif_suberror_Invalid_region_data)
.value("heif_suberror_missing_iref_reference", heif_suberror_missing_iref_reference)
.value("heif_suberror_Invalid_J2K_codestream", heif_suberror_Invalid_J2K_codestream)
.value("heif_suberror_Unsupported_codec", heif_suberror_Unsupported_codec)
.value("heif_suberror_Unsupported_image_type", heif_suberror_Unsupported_image_type)
Expand Down

0 comments on commit 3b1cc73

Please sign in to comment.