diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b7a9c2..2bb7774d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ All notable changes to this project will be documented in this file. ### Changed -- `subsampling` parameter for encoding has higher priority then `chroma`. +- `subsampling` parameter for encoding has higher priority then `chroma`. #213 +- the minimum required `libehif` version is `1.17.0`. #214 ## [0.15.0 - 2024-02-03] diff --git a/docker/from_src/Almalinux_9.Dockerfile b/docker/from_src/Almalinux_9.Dockerfile index f509b0c1..b1f6637d 100644 --- a/docker/from_src/Almalinux_9.Dockerfile +++ b/docker/from_src/Almalinux_9.Dockerfile @@ -3,8 +3,8 @@ FROM almalinux:9 as base RUN \ dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm -y && \ dnf makecache && \ - dnf install -y python3 python3-devel python3-pip libheif-freeworld && \ - dnf install -y libheif-devel && \ + dnf install -y python3 python3-devel python3-pip cmake && \ + dnf install -y x265-devel libaom-devel && \ dnf groupinstall -y 'Development Tools' RUN \ @@ -15,6 +15,7 @@ FROM base as build_test COPY . /pillow_heif RUN \ + python3 pillow_heif/libheif/linux_build_libs.py && \ if [ `getconf LONG_BIT` = 64 ]; then \ python3 -m pip install -v "pillow_heif/.[tests]"; \ else \ diff --git a/docs/installation.rst b/docs/installation.rst index eb3ab9aa..178838f2 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -35,7 +35,7 @@ Linux | **And of course you can build your own libheif library with your preferred encoders and decoders and use what you like.** There is many different ways how to build it from source. Main requirements are: - * ``libheif`` should be version >= ``1.16.1`` version(recommended version is ``1.17.3`` or higher). + * ``libheif`` should be version >= ``1.17.0`` version(recommended version is ``1.17.3`` or higher). * ``x265`` should support 10 - 12 bit encoding(if you want to save in that bitness) * ``aom`` should be >= ``3.3.0`` version * ``libde265`` should be >= ``1.0.8`` version diff --git a/libheif/heif.h b/libheif/heif.h index 48b40f9b..2cdf17d8 100644 --- a/libheif/heif.h +++ b/libheif/heif.h @@ -3,7 +3,7 @@ /* * HEIF codec. - * Copyright (c) 2017 struktur AG, Dirk Farin + * Copyright (c) 2017-2023 Dirk Farin * * This file is part of libheif. * @@ -37,7 +37,7 @@ extern "C" { #include //#include -#define LIBHEIF_NUMERIC_VERSION ((1<<24) | (15<<16) | (2<<8) | 0) +#define LIBHEIF_NUMERIC_VERSION ((1<<24) | (17<<16) | (6<<8) | 0) // API versions table // @@ -80,19 +80,18 @@ extern "C" { // Version string of linked libheif library. LIBHEIF_API const char* heif_get_version(void); -// Numeric version of linked libheif library, encoded as BCD 0xHHMMLL00 = HH.MM.LL. -// For example: 0x02143000 is version 2.14.30 +// Numeric version of linked libheif library, encoded as 0xHHMMLL00 = hh.mm.ll, where hh, mm, ll is the decimal representation of HH, MM, LL. +// For example: 0x02150300 is version 2.21.3 LIBHEIF_API uint32_t heif_get_version_number(void); -// Numeric part "HH" from above. Returned as a decimal number (not BCD). +// Numeric part "HH" from above. Returned as a decimal number. LIBHEIF_API int heif_get_version_number_major(void); -// Numeric part "MM" from above. Returned as a decimal number (not BCD). +// Numeric part "MM" from above. Returned as a decimal number. LIBHEIF_API int heif_get_version_number_minor(void); -// Numeric part "LL" from above. Returned as a decimal number (not BCD). +// Numeric part "LL" from above. Returned as a decimal number. LIBHEIF_API int heif_get_version_number_maintenance(void); // Helper macros to check for given versions of libheif at compile time. -// Note: h, m, l should be 2-digit BCD numbers. I.e., decimal 17 = 0x17 (BCD) #define LIBHEIF_MAKE_VERSION(h, m, l) ((h) << 24 | (m) << 16 | (l) << 8) #define LIBHEIF_HAVE_VERSION(h, m, l) (LIBHEIF_NUMERIC_VERSION >= LIBHEIF_MAKE_VERSION(h, m, l)) @@ -326,20 +325,153 @@ struct heif_error const char* message; }; +// Default success return value. Intended for use in user-supplied callback functions. +LIBHEIF_API extern const struct heif_error heif_error_success; + typedef uint32_t heif_item_id; typedef uint32_t heif_property_id; -// ========================= library initialization ====================== +// ========================= enum types ====================== + +/** + * libheif known compression formats. + */ +enum heif_compression_format +{ + /** + * Unspecified / undefined compression format. + * + * This is used to mean "no match" or "any decoder" for some parts of the + * API. It does not indicate a specific compression format. + */ + heif_compression_undefined = 0, + /** + * HEVC compression, used for HEIC images. + * + * This is equivalent to H.265. + */ + heif_compression_HEVC = 1, + /** + * AVC compression. (Currently unused in libheif.) + * + * The compression is defined in ISO/IEC 14496-10. This is equivalent to H.264. + * + * The encapsulation is defined in ISO/IEC 23008-12:2022 Annex E. + */ + heif_compression_AVC = 2, + /** + * JPEG compression. + * + * The compression format is defined in ISO/IEC 10918-1. The encapsulation + * of JPEG is specified in ISO/IEC 23008-12:2022 Annex H. + */ + heif_compression_JPEG = 3, + /** + * AV1 compression, used for AVIF images. + * + * The compression format is provided at https://aomediacodec.github.io/av1-spec/ + * + * The encapsulation is defined in https://aomediacodec.github.io/av1-avif/ + */ + heif_compression_AV1 = 4, + /** + * VVC compression. (Currently unused in libheif.) + * + * The compression format is defined in ISO/IEC 23090-3. This is equivalent to H.266. + * + * The encapsulation is defined in ISO/IEC 23008-12:2022 Annex L. + */ + heif_compression_VVC = 5, + /** + * EVC compression. (Currently unused in libheif.) + * + * The compression format is defined in ISO/IEC 23094-1. This is equivalent to H.266. + * + * The encapsulation is defined in ISO/IEC 23008-12:2022 Annex M. + */ + heif_compression_EVC = 6, + /** + * JPEG 2000 compression. + * + * The encapsulation of JPEG 2000 is specified in ISO/IEC 15444-16:2021. + * The core encoding is defined in ISO/IEC 15444-1, or ITU-T T.800. + */ + heif_compression_JPEG2000 = 7, + /** + * Uncompressed encoding. + * + * This is defined in ISO/IEC 23001-17:2023 (Final Draft International Standard). + */ + heif_compression_uncompressed = 8, + /** + * Mask image encoding. + * + * See ISO/IEC 23008-12:2022 Section 6.10.2 + */ + heif_compression_mask = 9 +}; + +enum heif_chroma +{ + heif_chroma_undefined = 99, + heif_chroma_monochrome = 0, + heif_chroma_420 = 1, + heif_chroma_422 = 2, + heif_chroma_444 = 3, + heif_chroma_interleaved_RGB = 10, + heif_chroma_interleaved_RGBA = 11, + heif_chroma_interleaved_RRGGBB_BE = 12, // HDR, big endian. + heif_chroma_interleaved_RRGGBBAA_BE = 13, // HDR, big endian. + heif_chroma_interleaved_RRGGBB_LE = 14, // HDR, little endian. + heif_chroma_interleaved_RRGGBBAA_LE = 15 // HDR, little endian. +}; + +// DEPRECATED ENUM NAMES +#define heif_chroma_interleaved_24bit heif_chroma_interleaved_RGB +#define heif_chroma_interleaved_32bit heif_chroma_interleaved_RGBA + + +enum heif_colorspace +{ + heif_colorspace_undefined = 99, + + // heif_colorspace_YCbCr should be used with one of these heif_chroma values: + // * heif_chroma_444 + // * heif_chroma_422 + // * heif_chroma_420 + heif_colorspace_YCbCr = 0, + + // heif_colorspace_RGB should be used with one of these heif_chroma values: + // * heif_chroma_444 (for planar RGB) + // * heif_chroma_interleaved_RGB + // * heif_chroma_interleaved_RGBA + // * heif_chroma_interleaved_RRGGBB_BE + // * heif_chroma_interleaved_RRGGBBAA_BE + // * heif_chroma_interleaved_RRGGBB_LE + // * heif_chroma_interleaved_RRGGBBAA_LE + heif_colorspace_RGB = 1, + + // heif_colorspace_monochrome should only be used with heif_chroma = heif_chroma_monochrome + heif_colorspace_monochrome = 2 +}; + +enum heif_channel +{ + heif_channel_Y = 0, + heif_channel_Cb = 1, + heif_channel_Cr = 2, + heif_channel_R = 3, + heif_channel_G = 4, + heif_channel_B = 5, + heif_channel_Alpha = 6, + heif_channel_interleaved = 10 +}; -// You should call heif_init() when you start using libheif and heif_deinit() when you are finished. -// These calls are reference counted. Each call to heif_init() should be matched by one call to heif_deinit(). -// For backwards compatibility, it is not really necessary to call heif_init(), but if you don't, the plugins -// registered by default may not be freed correctly. -// However, this should not be mixed, i.e. one part of your program does use heif_init()/heif_deinit() and another doesn't. -// If in doubt, enclose everything with init/deinit. + +// ========================= library initialization ====================== struct heif_init_params { @@ -349,12 +481,38 @@ struct heif_init_params }; -// You may pass nullptr to get default parameters. Currently, no parameters are supported. +/** + * Initialise library. + * + * You should call heif_init() when you start using libheif and heif_deinit() when you are finished. + * These calls are reference counted. Each call to heif_init() should be matched by one call to heif_deinit(). + * + * For backwards compatibility, it is not really necessary to call heif_init(), but some library memory objects + * will never be freed if you do not call heif_init()/heif_deinit(). + * + * heif_init() will load the external modules installed in the default plugin path. Thus, you need it when you + * want to load external plugins from the default path. + * Codec plugins that are compiled into the library directly (selected by the compile-time parameters of libheif) + * will be available even without heif_init(). + * + * Make sure that you do not have one part of your program use heif_init()/heif_deinit() and another part that does + * not use it as the latter may try to use an uninitialized library. If in doubt, enclose everything with init/deinit. + * + * You may pass nullptr to get default parameters. Currently, no parameters are supported. + */ LIBHEIF_API struct heif_error heif_init(struct heif_init_params*); +/** + * Deinitialise and clean up library. + * + * You should call heif_init() when you start using libheif and heif_deinit() when you are finished. + * These calls are reference counted. Each call to heif_init() should be matched by one call to heif_deinit(). + * + * \sa heif_init() + */ LIBHEIF_API -void heif_deinit(); +void heif_deinit(void); // --- Plugins are currently only supported on Unix platforms. @@ -389,7 +547,7 @@ struct heif_error heif_unload_plugin(const struct heif_plugin_info* plugin); // This includes the paths specified in the environment variable LIBHEIF_PLUGIN_PATHS and the built-in path // (if not overridden by the environment variable). LIBHEIF_API -const char*const* heif_get_plugin_directories(); +const char*const* heif_get_plugin_directories(void); LIBHEIF_API void heif_free_plugin_directories(const char*const*); @@ -432,6 +590,8 @@ enum heif_brand heif_vvis, // VVC sequence heif_evbi, // EVC image heif_evbs, // EVC sequence + heif_j2ki, // JPEG2000 image + heif_j2is, // JPEG2000 image sequence }; // input data should be at least 12 bytes @@ -442,27 +602,192 @@ enum heif_brand heif_main_brand(const uint8_t* data, int len); typedef uint32_t heif_brand2; -#define heif_brand2_heic heif_fourcc('h','e','i','c') // HEIF image with h265 -#define heif_brand2_heix heif_fourcc('h','e','i','x') // 10bit images, or anything that uses h265 with range extension -#define heif_brand2_hevc heif_fourcc('h','e','v','c') // image sequences -#define heif_brand2_hevx heif_fourcc('h','e','v','x') // HDR image sequence -#define heif_brand2_heim heif_fourcc('h','e','i','m') // multiview -#define heif_brand2_heis heif_fourcc('h','e','i','s') // scalable -#define heif_brand2_hevm heif_fourcc('h','e','v','m') // multiview sequence -#define heif_brand2_hevs heif_fourcc('h','e','v','s') // scalable sequence -#define heif_brand2_avif heif_fourcc('a','v','i','f') // AVIF image (AV1) +/** + * HEVC image (`heic`) brand. + * + * Image conforms to HEVC (H.265) Main or Main Still profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.1. + */ +#define heif_brand2_heic heif_fourcc('h','e','i','c') + +/** + * HEVC image (`heix`) brand. + * + * Image conforms to HEVC (H.265) Main 10 profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.1. + */ +#define heif_brand2_heix heif_fourcc('h','e','i','x') + +/** + * HEVC image sequence (`hevc`) brand. + * + * Image sequence conforms to HEVC (H.265) Main profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.2. + */ +#define heif_brand2_hevc heif_fourcc('h','e','v','c') + +/** + * HEVC image sequence (`hevx`) brand. + * + * Image sequence conforms to HEVC (H.265) Main 10 profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.2. + */ +#define heif_brand2_hevx heif_fourcc('h','e','v','x') + +/** + * HEVC layered image (`heim`) brand. + * + * Image layers conform to HEVC (H.265) Main or Multiview Main profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.3. + */ +#define heif_brand2_heim heif_fourcc('h','e','i','m') + +/** + * HEVC layered image (`heis`) brand. + * + * Image layers conform to HEVC (H.265) Main, Main 10, Scalable Main + * or Scalable Main 10 profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.3. + */ +#define heif_brand2_heis heif_fourcc('h','e','i','s') + +/** + * HEVC layered image sequence (`hevm`) brand. + * + * Image sequence layers conform to HEVC (H.265) Main or Multiview Main profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.4. + */ +#define heif_brand2_hevm heif_fourcc('h','e','v','m') + +/** + * HEVC layered image sequence (`hevs`) brand. + * + * Image sequence layers conform to HEVC (H.265) Main, Main 10, Scalable Main + * or Scalable Main 10 profile. + * + * See ISO/IEC 23008-12:2022 Section B.4.4. + */ +#define heif_brand2_hevs heif_fourcc('h','e','v','s') + +/** + * AV1 image (`avif`) brand. + * + * See https://aomediacodec.github.io/av1-avif/#image-and-image-collection-brand + */ +#define heif_brand2_avif heif_fourcc('a','v','i','f') + +/** + * AV1 image sequence (`avis`) brand. + * + * See https://aomediacodec.github.io/av1-avif/#image-sequence-brand + */ #define heif_brand2_avis heif_fourcc('a','v','i','s') // AVIF sequence -#define heif_brand2_mif1 heif_fourcc('m','i','f','1') // image, any coding algorithm -#define heif_brand2_mif2 heif_fourcc('m','i','f','2') // image, any coding algorithm -#define heif_brand2_msf1 heif_fourcc('m','s','f','1') // sequence, any coding algorithm -#define heif_brand2_vvic heif_fourcc('v','v','i','c') // VVC image -#define heif_brand2_vvis heif_fourcc('v','v','i','s') // VVC sequence -#define heif_brand2_evbi heif_fourcc('e','v','b','i') // EVC image -#define heif_brand2_evbs heif_fourcc('e','v','b','s') // EVC sequence -#define heif_brand2_jpeg heif_fourcc('j','p','e','g') // JPEG, per ISO/IEC 23008-12 Annex H.4 -#define heif_brand2_jpgs heif_fourcc('j','p','g','s') // JPEG sequence, per ISO/IEC 23008-12 Annex H.5 -#define heif_brand2_j2ki heif_fourcc('j','2','k','i') // JPEG2000 image, per ISO/IEC 15444-16:2021 Section 6.5 -#define heif_brand2_j2is heif_fourcc('j','2','i','s') // JPEG2000 sequence, per ISO/IEC 15444-16:2021 Section 7.6 + +/** + * HEIF image structural brand (`mif1`). + * + * This does not imply a specific coding algorithm. + * + * See ISO/IEC 23008-12:2022 Section 10.2.2. + */ +#define heif_brand2_mif1 heif_fourcc('m','i','f','1') + +/** + * HEIF image structural brand (`mif2`). + * + * This does not imply a specific coding algorithm. `mif2` extends + * the requirements of `mif1` to include the `rref` and `iscl` item + * properties. + * + * See ISO/IEC 23008-12:2022 Section 10.2.3. + */ +#define heif_brand2_mif2 heif_fourcc('m','i','f','2') + +/** + * HEIF image sequence structural brand (`msf1`). + * + * This does not imply a specific coding algorithm. + * + * See ISO/IEC 23008-12:2022 Section 10.3.1. + */ +#define heif_brand2_msf1 heif_fourcc('m','s','f','1') + +/** + * VVC image (`vvic`) brand. + * + * See ISO/IEC 23008-12:2022 Section L.4.1. + */ +#define heif_brand2_vvic heif_fourcc('v','v','i','c') + +/** + * VVC image sequence (`vvis`) brand. + * + * See ISO/IEC 23008-12:2022 Section L.4.2. + */ +#define heif_brand2_vvis heif_fourcc('v','v','i','s') + +/** + * EVC baseline image (`evbi`) brand. + * + * See ISO/IEC 23008-12:2022 Section M.4.1. + */ +#define heif_brand2_evbi heif_fourcc('e','v','b','i') + +/** + * EVC main profile image (`evmi`) brand. + * + * See ISO/IEC 23008-12:2022 Section M.4.2. + */ +#define heif_brand2_evmi heif_fourcc('e','v','m','i') + +/** + * EVC baseline image sequence (`evbs`) brand. + * + * See ISO/IEC 23008-12:2022 Section M.4.3. + */ +#define heif_brand2_evbs heif_fourcc('e','v','b','s') + +/** + * EVC main profile image sequence (`evms`) brand. + * + * See ISO/IEC 23008-12:2022 Section M.4.4. + */ +#define heif_brand2_evms heif_fourcc('e','v','m','s') + +/** + * JPEG image (`jpeg`) brand. + * + * See ISO/IEC 23008-12:2022 Annex H.4 + */ +#define heif_brand2_jpeg heif_fourcc('j','p','e','g') + +/** + * JPEG image sequence (`jpgs`) brand. + * + * See ISO/IEC 23008-12:2022 Annex H.5 + */ +#define heif_brand2_jpgs heif_fourcc('j','p','g','s') + +/** + * JPEG 2000 image (`j2ki`) brand. + * + * See ISO/IEC 15444-16:2021 Section 6.5 + */ +#define heif_brand2_j2ki heif_fourcc('j','2','k','i') + +/** + * JPEG 2000 image sequence (`j2is`) brand. + * + * See ISO/IEC 15444-16:2021 Section 7.6 + */ +#define heif_brand2_j2is heif_fourcc('j','2','i','s') /** * Multi-image application format (MIAF) brand. @@ -705,6 +1030,15 @@ int heif_image_handle_get_luma_bits_per_pixel(const struct heif_image_handle*); LIBHEIF_API int heif_image_handle_get_chroma_bits_per_pixel(const struct heif_image_handle*); +// Return the colorspace that libheif proposes to use for decoding. +// Usually, these will be either YCbCr or Monochrome, but it may also propose RGB for images +// encoded with matrix_coefficients=0. +// It may also return *_undefined if the file misses relevant information to determine this without decoding. +LIBHEIF_API +struct heif_error heif_image_handle_get_preferred_decoding_colorspace(const struct heif_image_handle* image_handle, + enum heif_colorspace* out_colorspace, + enum heif_chroma* out_chroma); + // Get the image width from the 'ispe' box. This is the original image size without // any transformations applied to it. Do not use this unless you know exactly what // you are doing. @@ -714,6 +1048,17 @@ int heif_image_handle_get_ispe_width(const struct heif_image_handle* handle); LIBHEIF_API int heif_image_handle_get_ispe_height(const struct heif_image_handle* handle); +// This gets the context associated with the image handle. +// Note that you have to release the returned context with heif_context_free() in any case. +// +// This means: when you have several image-handles that originate from the same file and you get the +// context of each of them, the returned pointer may be different even though it refers to the same +// logical context. You have to call heif_context_free() on all those context pointers. +// After you freed a context pointer, you can still use the context through a different pointer that you +// might have acquired from elsewhere. +LIBHEIF_API +struct heif_context* heif_image_handle_get_context(const struct heif_image_handle* handle); + // ------------------------- depth images ------------------------- @@ -878,6 +1223,10 @@ struct heif_error heif_image_handle_get_metadata(const struct heif_image_handle* heif_item_id metadata_id, void* out_data); +// Only valid for item type == "uri ", an absolute URI +LIBHEIF_API +const char* heif_image_handle_get_metadata_item_uri_type(const struct heif_image_handle* handle, + heif_item_id metadata_id); // ------------------------- color profiles ------------------------- @@ -1001,7 +1350,7 @@ struct heif_error heif_image_handle_get_nclx_color_profile(const struct heif_ima // Do not fill values for higher versions as these might be outside the allocated structure size. // May return NULL. LIBHEIF_API -struct heif_color_profile_nclx* heif_nclx_color_profile_alloc(); +struct heif_color_profile_nclx* heif_nclx_color_profile_alloc(void); LIBHEIF_API void heif_nclx_color_profile_free(struct heif_color_profile_nclx* nclx_profile); @@ -1022,110 +1371,7 @@ struct heif_error heif_image_get_nclx_color_profile(const struct heif_image* ima struct heif_color_profile_nclx** out_data); -// ------------------------- item properties ------------------------- - -enum heif_item_property_type -{ -// heif_item_property_unknown = -1, - heif_item_property_type_invalid = 0, - heif_item_property_type_user_description = heif_fourcc('u', 'd', 'e', 's'), - 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') -}; - -// Get the heif_property_id for a heif_item_id. -// You may specify which property 'type' you want to receive. -// If you specify 'heif_item_property_type_invalid', all properties associated to that item are returned. -// The number of properties is returned, which are not more than 'count' if (out_list != nullptr). -// By setting out_list==nullptr, you can query the number of properties, 'count' is ignored. -LIBHEIF_API -int heif_item_get_properties_of_type(const struct heif_context* context, - heif_item_id id, - enum heif_item_property_type type, - heif_property_id* out_list, - int count); - -// Returns all transformative properties in the correct order. -// This includes "irot", "imir", "clap". -// The number of properties is returned, which are not more than 'count' if (out_list != nullptr). -// By setting out_list==nullptr, you can query the number of properties, 'count' is ignored. -LIBHEIF_API -int heif_item_get_transformation_properties(const struct heif_context* context, - heif_item_id id, - heif_property_id* out_list, - int count); - -LIBHEIF_API -enum heif_item_property_type heif_item_get_property_type(const struct heif_context* context, - heif_item_id id, - heif_property_id property_id); - -// The strings are managed by libheif. They will be deleted in heif_property_user_description_release(). -struct heif_property_user_description -{ - int version; - - // version 1 - - const char* lang; - const char* name; - const char* description; - const char* tags; -}; - -// Get the "udes" user description property content. -// Undefined strings are returned as empty strings. -LIBHEIF_API -struct heif_error heif_item_get_property_user_description(const struct heif_context* context, - heif_item_id itemId, - heif_property_id propertyId, - struct heif_property_user_description** out); - -// Add a "udes" user description property to the item. -// If any string pointers are NULL, an empty string will be used instead. -LIBHEIF_API -struct heif_error heif_item_add_property_user_description(const struct heif_context* context, - heif_item_id itemId, - const struct heif_property_user_description* description, - heif_property_id* out_propertyId); - -// Release all strings and the object itself. -// Only call for objects that you received from heif_item_get_property_user_description(). -LIBHEIF_API -void heif_property_user_description_release(struct heif_property_user_description*); - -enum heif_transform_mirror_direction -{ - heif_transform_mirror_direction_vertical = 0, // flip image vertically - heif_transform_mirror_direction_horizontal = 1 // flip image horizontally -}; - -LIBHEIF_API -enum heif_transform_mirror_direction heif_item_get_property_transform_mirror(const struct heif_context* context, - heif_item_id itemId, - heif_property_id propertyId); - -// Returns only 0, 90, 180, or 270 angle values. -// Returns -1 in case of error (but it will only return an error in case of wrong usage). -LIBHEIF_API -int heif_item_get_property_transform_rotation_ccw(const struct heif_context* context, - heif_item_id itemId, - heif_property_id propertyId); - -// Returns the number of pixels that should be removed from the four edges. -// Because of the way this data is stored, you have to pass the image size at the moment of the crop operation -// to compute the cropped border sizes. -LIBHEIF_API -void heif_item_get_property_transform_crop_borders(const struct heif_context* context, - heif_item_id itemId, - heif_property_id propertyId, - int image_width, int image_height, - int* left, int* top, int* right, int* bottom); - - -// ========================= heif_image ========================= +// ========================= heif_image ========================= // An heif_image contains a decoded pixel image in various colorspaces, chroma formats, // and bit depths. @@ -1136,141 +1382,6 @@ void heif_item_get_property_transform_crop_borders(const struct heif_context* co // Planar RGB images are specified as heif_colorspace_RGB / heif_chroma_444. -/** - * libheif known compression formats. - */ -enum heif_compression_format -{ - /** - * Unspecified / undefined compression format. - * - * This is used to mean "no match" or "any decoder" for some parts of the - * API. It does not indicate a specific compression format. - */ - heif_compression_undefined = 0, - /** - * HEVC compression, used for HEIC images. - * - * This is equivalent to H.265. - */ - heif_compression_HEVC = 1, - /** - * AVC compression. (Currently unused in libheif.) - * - * The compression is defined in ISO/IEC 14496-10. This is equivalent to H.264. - * - * The encapsulation is defined in ISO/IEC 23008-12:2022 Annex E. - */ - heif_compression_AVC = 2, - /** - * JPEG compression. - * - * The compression format is defined in ISO/IEC 10918-1. The encapsulation - * of JPEG is specified in ISO/IEC 23008-12:2022 Annex H. - */ - heif_compression_JPEG = 3, - /** - * AV1 compression, used for AVIF images. - * - * The compression format is provided at https://aomediacodec.github.io/av1-spec/ - * - * The encapsulation is defined in https://aomediacodec.github.io/av1-avif/ - */ - heif_compression_AV1 = 4, - /** - * VVC compression. (Currently unused in libheif.) - * - * The compression format is defined in ISO/IEC 23090-3. This is equivalent to H.266. - * - * The encapsulation is defined in ISO/IEC 23008-12:2022 Annex L. - */ - heif_compression_VVC = 5, - /** - * EVC compression. (Currently unused in libheif.) - * - * The compression format is defined in ISO/IEC 23094-1. This is equivalent to H.266. - * - * The encapsulation is defined in ISO/IEC 23008-12:2022 Annex M. - */ - heif_compression_EVC = 6, - /** - * JPEG 2000 compression. (Currently unused in libheif.) - * - * The encapsulation of JPEG 2000 is specified in ISO/IEC 15444-16:2021. - * The core encoding is defined in ISO/IEC 15444-1, or ITU-T T.800. - */ - heif_compression_JPEG2000 = 7, - /** - * Uncompressed encoding. - * - * This is defined in ISO/IEC 23001-17:2023 (Draft International Standard). - */ - heif_compression_uncompressed = 8, - /** - * Mask image encoding. - * - * See ISO/IEC 23008-12:2022 Section 6.10.2 - */ - heif_compression_mask = 9 -}; - -enum heif_chroma -{ - heif_chroma_undefined = 99, - heif_chroma_monochrome = 0, - heif_chroma_420 = 1, - heif_chroma_422 = 2, - heif_chroma_444 = 3, - heif_chroma_interleaved_RGB = 10, - heif_chroma_interleaved_RGBA = 11, - heif_chroma_interleaved_RRGGBB_BE = 12, // HDR, big endian. - heif_chroma_interleaved_RRGGBBAA_BE = 13, // HDR, big endian. - heif_chroma_interleaved_RRGGBB_LE = 14, // HDR, little endian. - heif_chroma_interleaved_RRGGBBAA_LE = 15 // HDR, little endian. -}; - -// DEPRECATED ENUM NAMES -#define heif_chroma_interleaved_24bit heif_chroma_interleaved_RGB -#define heif_chroma_interleaved_32bit heif_chroma_interleaved_RGBA - - -enum heif_colorspace -{ - heif_colorspace_undefined = 99, - - // heif_colorspace_YCbCr should be used with one of these heif_chroma values: - // * heif_chroma_444 - // * heif_chroma_422 - // * heif_chroma_420 - heif_colorspace_YCbCr = 0, - - // heif_colorspace_RGB should be used with one of these heif_chroma values: - // * heif_chroma_444 (for planar RGB) - // * heif_chroma_interleaved_RGB - // * heif_chroma_interleaved_RGBA - // * heif_chroma_interleaved_RRGGBB_BE - // * heif_chroma_interleaved_RRGGBBAA_BE - // * heif_chroma_interleaved_RRGGBB_LE - // * heif_chroma_interleaved_RRGGBBAA_LE - heif_colorspace_RGB = 1, - - // heif_colorspace_monochrome should only be used with heif_chroma = heif_chroma_monochrome - heif_colorspace_monochrome = 2 -}; - -enum heif_channel -{ - heif_channel_Y = 0, - heif_channel_Cb = 1, - heif_channel_Cr = 2, - heif_channel_R = 3, - heif_channel_G = 4, - heif_channel_B = 5, - heif_channel_Alpha = 6, - heif_channel_interleaved = 10 -}; - - enum heif_progress_step { heif_progress_step_total = 0, @@ -1303,7 +1414,12 @@ struct heif_color_conversion_options enum heif_chroma_downsampling_algorithm preferred_chroma_downsampling_algorithm; enum heif_chroma_upsampling_algorithm preferred_chroma_upsampling_algorithm; - // When set to 'false', libheif may also use a different algorithm if the preferred one is not available. + // When set to 'false' libheif may also use a different algorithm if the preferred one is not available + // or using a different algorithm is computationally less complex. Note that currently (v1.17.0) this + // means that for RGB input it will usually choose nearest-neighbor sampling because this is computationally + // the simplest. + // Set this field to 'true' if you want to make sure that the specified algorithm is used even + // at the cost of slightly higher computation times. uint8_t only_use_preferred_chroma_algorithm; }; @@ -1354,7 +1470,7 @@ struct heif_decoding_options // Note: you should always get the decoding options through this function since the // option structure may grow in size in future versions. LIBHEIF_API -struct heif_decoding_options* heif_decoding_options_alloc(); +struct heif_decoding_options* heif_decoding_options_alloc(void); LIBHEIF_API void heif_decoding_options_free(struct heif_decoding_options*); @@ -1381,22 +1497,47 @@ enum heif_colorspace heif_image_get_colorspace(const struct heif_image*); LIBHEIF_API enum heif_chroma heif_image_get_chroma_format(const struct heif_image*); -// Get width of the given image channel in pixels. Returns -1 if a non-existing -// channel was given. +/** + * Get the width of a specified image channel. + * + * @param img the image to get the width for + * @param channel the channel to select + * @return the width of the channel in pixels, or -1 the channel does not exist in the image + */ LIBHEIF_API -int heif_image_get_width(const struct heif_image*, enum heif_channel channel); +int heif_image_get_width(const struct heif_image* img, enum heif_channel channel); -// Get height of the given image channel in pixels. Returns -1 if a non-existing -// channel was given. +/** + * Get the height of a specified image channel. + * + * @param img the image to get the height for + * @param channel the channel to select + * @return the height of the channel in pixels, or -1 the channel does not exist in the image + */ LIBHEIF_API -int heif_image_get_height(const struct heif_image*, enum heif_channel channel); +int heif_image_get_height(const struct heif_image* img, enum heif_channel channel); -// Get the width of the main channel (Y in YCbCr, or any in RGB). +/** + * Get the width of the main channel. + * + * This is the Y channel in YCbCr or mono, or any in RGB. + * + * @param img the image to get the primary width for + * @return the width in pixels + */ LIBHEIF_API -int heif_image_get_primary_width(const struct heif_image*); +int heif_image_get_primary_width(const struct heif_image* img); +/** + * Get the height of the main channel. + * + * This is the Y channel in YCbCr or mono, or any in RGB. + * + * @param img the image to get the primary height for + * @return the height in pixels + */ LIBHEIF_API -int heif_image_get_primary_height(const struct heif_image*); +int heif_image_get_primary_height(const struct heif_image* img); LIBHEIF_API struct heif_error heif_image_crop(struct heif_image* img, @@ -1763,7 +1904,7 @@ struct heif_error heif_encoder_get_parameter_integer(struct heif_encoder*, const char* parameter_name, int* value); -// TO-DO: name should be changed to heif_encoder_get_valid_integer_parameter_range +// TOD-O: name should be changed to heif_encoder_get_valid_integer_parameter_range LIBHEIF_API // DEPRECATED. struct heif_error heif_encoder_parameter_integer_valid_range(struct heif_encoder*, const char* parameter_name, @@ -1881,7 +2022,7 @@ struct heif_encoding_options }; LIBHEIF_API -struct heif_encoding_options* heif_encoding_options_alloc(); +struct heif_encoding_options* heif_encoding_options_alloc(void); LIBHEIF_API void heif_encoding_options_free(struct heif_encoding_options*); @@ -1963,20 +2104,53 @@ struct heif_error heif_context_add_generic_metadata(struct heif_context* ctx, // --- heif_image allocation -// Create a new image of the specified resolution and colorspace. -// Note: no memory for the actual image data is reserved yet. You have to use -// heif_image_add_plane() to add the image planes required by your colorspace/chroma. +/** + * Create a new image of the specified resolution and colorspace. + * + *

