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

wip: item API suggestions #1027

Closed
wants to merge 7 commits 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
4 changes: 3 additions & 1 deletion examples/heif_convert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <cstring>
#include <getopt.h>
#include "libheif/heif_items.h"

#if defined(HAVE_UNISTD_H)

Expand Down Expand Up @@ -413,6 +414,7 @@ int main(int argc, char** argv)
return 1;
}


int num_images = heif_context_get_number_of_top_level_images(ctx);
if (num_images == 0) {
fprintf(stderr, "File doesn't contain any images\n");
Expand Down Expand Up @@ -702,7 +704,7 @@ int main(int argc, char** argv)

offset = (exif[0]<<24) | (exif[1]<<16) | (exif[2]<<8) | exif[3];
offset += 4;

if (offset >= exifSize) {
heif_image_handle_release(handle);
std::cerr << "Invalid EXIF metadata, offset out of range.\n";
Expand Down
1 change: 1 addition & 0 deletions examples/heif_enc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#include <libheif/heif.h>
#include <libheif/heif_properties.h>
#include "libheif/heif_items.h"

#if HAVE_LIBJPEG
#include "decoder_jpeg.h"
Expand Down
3 changes: 3 additions & 0 deletions libheif/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(libheif_headers
heif_plugin.h
heif_properties.h
heif_regions.h
heif_items.h
${CMAKE_CURRENT_BINARY_DIR}/heif_version.h)

set(libheif_sources
Expand Down Expand Up @@ -49,6 +50,8 @@ set(libheif_sources
heif_regions.cc
heif_properties.h
heif_properties.cc
heif_items.h
heif_items.cc
color-conversion/colorconversion.cc
color-conversion/colorconversion.h
color-conversion/rgb2yuv.cc
Expand Down
2 changes: 2 additions & 0 deletions libheif/box.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@ class Box_infe : public FullBox

void set_item_name(const std::string& name) { m_item_name = name; }

const std::string& get_item_name() const { return m_item_name; }

const std::string& get_content_type() const { return m_content_type; }

const std::string& get_content_encoding() const { return m_content_encoding; }
Expand Down
10 changes: 7 additions & 3 deletions libheif/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3324,19 +3324,20 @@ Error HeifContext::add_exif_metadata(const std::shared_ptr<Image>& master_image,

return add_generic_metadata(master_image,
data_array.data(), (int) data_array.size(),
"Exif", nullptr, nullptr, heif_metadata_compression_off);
"Exif", nullptr, nullptr, heif_metadata_compression_off, nullptr);
}


Error HeifContext::add_XMP_metadata(const std::shared_ptr<Image>& master_image, const void* data, int size,
heif_metadata_compression compression)
{
return add_generic_metadata(master_image, data, size, "mime", "application/rdf+xml", nullptr, compression);
return add_generic_metadata(master_image, data, size, "mime", "application/rdf+xml", nullptr, compression, nullptr);
}


Error HeifContext::add_generic_metadata(const std::shared_ptr<Image>& master_image, const void* data, int size,
const char* item_type, const char* content_type, const char* item_uri_type, heif_metadata_compression compression)
const char* item_type, const char* content_type, const char* item_uri_type, heif_metadata_compression compression,
heif_item_id* out_item_id)
{
// create an infe box describing what kind of data we are storing (this also creates a new ID)

Expand All @@ -3350,6 +3351,9 @@ Error HeifContext::add_generic_metadata(const std::shared_ptr<Image>& master_ima
}

heif_item_id metadata_id = metadata_infe_box->get_item_ID();
if (out_item_id) {
*out_item_id = metadata_id;
}


// we assign this data to the image
Expand Down
2 changes: 1 addition & 1 deletion libheif/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ class HeifContext : public ErrorBuffer

Error add_generic_metadata(const std::shared_ptr<Image>& master_image, const void* data, int size,
const char* item_type, const char* content_type, const char* item_uri_type,
heif_metadata_compression compression);
heif_metadata_compression compression, heif_item_id* out_item_id);

heif_property_id add_property(heif_item_id targetItem, std::shared_ptr<Box> property, bool essential);

Expand Down
10 changes: 10 additions & 0 deletions libheif/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,14 @@ inline std::ostream& operator<<(std::ostream& ostr, const Error& err)
return ostr;
}


template <typename T> class Result
{
public:
operator bool() const { return error.error_code == heif_error_Ok; }

T value;
Error error;
};

#endif
96 changes: 96 additions & 0 deletions libheif/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,102 @@ std::shared_ptr<Box_j2kH> HeifFile::add_j2kH_property(heif_item_id id)
}


