diff --git a/libheif/box.cc b/libheif/box.cc index 6d101e46ac..e01946a3e6 100644 --- a/libheif/box.cc +++ b/libheif/box.cc @@ -392,12 +392,14 @@ Error Box::parse(BitstreamRange& range) } else { uint64_t content_size = get_box_size() - get_header_size(); - if (range.prepare_read(content_size)) { - if (content_size > MAX_BOX_SIZE) { - return Error(heif_error_Invalid_input, - heif_suberror_Invalid_box_size); - } - + if (content_size > MAX_BOX_SIZE) { + return Error(heif_error_Invalid_input, heif_suberror_Invalid_box_size); + } + else if (get_short_type() == fourcc("uuid")) { + m_uuid_data.resize(content_size); + range.read(m_uuid_data.data(), content_size); + } + else if (range.prepare_read(content_size)) { range.get_istream()->seek_cur(get_box_size() - get_header_size()); } } @@ -714,6 +716,10 @@ Error Box::write(StreamWriter& writer) const { size_t box_start = reserve_box_header_space(writer); + if (get_short_type() == fourcc("uuid")) { + writer.write(m_uuid_data); + } + Error err = write_children(writer); prepend_header(writer, box_start); diff --git a/libheif/box.h b/libheif/box.h index 0c0b148d12..52dae7bbd5 100644 --- a/libheif/box.h +++ b/libheif/box.h @@ -125,8 +125,13 @@ class BoxHeader std::string get_type_string() const; + std::vector get_uuid_data() const { return m_uuid_data; } + void set_short_type(uint32_t type) { m_type = type; } + void set_uuid_type(const std::vector& uuid_type) { m_uuid_type = uuid_type; } + + void set_uuid_data(const std::vector& uuid_data) { m_uuid_data = uuid_data; } Error parse_header(BitstreamRange& range); @@ -140,9 +145,10 @@ class BoxHeader uint64_t m_size = 0; uint32_t m_type = 0; - std::vector m_uuid_type; protected: + std::vector m_uuid_type; + std::vector m_uuid_data; uint32_t m_header_size = 0; }; diff --git a/libheif/heif_properties.cc b/libheif/heif_properties.cc index d73cea41ca..d0c39f02c1 100644 --- a/libheif/heif_properties.cc +++ b/libheif/heif_properties.cc @@ -300,3 +300,92 @@ void heif_property_user_description_release(struct heif_property_user_descriptio delete udes; } + +struct heif_error heif_item_add_property_uuid(const struct heif_context* context, + heif_item_id itemId, + const uint8_t* uuid_type, + const uint8_t* data, size_t size, + heif_property_id* out_propertyId) +{ + if (!context || !uuid_type || !data) { + return {heif_error_Usage_error, heif_suberror_Null_pointer_argument, "NULL argument passed in"}; + } + + auto uuid_box = std::make_shared(); + uuid_box->set_short_type(fourcc("uuid")); + + std::vector uuid_type_vector(uuid_type, uuid_type + 16); + uuid_box->set_uuid_type(uuid_type_vector); + + std::vector data_vector(data, data + size); + uuid_box->set_uuid_data(data_vector); + + heif_property_id id = context->context->add_property(itemId, uuid_box, false); + + if (out_propertyId) { + *out_propertyId = id; + } + + return heif_error_success; +} + + +struct heif_error heif_item_get_property_uuid_size(const struct heif_context* context, + heif_item_id itemId, + heif_property_id propertyId, + size_t* size_out) +{ + auto file = context->context->get_heif_file(); if (!context || !size_out) { + return {heif_error_Usage_error, heif_suberror_Null_pointer_argument, "NULL argument passed in"}; + } + + std::vector> properties; + Error err = file->get_properties(itemId, properties); + if (err) { + return err.error_struct(context->context.get()); + } + + if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { + return {heif_error_Usage_error, heif_suberror_Invalid_property, "property index out of range"}; + } + + auto uuid_box = properties[propertyId - 1]; + auto data = uuid_box->get_uuid_data(); + + *size_out = data.size(); + + return heif_error_success; +} + + +struct heif_error heif_item_get_property_uuid(const struct heif_context* context, + heif_item_id itemId, + heif_property_id propertyId, + uint8_t* data_out) +{ + if (!context || !data_out) { + return {heif_error_Usage_error, heif_suberror_Null_pointer_argument, "NULL argument passed in"}; + } + + auto file = context->context->get_heif_file(); + + std::vector> properties; + Error err = file->get_properties(itemId, properties); + if (err) { + return err.error_struct(context->context.get()); + } + + if (propertyId - 1 < 0 || propertyId - 1 >= properties.size()) { + return {heif_error_Usage_error, heif_suberror_Invalid_property, "property index out of range"}; + } + + auto uuid_box = properties[propertyId - 1]; + auto data = uuid_box->get_uuid_data(); + + + + std::copy(data.begin(), data.end(), data_out); + + return heif_error_success; +} + diff --git a/libheif/heif_properties.h b/libheif/heif_properties.h index 4ed15c8a90..1c88d930d8 100644 --- a/libheif/heif_properties.h +++ b/libheif/heif_properties.h @@ -37,7 +37,8 @@ enum heif_item_property_type heif_item_property_type_transform_mirror = heif_fourcc('i', 'm', 'i', 'r'), heif_item_property_type_transform_rotation = heif_fourcc('i', 'r', 'o', 't'), heif_item_property_type_transform_crop = heif_fourcc('c', 'l', 'a', 'p'), - heif_item_property_type_image_size = heif_fourcc('i', 's', 'p', 'e') + heif_item_property_type_image_size = heif_fourcc('i', 's', 'p', 'e'), + heif_item_property_type_uuid = heif_fourcc('u', 'u', 'i', 'd') }; // Get the heif_property_id for a heif_item_id. @@ -131,6 +132,29 @@ void heif_item_get_property_transform_crop_borders(const struct heif_context* co int image_width, int image_height, int* left, int* top, int* right, int* bottom); +LIBHEIF_API +struct heif_error heif_item_add_property_uuid(const struct heif_context* context, + heif_item_id itemId, + const uint8_t* uuid_type, + const uint8_t* data, size_t size, + heif_property_id* out_propertyId); + +LIBHEIF_API +struct heif_error heif_item_get_property_uuid_size(const struct heif_context* context, + heif_item_id itemId, + heif_property_id propertyId, + size_t* size_out); + +/** + * @param data_out User-supplied array. The size given by heif_item_get_property_uuid_size(). +*/ +LIBHEIF_API +struct heif_error heif_item_get_property_uuid(const struct heif_context* context, + heif_item_id itemId, + heif_property_id propertyId, + uint8_t* data_out); + + #ifdef __cplusplus } #endif