This does not allocate memory for the image data. Use {@link heif_image_add_plane} to + * add the corresponding planes to match the specified {@code colorspace} and {@code chroma}. + * + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @param colorspace the colorspace of the image + * @param chroma the chroma of the image + * @param out_image pointer to pointer of the resulting image + * @return whether the creation succeeded or there was an error +*/ LIBHEIF_API struct heif_error heif_image_create(int width, int height, enum heif_colorspace colorspace, enum heif_chroma chroma, struct heif_image** out_image); -// The indicated bit_depth corresponds to the bit depth per channel. -// I.e. for interleaved formats like RRGGBB, the bit_depth would be, e.g., 10 bit instead -// of 30 bits or 3*16=48 bits. -// For backward compatibility, one can also specify 24bits for RGB and 32bits for RGBA, -// instead of the preferred 8 bits. +/** + * Add an image plane to the image. + * + *

The image plane needs to match the colorspace and chroma of the image. Note + * that this does not need to be a single "planar" format - interleaved pixel channels + * can also be used if the chroma is interleaved. + * + *

The indicated bit_depth corresponds to the bit depth per channel. For example, + * with an interleaved format like RRGGBB where each color is represented by 10 bits, + * the {@code bit_depth} would be {@code 10} rather than {@code 30}. + * + *

