Skip to content

Commit

Permalink
heif_image_handle_get_grid_image_tile_id() can now handle image trans…
Browse files Browse the repository at this point in the history
…formations
  • Loading branch information
farindk committed Oct 6, 2024
1 parent eabdeff commit e2df33c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 53 deletions.
8 changes: 7 additions & 1 deletion libheif/api/libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,9 @@ heif_error heif_image_handle_get_image_tiling(const struct heif_image_handle* ha


struct heif_error heif_image_handle_get_grid_image_tile_id(const struct heif_image_handle* handle,
uint32_t tile_x, uint32_t tile_y, heif_item_id* tile_item_id)
int process_image_transformations,
uint32_t tile_x, uint32_t tile_y,
heif_item_id* tile_item_id)
{
if (!handle || !tile_item_id) {
return { heif_error_Usage_error,
Expand All @@ -903,6 +905,10 @@ struct heif_error heif_image_handle_get_grid_image_tile_id(const struct heif_ima
"Grid tile index out of range" };
}

if (process_image_transformations) {
gridItem->transform_requested_tile_position_to_original_tile_position(tile_x, tile_y);
}

*tile_item_id = gridItem->get_grid_tiles()[tile_y * gridspec.get_columns() + tile_x];

return heif_error_ok;
Expand Down
9 changes: 6 additions & 3 deletions libheif/api/libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -1204,11 +1204,14 @@ LIBHEIF_API
struct heif_error heif_image_handle_get_image_tiling(const struct heif_image_handle* handle, int process_image_transformations, struct heif_image_tiling* out_tiling);


// For grid images, return the image item ID of a specific grid tile. Note that the tile position is given in
// the original, non-transformed image.
// For grid images, return the image item ID of a specific grid tile.
// If 'process_image_transformations' is true, the tile positions are given in the transformed image coordinate system and
// are internally mapped to the original image tile positions.
LIBHEIF_API
struct heif_error heif_image_handle_get_grid_image_tile_id(const struct heif_image_handle* handle,
uint32_t tile_x, uint32_t tile_y, heif_item_id* tile_item_id);
int process_image_transformations,
uint32_t tile_x, uint32_t tile_y,
heif_item_id* tile_item_id);


struct heif_decoding_options;
Expand Down
108 changes: 59 additions & 49 deletions libheif/image-items/image_item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,63 @@ Error ImageItem::check_for_valid_image_size(uint32_t width, uint32_t height) con
}


Error ImageItem::transform_requested_tile_position_to_original_tile_position(uint32_t& tile_x, uint32_t& tile_y) const
{
Result<std::vector<std::shared_ptr<Box>>> propertiesResult = get_properties();
if (propertiesResult.error) {
return propertiesResult.error;
}

heif_image_tiling tiling = get_heif_image_tiling();

//for (auto& prop : std::ranges::reverse_view(propertiesResult.value)) {
for (auto propIter = propertiesResult.value.rbegin(); propIter != propertiesResult.value.rend(); propIter++) {
if (auto irot = std::dynamic_pointer_cast<Box_irot>(*propIter)) {
switch (irot->get_rotation_ccw()) {
case 90: {
uint32_t tx0 = tiling.num_columns - 1 - tile_y;
uint32_t ty0 = tile_x;
tile_y = ty0;
tile_x = tx0;
break;
}
case 270: {
uint32_t tx0 = tile_y;
uint32_t ty0 = tiling.num_rows - 1 - tile_x;
tile_y = ty0;
tile_x = tx0;
break;
}
case 180: {
tile_x = tiling.num_columns - 1 - tile_x;
tile_y = tiling.num_rows - 1 - tile_y;
break;
}
default:
assert(false);
break;
}
}

if (auto imir = std::dynamic_pointer_cast<Box_imir>(*propIter)) {
switch (imir->get_mirror_direction()) {
case heif_transform_mirror_direction_horizontal:
tile_x = tiling.num_columns - 1 - tile_x;
break;
case heif_transform_mirror_direction_vertical:
tile_y = tiling.num_rows - 1 - tile_y;
break;
default:
assert(false);
break;
}
}
}

return Error::Ok;
}


Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_image(const struct heif_decoding_options& options,
bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
{
Expand All @@ -688,55 +745,8 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_image(const struct hei
// --- transform tile position

if (decode_tile_only && options.ignore_transformations == false) {
Result<std::vector<std::shared_ptr<Box>>> propertiesResult = get_properties();
if (propertiesResult.error) {
return propertiesResult.error;
}

heif_image_tiling tiling = get_heif_image_tiling();

//for (auto& prop : std::ranges::reverse_view(propertiesResult.value)) {
for (auto propIter = propertiesResult.value.rbegin(); propIter != propertiesResult.value.rend(); propIter++) {
if (auto irot = std::dynamic_pointer_cast<Box_irot>(*propIter)) {
switch (irot->get_rotation_ccw()) {
case 90: {
uint32_t tx0 = tiling.num_columns - 1 - tile_y0;
uint32_t ty0 = tile_x0; //tiling.num_rows - 1 - tile_x0;
tile_y0 = ty0;
tile_x0 = tx0;
break;
}
case 270: {
uint32_t tx0 = tile_y0;
uint32_t ty0 = tiling.num_rows - 1 - tile_x0;
tile_y0 = ty0;
tile_x0 = tx0;
break;
}
case 180: {
tile_x0 = tiling.num_columns - 1 - tile_x0;
tile_y0 = tiling.num_rows - 1 - tile_y0;
break;
}
default:
assert(false);
break;
}
}

if (auto imir = std::dynamic_pointer_cast<Box_imir>(*propIter)) {
switch (imir->get_mirror_direction()) {
case heif_transform_mirror_direction_horizontal:
tile_x0 = tiling.num_columns - 1 - tile_x0;
break;
case heif_transform_mirror_direction_vertical:
tile_y0 = tiling.num_rows - 1 - tile_y0;
break;
default:
assert(false);
break;
}
}
if (Error error = transform_requested_tile_position_to_original_tile_position(tile_x0, tile_y0)) {
return error;
}
}

Expand Down
2 changes: 2 additions & 0 deletions libheif/image-items/image_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ class ImageItem : public ErrorBuffer

Error process_image_transformations_on_tiling(heif_image_tiling&) const;

Error transform_requested_tile_position_to_original_tile_position(uint32_t& tile_x, uint32_t& tile_y) const;

virtual std::shared_ptr<class Decoder> get_decoder() const { return nullptr; }

private:
Expand Down

0 comments on commit e2df33c

Please sign in to comment.