Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle iden derived images #1092

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go/heif/heif.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,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
3 changes: 2 additions & 1 deletion libheif/error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +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";

// --- Memory_allocation_error ---

Expand Down
55 changes: 51 additions & 4 deletions libheif/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ Error HeifFile::parse_heif_file(BitstreamRange& range)
m_iref_box = std::dynamic_pointer_cast<Box_iref>(m_meta_box->get_child_box(fourcc("iref")));
if (m_iref_box) {
Error error = check_for_ref_cycle(get_primary_image_ID(), m_iref_box);
if (error) {
if (error != Error::Ok) {
return error;
}
}
Expand Down Expand Up @@ -397,15 +397,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 All @@ -417,7 +417,7 @@ Error HeifFile::check_for_ref_cycle_recursion(heif_item_id ID,
std::vector<heif_item_id> image_references = iref_box->get_references(ID, fourcc("dimg"));
for (heif_item_id reference_idx : image_references) {
Error error = check_for_ref_cycle_recursion(reference_idx, iref_box, parent_items);
if (error) {
if (error != Error::Ok) {
return error;
}
}
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 != Error::Ok) {
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 @@ -221,15 +221,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
2 changes: 2 additions & 0 deletions libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ 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,

// --- Memory_allocation_error ---

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_Unsupported_codec", heif_suberror_Unsupported_codec)
.value("heif_suberror_Unsupported_image_type", heif_suberror_Unsupported_image_type)
.value("heif_suberror_Unsupported_data_version", heif_suberror_Unsupported_data_version)
Expand Down
Loading