Skip to content

Commit

Permalink
move adding tiles to tili images to ImageItem_Tiled
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Oct 14, 2024
1 parent ed36bc0 commit a8d7348
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 90 deletions.
4 changes: 2 additions & 2 deletions libheif/api/libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3574,8 +3574,8 @@ struct heif_error heif_context_add_image_tile(struct heif_context* ctx,
const struct heif_image* image,
struct heif_encoder* encoder)
{
if (tiled_image->image->get_infe_type() == fourcc("tili")) {
Error err = ctx->context->add_tiled_image_tile(tiled_image->image->get_id(), tile_x, tile_y, image->image, encoder);
if (auto tili_image = std::dynamic_pointer_cast<ImageItem_Tiled>(tiled_image->image)) {
Error err = tili_image->add_image_tile(tile_x, tile_y, image->image, encoder);
return err.error_struct(ctx->context.get());
}
#if WITH_UNCOMPRESSED_CODEC
Expand Down
84 changes: 0 additions & 84 deletions libheif/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1243,90 +1243,6 @@ Error HeifContext::encode_image(const std::shared_ptr<HeifPixelImage>& pixel_ima
return error;
}

Error HeifContext::add_tiled_image_tile(heif_item_id tild_id, uint32_t tile_x, uint32_t tile_y,
const std::shared_ptr<HeifPixelImage>& image,
struct heif_encoder* encoder)
{
auto item = ImageItem::alloc_for_compression_format(this, encoder->plugin->compression_format);

heif_encoding_options* options = heif_encoding_options_alloc(); // TODO: should this be taken from heif_context_add_tiled_image() ?

Result<std::shared_ptr<HeifPixelImage>> colorConversionResult = item->convert_colorspace_for_encoding(image, encoder, *options);
if (colorConversionResult.error) {
return colorConversionResult.error;
}

std::shared_ptr<HeifPixelImage> colorConvertedImage = colorConversionResult.value;

Result<ImageItem::CodedImageData> encodeResult = item->encode_to_bitstream_and_boxes(colorConvertedImage, encoder, *options, heif_image_input_class_normal); // TODO (other than JPEG)
heif_encoding_options_free(options);

if (encodeResult.error) {
return encodeResult.error;
}

const int construction_method = 0; // 0=mdat 1=idat
m_heif_file->append_iloc_data(tild_id, encodeResult.value.bitstream, construction_method);

auto imgItem = get_image(tild_id, true);
auto tildImg = std::dynamic_pointer_cast<ImageItem_Tiled>(imgItem);
if (!tildImg) {
return {heif_error_Usage_error, heif_suberror_Invalid_parameter_value, "item ID for add_tiled_image_tile() is no 'tili' image."};
}
assert(!tildImg->get_item_error());

auto& header = tildImg->get_tild_header();

if (image->get_width() != header.get_parameters().tile_width ||
image->get_height() != header.get_parameters().tile_height) {

std::cout << "tx:" << tile_x << " ty:" << tile_y << "\n";
std::cout << image->get_width() << " " << header.get_parameters().tile_width << " | "
<< image->get_height() << " " << header.get_parameters().tile_height <<"\n";

return {heif_error_Usage_error,
heif_suberror_Unspecified,
"Tile image size does not match the specified tile size."};
}

uint64_t offset = tildImg->get_next_tild_position();
size_t dataSize = encodeResult.value.bitstream.size();
if (dataSize > 0xFFFFFFFF) {
return {heif_error_Encoding_error, heif_suberror_Unspecified, "Compressed tile size exceeds maximum tile size."};
}
header.set_tild_tile_range(tile_x, tile_y, offset, static_cast<uint32_t>(dataSize));
tildImg->set_next_tild_position(offset + encodeResult.value.bitstream.size());

std::vector<std::shared_ptr<Box>> existing_properties;
Error err = m_heif_file->get_properties(tild_id, existing_properties);
if (err) {
return err;
}

for (auto& propertyBox : encodeResult.value.properties) {
if (propertyBox->get_short_type() == fourcc("ispe")) {
continue;
}

// skip properties that exist already

bool exists = std::any_of(existing_properties.begin(),
existing_properties.end(),
[&propertyBox](const std::shared_ptr<Box>& p) { return p->get_short_type() == propertyBox->get_short_type();});
if (exists) {
continue;
}

m_heif_file->add_property(tild_id, propertyBox, propertyBox->is_essential());
}

m_heif_file->set_brand(encoder->plugin->compression_format,
true); // TODO: out_grid_image->is_miaf_compatible());

return Error::Ok;
}


void HeifContext::set_primary_image(const std::shared_ptr<ImageItem>& image)
{
// update heif context
Expand Down
4 changes: 0 additions & 4 deletions libheif/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,6 @@ class HeifContext : public ErrorBuffer
enum heif_image_input_class input_class,
std::shared_ptr<ImageItem>& out_image);

Error add_tiled_image_tile(heif_item_id tili_id, uint32_t tile_x, uint32_t tile_y,
const std::shared_ptr<HeifPixelImage>& image,
struct heif_encoder* encoder);

void set_primary_image(const std::shared_ptr<ImageItem>& image);

bool is_primary_image_set() const { return m_primary_image != nullptr; }
Expand Down
77 changes: 77 additions & 0 deletions libheif/image-items/tiled.cc
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,83 @@ ImageItem_Tiled::add_new_tiled_item(HeifContext* ctx, const heif_tiled_image_par
}


Error ImageItem_Tiled::add_image_tile(uint32_t tile_x, uint32_t tile_y,
const std::shared_ptr<HeifPixelImage>& image,
struct heif_encoder* encoder)
{
auto item = ImageItem::alloc_for_compression_format(get_context(), encoder->plugin->compression_format);

heif_encoding_options* options = heif_encoding_options_alloc(); // TODO: should this be taken from heif_context_add_tiled_image() ?

Result<std::shared_ptr<HeifPixelImage>> colorConversionResult = item->convert_colorspace_for_encoding(image, encoder, *options);
if (colorConversionResult.error) {
return colorConversionResult.error;
}

std::shared_ptr<HeifPixelImage> colorConvertedImage = colorConversionResult.value;

Result<ImageItem::CodedImageData> encodeResult = item->encode_to_bitstream_and_boxes(colorConvertedImage, encoder, *options, heif_image_input_class_normal); // TODO (other than JPEG)
heif_encoding_options_free(options);

if (encodeResult.error) {
return encodeResult.error;
}

const int construction_method = 0; // 0=mdat 1=idat
get_file()->append_iloc_data(get_id(), encodeResult.value.bitstream, construction_method);

auto& header = m_tild_header;

if (image->get_width() != header.get_parameters().tile_width ||
image->get_height() != header.get_parameters().tile_height) {

std::cout << "tx:" << tile_x << " ty:" << tile_y << "\n";
std::cout << image->get_width() << " " << header.get_parameters().tile_width << " | "
<< image->get_height() << " " << header.get_parameters().tile_height <<"\n";

return {heif_error_Usage_error,
heif_suberror_Unspecified,
"Tile image size does not match the specified tile size."};
}

uint64_t offset = get_next_tild_position();
size_t dataSize = encodeResult.value.bitstream.size();
if (dataSize > 0xFFFFFFFF) {
return {heif_error_Encoding_error, heif_suberror_Unspecified, "Compressed tile size exceeds maximum tile size."};
}
header.set_tild_tile_range(tile_x, tile_y, offset, static_cast<uint32_t>(dataSize));
set_next_tild_position(offset + encodeResult.value.bitstream.size());

std::vector<std::shared_ptr<Box>> existing_properties;
Error err = get_file()->get_properties(get_id(), existing_properties);
if (err) {
return err;
}

for (auto& propertyBox : encodeResult.value.properties) {
if (propertyBox->get_short_type() == fourcc("ispe")) {
continue;
}

// skip properties that exist already

bool exists = std::any_of(existing_properties.begin(),
existing_properties.end(),
[&propertyBox](const std::shared_ptr<Box>& p) { return p->get_short_type() == propertyBox->get_short_type();});
if (exists) {
continue;
}

get_file()->add_property(get_id(), propertyBox, propertyBox->is_essential());
}

get_file()->set_brand(encoder->plugin->compression_format,
true); // TODO: out_grid_image->is_miaf_compatible());

return Error::Ok;
}


void ImageItem_Tiled::process_before_write()
{
// overwrite offsets
Expand Down
5 changes: 5 additions & 0 deletions libheif/image-items/tiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ class ImageItem_Tiled : public ImageItem
static Result<std::shared_ptr<ImageItem_Tiled>> add_new_tiled_item(HeifContext* ctx, const heif_tiled_image_parameters* parameters,
const heif_encoder* encoder);

Error add_image_tile(uint32_t tile_x, uint32_t tile_y,
const std::shared_ptr<HeifPixelImage>& image,
struct heif_encoder* encoder);


Error on_load_file() override;

void process_before_write() override;
Expand Down

0 comments on commit a8d7348

Please sign in to comment.