Result<heif_item_id> HeifFile::add_infe(const char* item_type, const uint8_t* data, size_t size)
{
Result<heif_item_id> result;

// create an infe box describing what kind of data we are storing (this also creates a new ID)

auto infe_box = add_new_infe_box(item_type);
infe_box->set_hidden_item(true);

heif_item_id metadata_id = infe_box->get_item_ID();
result.value = metadata_id;

set_item_data(infe_box, data, size, heif_metadata_compression_off);

return result;
}


Result<heif_item_id> HeifFile::add_infe_mime(const char* content_type, heif_metadata_compression content_encoding, const uint8_t* data, size_t size)
{
Result<heif_item_id> result;

// create an infe box describing what kind of data we are storing (this also creates a new ID)

auto infe_box = add_new_infe_box("mime");
infe_box->set_hidden_item(true);
infe_box->set_content_type(content_type);

heif_item_id metadata_id = infe_box->get_item_ID();
result.value = metadata_id;

set_item_data(infe_box, data, size, content_encoding);

return result;
}


Result<heif_item_id> HeifFile::add_infe_uri(const char* item_uri_type, const uint8_t* data, size_t size)
{
Result<heif_item_id> result;

// create an infe box describing what kind of data we are storing (this also creates a new ID)

auto infe_box = add_new_infe_box("uri ");
infe_box->set_hidden_item(true);
infe_box->set_item_uri_type(item_uri_type);

heif_item_id metadata_id = infe_box->get_item_ID();
result.value = metadata_id;

set_item_data(infe_box, data, size, heif_metadata_compression_off);

return result;
}


Error HeifFile::set_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, heif_metadata_compression compression)
{
// --- metadata compression

if (compression == heif_metadata_compression_auto) {
compression = heif_metadata_compression_off; // currently, we don't use header compression by default
}

// only set metadata compression for MIME type data which has 'content_encoding' field
if (compression != heif_metadata_compression_off &&
item->get_item_type() != "mime") {
// TODO: error, compression not supported
}


std::vector<uint8_t> data_array;
if (compression == heif_metadata_compression_deflate) {
#if WITH_DEFLATE_HEADER_COMPRESSION
data_array = deflate((const uint8_t*) data, size);
item->set_content_encoding("deflate");
#else
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_header_compression_method);
#endif
}
else {
// uncompressed data, plain copy

data_array.resize(size);
memcpy(data_array.data(), data, size);
}

// copy the data into the file, store the pointer to it in an iloc box entry

append_iloc_data(item->get_item_ID(), data_array);

return Error::Ok;
}


void HeifFile::append_iloc_data(heif_item_id id, const std::vector<uint8_t>& nal_packets, uint8_t construction_method)
{
m_iloc_box->append_data(id, nal_packets, construction_method);
Expand Down
11 changes: 11 additions & 0 deletions libheif/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class HeifFile

heif_item_id get_primary_image_ID() const { return m_pitm_box->get_item_ID(); }

size_t get_number_of_items() const { return m_infe_boxes.size(); }

std::vector<heif_item_id> get_item_IDs() const;

bool image_exists(heif_item_id ID) const;
Expand All @@ -81,6 +83,7 @@ class HeifFile

Error get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>* out_data) const;