For backward compatibility, one can also specify 24bits for RGB and 32bits for RGBA, + * instead of the preferred 8 bits. However, this use is deprecated. + * + * @param image the parent image to add the channel plane to + * @param channel the channel of the plane to add + * @param width the width of the plane + * @param height the height of the plane + * @param bit_depth the bit depth per color channel + * @return whether the addition succeeded or there was an error + * + * @note The width and height are usually the same as the parent image, but can be + * less for subsampling. + * + * @note The specified width can differ from the row stride of the resulting image plane. + * Always use the result of {@link heif_image_get_plane} or {@link heif_image_get_plane_readonly} + * to determine row stride. + */ LIBHEIF_API struct heif_error heif_image_add_plane(struct heif_image* image, enum heif_channel channel, @@ -2024,838 +2198,6 @@ LIBHEIF_API int heif_encoder_descriptor_supportes_lossless_compression(const struct heif_encoder_descriptor*); -// --- region items and annotations - -// See ISO/IEC 23008-12:2022 Section 6.10 "Region items and region annotations" - -struct heif_region_item; - -/** - * Region type. - * - * Each region item will contain zero or more regions, which may have different geometry or - * mask representations. -*/ -enum heif_region_type -{ - /** - * Point gemetry. - * - * The region is represented by a single point. - */ - heif_region_type_point = 0, - - /** - * Rectangle geometry. - * - * The region is represented by a top left position, and a size defined - * by a width and height. All of the interior points and the edge are - * part of the region. - */ - heif_region_type_rectangle = 1, - - /** - * Ellipse geometry. - * - * The region is represented by a centre point, and radii in the X and - * Y directions. All of the interior points and the edge are part of the - * region. - */ - heif_region_type_ellipse = 2, - - /** - * Polygon geometry. - * - * The region is represented by a sequence of points, which is considered - * implicitly closed. All of the interior points and the edge are part - * of the region. - */ - heif_region_type_polygon = 3, - - /** - * Reference mask. - * - * The region geometry is described by the pixels in another image item, - * which has a item reference of type `mask` from the region item to the - * image item containing the mask. - * - * The image item containing the mask is one of: - * - * - a mask item (see ISO/IEC 23008-12:2022 Section 6.10.2), or a derived - * image from a mask item - * - * - an image item in monochrome format (4:0:0 chroma) - * - * - an image item in colour format with luma and chroma planes (e.g. 4:2:0) - * - * If the pixel value is equal to the minimum sample value (e.g. 0 for unsigned - * integer), the pixel is not part of the region. If the pixel value is equal - * to the maximum sample value (e.g. 255 for 8 bit unsigned integer), the pixel - * is part of the region. If the pixel value is between the minimum sample value - * and maximum sample value, the pixel value represents an (application defined) - * probability that the pixel is part of the region, where higher pixel values - * correspond to higher probability values. - */ - heif_region_type_referenced_mask = 4, - - /** - * Inline mask. - * - * The region geometry is described by a sequence of bits stored in inline - * in the region, one bit per pixel. If the bit value is `1`, the pixel is - * part of the region. If the bit value is `0`, the pixel is not part of the - * region. - */ - heif_region_type_inline_mask = 5, - - /** - * Polyline geometry. - * - * The region is represented by a sequence of points, which are not - * considered to form a closed surface. Only the edge is part of the region. - */ - heif_region_type_polyline = 6 -}; - -struct heif_region; - -/** - * Get the number of region items that are attached to an image. - * - * @param image_handle the image handle for the image to query. - * @return the number of region items, which can be zero. - */ -LIBHEIF_API -int heif_image_handle_get_number_of_region_items(const struct heif_image_handle* image_handle); - -/** - * Get the region item identifiers for the region items attached to an image. - * - * Possible usage (in C++): - * @code - * int numRegionItems = heif_image_handle_get_number_of_region_items(handle); - * if (numRegionItems > 0) { - * std::vector region_item_ids(numRegionItems); - * heif_image_handle_get_list_of_region_item_ids(handle, region_item_ids.data(), numRegionItems); - * // use region item ids - * } - * @endcode - * - * @param image_handle the image handle for the parent image to query - * @param region_item_ids_array array to put the item identifiers into - * @param max_count the maximum number of region identifiers - * @return the number of region item identifiers that were returned. - */ -LIBHEIF_API -int heif_image_handle_get_list_of_region_item_ids(const struct heif_image_handle* image_handle, - heif_item_id* region_item_ids_array, - int max_count); - -/** - * Get the region item. - * - * Caller is responsible for release of the output heif_region_item with heif_region_item_release(). - * - * @param context the context to get the region item from, usually from a file operation - * @param region_item_id the identifier for the region item - * @param out pointer to pointer to the resulting region item - * @return heif_error_ok on success, or an error value indicating the problem - */ -LIBHEIF_API -struct heif_error heif_context_get_region_item(const struct heif_context* context, - heif_item_id region_item_id, - struct heif_region_item** out); - -/** - * Get the item identifier for a region item. - * - * @param region_item the region item to query - * @return the region item identifier (or -1 if the region_item is null) - */ -LIBHEIF_API -heif_item_id heif_region_item_get_id(struct heif_region_item* region_item); - -/** - * Release a region item. - * - * This should be called on items from heif_context_get_region_item(). - * - * @param region_item the item to release. - */ -LIBHEIF_API -void heif_region_item_release(struct heif_region_item* region_item); - -/** - * Get the reference size for a region item. - * - * The reference size specifies the coordinate space used for the region items. - * When the reference size does not match the image size, the regions need to be - * scaled to correspond. - * - * @param width the return value for the reference width (before any transformation) - * @param height the return value for the reference height (before any transformation) - */ -LIBHEIF_API -void heif_region_item_get_reference_size(struct heif_region_item*, uint32_t* width, uint32_t* height); - -/** - * Get the number of regions within a region item. - * - * @param region_item the region item to query. - * @return the number of regions -*/ -LIBHEIF_API -int heif_region_item_get_number_of_regions(const struct heif_region_item* region_item); - -/** - * Get the regions that are part of a region item. - * - * Caller is responsible for releasing the returned `heif_region` objects, using heif_region_release() - * on each region, or heif_region_release_many() on the returned array. - * - * Possible usage (in C++): - * @code - * int num_regions = heif_image_handle_get_number_of_regions(region_item); - * if (num_regions > 0) { - * std::vector regions(num_regions); - * int n = heif_region_item_get_list_of_regions(region_item, regions.data(), (int)regions.size()); - * // use regions - * heif_region_release_many(regions.data(), n); - * } - * @endcode - * - * @param region_item the region_item to query - * @param out_regions_array array to put the region pointers into - * @param max_count the maximum number of regions, which needs to correspond to the size of the out_regions_array - * @return the number of regions that were returned. - */ -LIBHEIF_API -int heif_region_item_get_list_of_regions(const struct heif_region_item* region_item, - struct heif_region** out_regions_array, - int max_count); - -/** - * Release a region. - * - * This should be called on regions from heif_region_item_get_list_of_regions(). - * - * @param region the region to release. - * - * \sa heif_region_release_many() to release the whole list - */ -LIBHEIF_API -void heif_region_release(const struct heif_region* region); - -/** - * Release a list of regions. - * - * This should be called on the list of regions from heif_region_item_get_list_of_regions(). - * - * @param regions_array the regions to release. - * @param num the number of items in the array - * - * \sa heif_region_release() to release a single region - */ -LIBHEIF_API -void heif_region_release_many(const struct heif_region* const* regions_array, int num); - -/** - * Get the region type for a specified region. - * - * @param region the region to query - * @return the corresponding region type as an enumeration value - */ -LIBHEIF_API -enum heif_region_type heif_region_get_type(const struct heif_region* region); - -// When querying the region geometry, there is a version without and a version with "_transformed" suffix. -// The version without returns the coordinates in the reference coordinate space. -// The version with "_transformed" suffix give the coordinates in pixels after all transformative properties have been applied. - -/** - * Get the values for a point region. - * - * This returns the coordinates in the reference coordinate space (from the parent region item). - * - * @param region the region to query, which must be of type #heif_region_type_point. - * @param x the X coordinate, where 0 is the left-most column. - * @param y the Y coordinate, where 0 is the top-most row. - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_point_transformed() for a version in pixels after all transformative properties have been applied. - */ -LIBHEIF_API -struct heif_error heif_region_get_point(const struct heif_region* region, int32_t* x, int32_t* y); - -/** - * Get the transformed values for a point region. - * - * This returns the coordinates in pixels after all transformative properties have been applied. - * - * @param region the region to query, which must be of type #heif_region_type_point. - * @param x the X coordinate, where 0 is the left-most column. - * @param y the Y coordinate, where 0 is the top-most row. - * @param image_id the identifier for the image to transform / scale the region to - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_point() for a version that returns the values in the reference coordinate space. - */ -LIBHEIF_API -struct heif_error heif_region_get_point_transformed(const struct heif_region* region, double* x, double* y, - heif_item_id image_id); - -/** - * Get the values for a rectangle region. - * - * This returns the values in the reference coordinate space (from the parent region item). - * The rectangle is represented by a top left corner position, and a size defined - * by a width and height. All of the interior points and the edge are - * part of the region. - * - * @param region the region to query, which must be of type #heif_region_type_rectangle. - * @param x the X coordinate for the top left corner, where 0 is the left-most column. - * @param y the Y coordinate for the top left corner, where 0 is the top-most row. - * @param width the width of the rectangle - * @param height the height of the rectangle - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_rectangle_transformed() for a version in pixels after all transformative properties have been applied. - */ -LIBHEIF_API -struct heif_error heif_region_get_rectangle(const struct heif_region* region, - int32_t* x, int32_t* y, - uint32_t* width, uint32_t* height); - -/** - * Get the transformed values for a rectangle region. - * - * This returns the coordinates in pixels after all transformative properties have been applied. - * The rectangle is represented by a top left corner position, and a size defined - * by a width and height. All of the interior points and the edge are - * part of the region. - * - * @param region the region to query, which must be of type #heif_region_type_rectangle. - * @param x the X coordinate for the top left corner, where 0 is the left-most column. - * @param y the Y coordinate for the top left corner, where 0 is the top-most row. - * @param width the width of the rectangle - * @param height the height of the rectangle - * @param image_id the identifier for the image to transform / scale the region to - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_rectangle() for a version that returns the values in the reference coordinate space. - */ -LIBHEIF_API -struct heif_error heif_region_get_rectangle_transformed(const struct heif_region* region, - double* x, double* y, - double* width, double* height, - heif_item_id image_id); - -/** - * Get the values for an ellipse region. - * - * This returns the values in the reference coordinate space (from the parent region item). - * The ellipse is represented by a centre position, and a size defined - * by radii in the X and Y directions. All of the interior points and the edge are - * part of the region. - * - * @param region the region to query, which must be of type #heif_region_type_ellipse. - * @param x the X coordinate for the centre point, where 0 is the left-most column. - * @param y the Y coordinate for the centre point, where 0 is the top-most row. - * @param radius_x the radius value in the X direction. - * @param radius_y the radius value in the Y direction - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_ellipse_transformed() for a version in pixels after all transformative properties have been applied. - */ -LIBHEIF_API -struct heif_error heif_region_get_ellipse(const struct heif_region* region, - int32_t* x, int32_t* y, - uint32_t* radius_x, uint32_t* radius_y); - - -/** - * Get the transformed values for an ellipse region. - * - * This returns the coordinates in pixels after all transformative properties have been applied. - * The ellipse is represented by a centre position, and a size defined - * by radii in the X and Y directions. All of the interior points and the edge are - * part of the region. - * - * @param region the region to query, which must be of type #heif_region_type_ellipse. - * @param x the X coordinate for the centre point, where 0 is the left-most column. - * @param y the Y coordinate for the centre point, where 0 is the top-most row. - * @param radius_x the radius value in the X direction. - * @param radius_y the radius value in the Y direction - * @param image_id the identifier for the image to transform / scale the region to - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_ellipse() for a version that returns the values in the reference coordinate space. - */ -LIBHEIF_API -struct heif_error heif_region_get_ellipse_transformed(const struct heif_region* region, - double* x, double* y, - double* radius_x, double* radius_y, - heif_item_id image_id); - -/** - * Get the number of points in a polygon. - * - * @param region the region to query, which must be of type #heif_region_type_polygon - * @return the number of points, or -1 on error. - */ -LIBHEIF_API -int heif_region_get_polygon_num_points(const struct heif_region* region); - -/** - * Get the points in a polygon region. - * - * This returns the values in the reference coordinate space (from the parent region item). - * - * A polygon is a sequence of points that form a closed shape. The first point does - * not need to be repeated as the last point. All of the interior points and the edge are - * part of the region. - * The points are returned as pairs of X,Y coordinates, in the order X1, - * Y1, X2, Y2, ..., Xn, Yn. - * - * @param region the region to equery, which must be of type #heif_region_type_polygon - * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points - * in the polygon. - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_polygon_points_transformed() for a version in pixels after all transformative properties have been applied. - */ -LIBHEIF_API -struct heif_error heif_region_get_polygon_points(const struct heif_region* region, - int32_t* out_pts_array); - -/** - * Get the transformed points in a polygon region. - * - * This returns the coordinates in pixels after all transformative properties have been applied. - * - * A polygon is a sequence of points that form a closed shape. The first point does - * not need to be repeated as the last point. All of the interior points and the edge are - * part of the region. - * The points are returned as pairs of X,Y coordinates, in the order X1, - * Y1, X2, Y2, ..., Xn, Yn. - * - * @param region the region to equery, which must be of type #heif_region_type_polygon - * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points - * in the polygon. - * @param image_id the identifier for the image to transform / scale the region to - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_polygon_points() for a version that returns the values in the reference coordinate space. - */ -LIBHEIF_API -struct heif_error heif_region_get_polygon_points_transformed(const struct heif_region* region, - double* out_pts_array, - heif_item_id image_id); -/** - * Get the number of points in a polyline. - * - * @param region the region to query, which must be of type #heif_region_type_polyline - * @return the number of points, or -1 on error. - */ -LIBHEIF_API -int heif_region_get_polyline_num_points(const struct heif_region* region); - -/** - * Get the points in a polyline region. - * - * This returns the values in the reference coordinate space (from the parent region item). - * - * A polyline is a sequence of points that does not form a closed shape. Even if the - * polyline is closed, the only points that are part of the region are those that - * intersect (even minimally) a one-pixel line drawn along the polyline. - * The points are provided as pairs of X,Y coordinates, in the order X1, - * Y1, X2, Y2, ..., Xn, Yn. - * - * Possible usage (in C++): - * @code - * int num_polyline_points = heif_region_get_polyline_num_points(region); - * if (num_polyline_points > 0) { - * std::vector polyline(num_polyline_points * 2); - * heif_region_get_polyline_points(region, polyline.data()); - * // do something with points ... - * } - * @endcode - * - * @param region the region to equery, which must be of type #heif_region_type_polyline - * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points - * in the polyline. - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_polyline_points_transformed() for a version in pixels after all transformative properties have been applied. - */ -LIBHEIF_API -struct heif_error heif_region_get_polyline_points(const struct heif_region* region, - int32_t* out_pts_array); - -/** - * Get the transformed points in a polyline region. - * - * This returns the coordinates in pixels after all transformative properties have been applied. - * - * A polyline is a sequence of points that does not form a closed shape. Even if the - * polyline is closed, the only points that are part of the region are those that - * intersect (even minimally) a one-pixel line drawn along the polyline. - * The points are provided as pairs of X,Y coordinates, in the order X1, - * Y1, X2, Y2, ..., Xn, Yn. - * - * @param region the region to equery, which must be of type #heif_region_type_polyline - * @param out_pts_array the array to return the points in, which must have twice as many entries as there are points - * in the polyline. - * @param image_id the identifier for the image to transform / scale the region to - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \sa heif_region_get_polyline_points() for a version that returns the values in the reference coordinate space. - */ -LIBHEIF_API -struct heif_error heif_region_get_polyline_points_transformed(const struct heif_region* region, - double* out_pts_array, - heif_item_id image_id); - -/** - * Get a referenced item mask region. - * - * This returns the values in the reference coordinate space (from the parent region item). - * The mask location is represented by a top left corner position, and a size defined - * by a width and height. The value of each sample in that mask identifies whether the - * corresponding pixel is part of the region. - * - * The mask is provided as an image in another item. The image item containing the mask - * is one of: - * - * - a mask item (see ISO/IEC 23008-12:2022 Section 6.10.2), or a derived - * image from a mask item - * - * - an image item in monochrome format (4:0:0 chroma) - * - * - an image item in colour format with luma and chroma planes (e.g. 4:2:0) - * - * If the pixel value is equal to the minimum sample value (e.g. 0 for unsigned - * integer), the pixel is not part of the region. If the pixel value is equal - * to the maximum sample value (e.g. 255 for 8 bit unsigned integer), the pixel - * is part of the region. If the pixel value is between the minimum sample value - * and maximum sample value, the pixel value represents an (application defined) - * probability that the pixel is part of the region, where higher pixel values - * correspond to higher probability values. - * - * @param region the region to query, which must be of type #heif_region_type_referenced_mask. - * @param x the X coordinate for the top left corner, where 0 is the left-most column. - * @param y the Y coordinate for the top left corner, where 0 is the top-most row. - * @param width the width of the mask region - * @param height the height of the mask region - * @param mask_item_id the item identifier for the image that provides the mask. - * @return heif_error_ok on success, or an error value indicating the problem on failure - */ -LIBHEIF_API -struct heif_error heif_region_get_referenced_mask_ID(const struct heif_region* region, - int32_t* x, int32_t* y, - uint32_t* width, uint32_t* height, - heif_item_id *mask_item_id); - -/** - * Get the length of the data in an inline mask region. - * - * @param region the region to query, which must be of type #heif_region_type_inline_mask. - * @return the number of bytes in the mask data, or 0 on error. - */ -LIBHEIF_API -unsigned long heif_region_get_inline_mask_data_len(const struct heif_region* region); - - -/** - * Get data for an inline mask region. - * - * This returns the values in the reference coordinate space (from the parent region item). - * The mask location is represented by a top left corner position, and a size defined - * by a width and height. - * - * The mask is held as inline data on the region, one bit per pixel, most significant - * bit first pixel, no padding. If the bit value is `1`, the corresponding pixel is - * part of the region. If the bit value is `0`, the corresponding pixel is not part of the - * region. - * - * Possible usage (in C++): - * @code - * long unsigned int data_len = heif_region_get_inline_mask_data_len(region); - * int32_t x, y; - * uint32_t width, height; - * std::vector mask_data(data_len); - * err = heif_region_get_inline_mask(region, &x, &y, &width, &height, mask_data.data()); - * @endcode - * - * @param region the region to query, which must be of type #heif_region_type_inline_mask. - * @param x the X coordinate for the top left corner, where 0 is the left-most column. - * @param y the Y coordinate for the top left corner, where 0 is the top-most row. - * @param width the width of the mask region - * @param height the height of the mask region - * @param mask_data the location to return the mask data - * @return heif_error_ok on success, or an error value indicating the problem on failure - */ -LIBHEIF_API -struct heif_error heif_region_get_inline_mask_data(const struct heif_region* region, - int32_t* x, int32_t* y, - uint32_t* width, uint32_t* height, - uint8_t* mask_data); - -/** - * Get a mask region image. - * - * This returns the values in the reference coordinate space (from the parent region item). - * The mask location is represented by a top left corner position, and a size defined - * by a width and height. - * - * This function works when the passed region is either a heif_region_type_referenced_mask or - * a heif_region_type_inline_mask. - * The returned image is a monochrome image where each pixel represents the (scaled) probability - * of the pixel being part of the mask. - * - * If the region type is an inline mask, which always holds a binary mask, this function - * converts the binary inline mask to an 8-bit monochrome image with the values '0' and '255'. - * The pixel value is set to `255` where the pixel is part of the region, and `0` where the - * pixel is not part of the region. - * - * @param region the region to query, which must be of type #heif_region_type_inline_mask. - * @param x the X coordinate for the top left corner, where 0 is the left-most column. - * @param y the Y coordinate for the top left corner, where 0 is the top-most row. - * @param width the width of the mask region - * @param height the height of the mask region - * @param mask_image the returned mask image - * @return heif_error_ok on success, or an error value indicating the problem on failure - * - * \note the caller is responsible for releasing the mask image - */ -LIBHEIF_API -struct heif_error heif_region_get_mask_image(const struct heif_region* region, - int32_t* x, int32_t* y, - uint32_t* width, uint32_t* height, - struct heif_image** mask_image); - -// --- adding region items - -/** - * Add a region item to an image. - * - * The region item is a collection of regions (point, polyline, polygon, rectangle, ellipse or mask) - * along with a reference size (width and height) that forms the coordinate basis for the regions. - * - * The concept is to add the region item, then add one or more regions to the region item. - * - * @param image_handle the image to attach the region item to. - * @param reference_width the width of the reference size. - * @param reference_height the height of the reference size. - * @param out_region_item the resulting region item - * @return heif_error_ok on success, or an error indicating the problem on failure -*/ -LIBHEIF_API -struct heif_error heif_image_handle_add_region_item(struct heif_image_handle* image_handle, - uint32_t reference_width, uint32_t reference_height, - struct heif_region_item** out_region_item); - -/** - * Add a point region to the region item. - * - * @param region_item the region item that holds this point region - * @param x the x value for the point location - * @param y the y value for the point location - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error indicating the problem on failure - * - * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. - */ -LIBHEIF_API -struct heif_error heif_region_item_add_region_point(struct heif_region_item* region_item, - int32_t x, int32_t y, - struct heif_region** out_region); - -/** - * Add a rectangle region to the region item. - * - * @param region_item the region item that holds this rectangle region - * @param x the x value for the top-left corner of this rectangle region - * @param y the y value for the top-left corner of this rectangle region - * @param width the width of this rectangle region - * @param height the height of this rectangle region - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error indicating the problem on failure - * - * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. - */ -LIBHEIF_API -struct heif_error heif_region_item_add_region_rectangle(struct heif_region_item* region_item, - int32_t x, int32_t y, - uint32_t width, uint32_t height, - struct heif_region** out_region); - -/** - * Add a ellipse region to the region item. - * - * @param region_item the region item that holds this ellipse region - * @param x the x value for the centre of this ellipse region - * @param y the y value for the centre of this ellipse region - * @param radius_x the radius of the ellipse in the X (horizontal) direction - * @param radius_y the radius of the ellipse in the Y (vertical) direction - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error indicating the problem on failure - * - * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. - */ -LIBHEIF_API -struct heif_error heif_region_item_add_region_ellipse(struct heif_region_item* region_item, - int32_t x, int32_t y, - uint32_t radius_x, uint32_t radius_y, - struct heif_region** out_region); - -/** - * Add a polygon region to the region item. - * - * A polygon is a sequence of points that form a closed shape. The first point does - * not need to be repeated as the last point. - * The points are provided as pairs of X,Y coordinates, in the order X1, - * Y1, X2, Y2, ..., Xn, Yn. - * - * @param region_item the region item that holds this polygon region - * @param pts_array the array of points in X,Y order (see above) - * @param nPoints the number of points - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error indicating the problem on failure - * - * @note `nPoints` is the number of points, not the number of elements in the array - * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. - */ -LIBHEIF_API -struct heif_error heif_region_item_add_region_polygon(struct heif_region_item* region_item, - const int32_t* pts_array, int nPoints, - struct heif_region** out_region); - -/** - * Add a polyline region to the region item. - * - * A polyline is a sequence of points that does not form a closed shape. Even if the - * polyline is closed, the only points that are part of the region are those that - * intersect (even minimally) a one-pixel line drawn along the polyline. - * The points are provided as pairs of X,Y coordinates, in the order X1, - * Y1, X2, Y2, ..., Xn, Yn. - * - * @param region_item the region item that holds this polyline region - * @param pts_array the array of points in X,Y order (see above) - * @param nPoints the number of points - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error indicating the problem on failure - * - * @note `nPoints` is the number of points, not the number of elements in the array - * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. - */ -LIBHEIF_API -struct heif_error heif_region_item_add_region_polyline(struct heif_region_item* region_item, - const int32_t* pts_array, int nPoints, - struct heif_region** out_region); - - -/** - * Add a referenced mask region to the region item. - * - * The region geometry is described by the pixels in another image item, - * which has a item reference of type `mask` from the region item to the - * image item containing the mask. - * - * The image item containing the mask is one of: - * - * - a mask item (see ISO/IEC 23008-12:2022 Section 6.10.2), or a derived - * image from a mask item - * - * - an image item in monochrome format (4:0:0 chroma) - * - * - an image item in colour format with luma and chroma planes (e.g. 4:2:0) - * - * If the pixel value is equal to the minimum sample value (e.g. 0 for unsigned - * integer), the pixel is not part of the region. If the pixel value is equal - * to the maximum sample value (e.g. 255 for 8 bit unsigned integer), the pixel - * is part of the region. If the pixel value is between the minimum sample value - * and maximum sample value, the pixel value represents an (application defined) - * probability that the pixel is part of the region, where higher pixel values - * correspond to higher probability values. - * - * @param region_item the region item that holds this mask region - * @param x the x value for the top-left corner of this mask region - * @param y the y value for the top-left corner of this mask region - * @param width the width of this mask region - * @param height the height of this mask region - * @param mask_item_id the item identifier for the mask that is referenced - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error indicating the problem on failure - * - * @note The `out_region` parameter is optional, and can be set to `NULL` if not needed. - */ -LIBHEIF_API -struct heif_error heif_region_item_add_region_referenced_mask(struct heif_region_item* region_item, - int32_t x, int32_t y, - uint32_t width, uint32_t height, - heif_item_id mask_item_id, - struct heif_region** out_region); - - -/** - * Add an inline mask region to the region item. - * - * The region geometry is described by a top left corner position, and a size defined - * by a width and height. - * - * The mask is held as inline data on the region, one bit per pixel, most significant - * bit first pixel, no padding. If the bit value is `1`, the corresponding pixel is - * part of the region. If the bit value is `0`, the corresponding pixel is not part of the - * region. - * - * @param region_item the region item that holds this mask region - * @param x the x value for the top-left corner of this mask region - * @param y the y value for the top-left corner of this mask region - * @param width the width of this mask region - * @param height the height of this mask region - * @param mask_data the location to return the mask data - * @param mask_data_len the length of the mask data, in bytes - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error value indicating the problem on failure - */ - LIBHEIF_API -struct heif_error heif_region_item_add_region_inline_mask_data(struct heif_region_item* region_item, - int32_t x, int32_t y, - uint32_t width, uint32_t height, - uint8_t* mask_data, - unsigned long mask_data_len, - struct heif_region** out_region); - -/** - * Add an inline mask region image to the region item. - * - * The region geometry is described by a top left corner position, and a size defined - * by a width and height. - * - * The mask data is held as inline data on the region, one bit per pixel. The provided - * image is converted to inline data, where any pixel with a value >= 0x80 becomes part of the - * mask region. If the image width is less that the specified width, it is expanded - * to match the width of the region (zero fill on the right). If the image height is - * less than the specified height, it is expanded to match the height of the region - * (zero fill on the bottom). If the image width or height is greater than the - * width or height (correspondingly) of the region, the image is cropped. - * - * @param region_item the region item that holds this mask region - * @param x the x value for the top-left corner of this mask region - * @param y the y value for the top-left corner of this mask region - * @param width the width of this mask region - * @param height the height of this mask region - * @param image the image to convert to an inline mask - * @param out_region pointer to pointer to the returned region (optional, see below) - * @return heif_error_ok on success, or an error value indicating the problem on failure - */ - LIBHEIF_API -struct heif_error heif_region_item_add_region_inline_mask(struct heif_region_item* region_item, - int32_t x, int32_t y, - uint32_t width, uint32_t height, - struct heif_image* image, - struct heif_region** out_region); #ifdef __cplusplus } #endif diff --git a/tests/basic_test.py b/tests/basic_test.py index 0089b17d..66980350 100644 --- a/tests/basic_test.py +++ b/tests/basic_test.py @@ -16,10 +16,6 @@ def test_libheif_info(): for key in ("HEIF", "AVIF", "encoders", "decoders"): assert key in info assert pillow_heif.libheif_version() in ( - "1.15.1", - "1.15.2", - "1.16.1", - "1.16.2", "1.17.1", "1.17.3", "1.17.4",