std::shared_ptr<Box_ftyp> get_ftyp_box() { return m_ftyp_box; }

std::shared_ptr<Box_infe> get_infe_box(heif_item_id imageID)
{
Expand Down Expand Up @@ -169,6 +172,14 @@ class HeifFile

heif_property_id add_property(heif_item_id id, std::shared_ptr<Box> property, bool essential);

Result<heif_item_id> add_infe(const char* item_type, const uint8_t* data, size_t size);

Result<heif_item_id> add_infe_mime(const char* content_type, heif_metadata_compression content_encoding, const uint8_t* data, size_t size);

Result<heif_item_id> add_infe_uri(const char* item_uri_type, const uint8_t* data, size_t size);

Error set_item_data(const std::shared_ptr<Box_infe>& item, const uint8_t* data, size_t size, heif_metadata_compression compression);

void append_iloc_data(heif_item_id id, const std::vector<uint8_t>& nal_packets, uint8_t construction_method = 0);

void append_iloc_data_with_4byte_size(heif_item_id id, const uint8_t* data, size_t size);
Expand Down
18 changes: 15 additions & 3 deletions libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,17 @@ struct heif_error heif_context_write(struct heif_context* ctx,
}
}

void heif_context_set_major_brand(struct heif_context* ctx, heif_brand2 major_brand)
{
ctx->context->get_heif_file()->get_ftyp_box()->set_major_brand(major_brand);
}

void heif_context_add_compatible_brand(struct heif_context* ctx,
heif_brand2 compatible_brand)
{
ctx->context->get_heif_file()->get_ftyp_box()->add_compatible_brand(compatible_brand);
}


int heif_context_get_encoder_descriptors(struct heif_context* ctx,
enum heif_compression_format format,
Expand Down Expand Up @@ -2829,7 +2840,7 @@ struct heif_error heif_context_add_generic_metadata(struct heif_context* ctx,
const char* item_type, const char* content_type)
{
Error error = ctx->context->add_generic_metadata(image_handle->image, data, size,
item_type, content_type, nullptr, heif_metadata_compression_off);
item_type, content_type, nullptr, heif_metadata_compression_off, nullptr);
if (error != Error::Ok) {
return error.error_struct(ctx->context.get());
}
Expand All @@ -2842,10 +2853,11 @@ struct heif_error heif_context_add_generic_metadata(struct heif_context* ctx,
struct heif_error heif_context_add_generic_uri_metadata(struct heif_context* ctx,
const struct heif_image_handle* image_handle,
const void* data, int size,
const char* item_uri_type)
const char* item_uri_type,
heif_item_id* out_item_id)
{
Error error = ctx->context->add_generic_metadata(image_handle->image, data, size,
"uri ", nullptr, item_uri_type, heif_metadata_compression_off);
"uri ", nullptr, item_uri_type, heif_metadata_compression_off, out_item_id);
if (error != Error::Ok) {
return error.error_struct(ctx->context.get());
}
Expand Down
10 changes: 9 additions & 1 deletion libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -1700,6 +1700,13 @@ struct heif_error heif_context_write(struct heif_context*,
struct heif_writer* writer,
void* userdata);

LIBHEIF_API
void heif_context_set_major_brand(struct heif_context* ctx, heif_brand2 major_brand);

// Add a compatible brand that is now added automatically by libheif when encoding images (e.g. some application brands like 'geo1').
LIBHEIF_API
void heif_context_add_compatible_brand(struct heif_context* ctx,
heif_brand2 compatible_brand);

// ----- encoder -----

Expand Down Expand Up @@ -2094,7 +2101,8 @@ LIBHEIF_API
struct heif_error heif_context_add_generic_uri_metadata(struct heif_context* ctx,
const struct heif_image_handle* image_handle,
const void* data, int size,
const char* item_uri_type);
const char* item_uri_type,
heif_item_id* out_item_id);

// --- heif_image allocation

Expand Down
Loading