Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libheif for openSUSE:Factory checked in at 2021-04-12 12:33:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libheif (Old) and /work/SRC/openSUSE:Factory/.libheif.new.2401 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libheif" Mon Apr 12 12:33:43 2021 rev:6 rq:883725 version:1.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libheif/libheif.changes 2021-01-11 17:09:27.628000569 +0100 +++ /work/SRC/openSUSE:Factory/.libheif.new.2401/libheif.changes 2021-04-12 12:33:45.773053880 +0200 @@ -1,0 +2,10 @@ +Wed Apr 7 23:21:55 UTC 2021 - Dirk M??ller <[email protected]> + +- update to 1.11.0: + * fix writing ispe box in HEIFs + * nclx output profile encoding parameters + * change the way nclx profiles is written so that macOS can read them + * API for listing file brands and checking file type + * fix heif_image_handle_get_depth_image_representation_info() + +------------------------------------------------------------------- Old: ---- libheif-1.10.0.tar.gz New: ---- libheif-1.11.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libheif.spec ++++++ --- /var/tmp/diff_new_pack.bOfNEV/_old 2021-04-12 12:33:46.429054895 +0200 +++ /var/tmp/diff_new_pack.bOfNEV/_new 2021-04-12 12:33:46.433054901 +0200 @@ -21,7 +21,7 @@ %define gdk_pixbuf_binary_version 2.10.0 Name: libheif -Version: 1.10.0 +Version: 1.11.0 Release: 0 Summary: HEIF/AVIF file format decoder and encoder # @@ -55,7 +55,6 @@ HEIF and AVIF are new image file formats employing HEVC (H.265) or AV1 image coding, respectively, for the best compression ratios currently possible. - %package -n libheif1 Summary: HEIF/AVIF file format decoder and encoder Group: System/Libraries @@ -79,7 +78,6 @@ libheif is a ISO/IEC 23008-12:2017 HEIF file format decoder and encoder. This package contains the header files. - %package -n gdk-pixbuf-loader-libheif Summary: GDK PixBuf Loader for %{name} Group: System/Libraries ++++++ libheif-1.10.0.tar.gz -> libheif-1.11.0.tar.gz ++++++ ++++ 4320 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/CMakeLists.txt new/libheif-1.11.0/CMakeLists.txt --- old/libheif-1.10.0/CMakeLists.txt 2020-12-15 16:25:13.000000000 +0100 +++ new/libheif-1.11.0/CMakeLists.txt 2021-02-01 15:14:13.000000000 +0100 @@ -1,6 +1,6 @@ -cmake_minimum_required (VERSION 3.3.2) +cmake_minimum_required (VERSION 3.13) -project(libheif LANGUAGES C CXX VERSION 1.10.0.0) +project(libheif LANGUAGES C CXX VERSION 1.11.0.0) # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html cmake_policy(SET CMP0054 NEW) @@ -52,20 +52,31 @@ endif() LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") + option(WITH_LIBDE265 "Build libde265 decoder" ON) if (WITH_LIBDE265) find_package(Libde265) endif () + option(WITH_X265 "Build x265 encoder" ON) if (WITH_X265) find_package(X265) endif () + option(WITH_AOM "Build aom encoder/decoder" ON) if (WITH_AOM) find_package(LibAOM) endif() -find_package(Rav1e) -find_package(Dav1d) + +option(WITH_RAV1E "Build rav1e encoder" ON) +if (WITH_RAV1E) + find_package(Rav1e) +endif () + +option(WITH_DAV1D "Build dav1e decoder" ON) +if (WITH_DAV1D) + find_package(Dav1d) +endif () if (LIBDE265_FOUND) message("HEIF decoder, libde265: found") @@ -124,6 +135,12 @@ if (AOM_DECODER_FOUND OR AOM_ENCODER_FOUND) list(APPEND REQUIRES_PRIVATE "aom") endif() +if (DAV1D_FOUND) + list(APPEND REQUIRES_PRIVATE "dav1d") +endif() +if (RAV1E_FOUND) + list(APPEND REQUIRES_PRIVATE "rav1e") +endif() if (AOM_DECODER_FOUND OR DAV1D_FOUND) set(have_avif_decoder yes) else() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/compile new/libheif-1.11.0/compile --- old/libheif-1.10.0/compile 2020-12-16 15:05:13.000000000 +0100 +++ new/libheif-1.11.0/compile 2021-02-02 09:19:47.000000000 +0100 @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey <[email protected]>. # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -255,7 +255,8 @@ echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -339,9 +340,9 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/configure.ac new/libheif-1.11.0/configure.ac --- old/libheif-1.10.0/configure.ac 2020-12-15 16:26:06.000000000 +0100 +++ new/libheif-1.11.0/configure.ac 2021-02-01 15:14:53.000000000 +0100 @@ -1,11 +1,11 @@ AC_PREREQ([2.68]) -AC_INIT([libheif], [1.10.0], [[email protected]]) +AC_INIT([libheif], [1.11.0], [[email protected]]) AC_CONFIG_SRCDIR([libheif/box.cc]) AC_CONFIG_HEADERS([config.h]) # Note: do not forget to set the version in the CMakeLists.txt file accordingly PROJECT_VERSION_MAJOR=1 -PROJECT_VERSION_MINOR=10 +PROJECT_VERSION_MINOR=11 PROJECT_VERSION_PATCH=0 PROJECT_VERSION_TWEAK=0 AC_SUBST(PROJECT_VERSION_MAJOR) @@ -19,9 +19,9 @@ # If any interfaces have been added since the last public release, then increment age. # If any interfaces have been removed or changed since the last public release, then set age to 0. -LIBHEIF_CURRENT=11 +LIBHEIF_CURRENT=12 LIBHEIF_REVISION=0 -LIBHEIF_AGE=10 +LIBHEIF_AGE=11 AC_SUBST(LIBHEIF_CURRENT) AC_SUBST(LIBHEIF_REVISION) AC_SUBST(LIBHEIF_AGE) @@ -250,6 +250,7 @@ AC_SUBST(rav1e_CFLAGS) AC_SUBST(rav1e_LIBS) have_avif_encoder="yes" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE rav1e" have_rav1e="yes" ], [have_rav1e="no"]) else @@ -263,6 +264,7 @@ AC_SUBST(dav1d_CFLAGS) AC_SUBST(dav1d_LIBS) have_avif_decoder="yes" + REQUIRES_PRIVATE="$REQUIRES_PRIVATE dav1d" have_dav1d="yes" ], [have_dav1d="no"]) AM_CONDITIONAL([HAVE_DAV1D], [test "x$have_dav1d" = "xyes"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/examples/heif_convert.cc new/libheif-1.11.0/examples/heif_convert.cc --- old/libheif-1.10.0/examples/heif_convert.cc 2020-12-15 15:39:55.000000000 +0100 +++ new/libheif-1.11.0/examples/heif_convert.cc 2021-01-24 20:56:52.000000000 +0100 @@ -357,7 +357,7 @@ std::string auxType = std::string(auxTypeC); - free((void*)auxTypeC); + heif_image_handle_free_auxiliary_types(aux_handle, &auxTypeC); std::ostringstream s; s << output_filename.substr(0, output_filename.find('.')); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/examples/heif_enc.cc new/libheif-1.11.0/examples/heif_enc.cc --- old/libheif-1.10.0/examples/heif_enc.cc 2020-12-15 14:49:42.000000000 +0100 +++ new/libheif-1.11.0/examples/heif_enc.cc 2021-01-24 20:56:52.000000000 +0100 @@ -1215,7 +1215,7 @@ nclx.color_primaries = (heif_color_primaries) nclx_colour_primaries; nclx.full_range_flag = (uint8_t) nclx_full_range; - heif_image_set_nclx_color_profile(image.get(), &nclx); + //heif_image_set_nclx_color_profile(image.get(), &nclx); heif_encoder_set_lossy_quality(encoder, quality); heif_encoder_set_lossless(encoder, lossless); @@ -1226,6 +1226,7 @@ struct heif_encoding_options* options = heif_encoding_options_alloc(); options->save_alpha_channel = (uint8_t) master_alpha; options->save_two_colr_boxes_when_ICC_and_nclx_available = (uint8_t)two_colr_boxes; + options->output_nclx_profile = &nclx; if (crop_to_even_size) { if (heif_image_get_primary_width(image.get()) == 1 || diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/examples/heif_info.cc new/libheif-1.11.0/examples/heif_info.cc --- old/libheif-1.10.0/examples/heif_info.cc 2020-11-12 23:19:08.000000000 +0100 +++ new/libheif-1.11.0/examples/heif_info.cc 2021-02-01 15:08:05.000000000 +0100 @@ -141,11 +141,13 @@ // show MIME type { - uint8_t buf[20]; + const static int bufSize = 50; + + uint8_t buf[bufSize]; FILE* fh = fopen(input_filename, "rb"); if (fh) { std::cout << "MIME type: "; - int n = (int) fread(buf, 1, 20, fh); + int n = (int) fread(buf, 1, bufSize, fh); const char* mime_type = heif_get_file_mime_type(buf, n); if (*mime_type == 0) { std::cout << "unknown\n"; @@ -155,7 +157,35 @@ } fclose(fh); + + char fourcc[5]; + fourcc[4]=0; + heif_brand_to_fourcc( heif_read_main_brand(buf,bufSize), fourcc ); + std::cout << "main brand: " << fourcc << "\n"; + + heif_brand2* brands=nullptr; + int nBrands=0; + struct heif_error err=heif_list_compatible_brands(buf, n, &brands, &nBrands); + if (err.code) { + std::cerr << "error reading brands: " << err.message << "\n"; + } + else { + std::cout << "compatible brands: "; + for (int i=0;i<nBrands;i++) { + heif_brand_to_fourcc(brands[i], fourcc); + if (i>0) { + std::cout << ", "; + } + std::cout << fourcc; + } + + std::cout << "\n"; + + heif_free_list_of_compatible_brands(brands); + } } + + std::cout << "\n"; } // ============================================================================== @@ -260,7 +290,7 @@ heif_image_handle_get_height(depth_handle)); const struct heif_depth_representation_info* depth_info; - if (heif_image_handle_get_depth_image_representation_info(depth_handle, depth_id, &depth_info)) { + if (heif_image_handle_get_depth_image_representation_info(handle, depth_id, &depth_info)) { printf(" z-near: "); if (depth_info->has_z_near) printf("%f\n", depth_info->z_near); else printf("undefined\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/box.h new/libheif-1.11.0/libheif/box.h --- old/libheif-1.10.0/libheif/box.h 2020-11-12 23:19:08.000000000 +0100 +++ new/libheif-1.11.0/libheif/box.h 2021-01-24 20:56:58.000000000 +0100 @@ -240,7 +240,9 @@ bool has_compatible_brand(uint32_t brand) const; + std::vector<uint32_t> list_brands() const { return m_compatible_brands; } + void set_major_brand(uint32_t major_brand) { m_major_brand = major_brand; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/heif.cc new/libheif-1.11.0/libheif/heif.cc --- old/libheif-1.10.0/libheif/heif.cc 2020-12-15 14:54:48.000000000 +0100 +++ new/libheif-1.11.0/libheif/heif.cc 2021-02-01 15:10:19.000000000 +0100 @@ -135,17 +135,17 @@ } -heif_brand heif_main_brand(const uint8_t* data, int len) +heif_brand heif_fourcc_to_brand_enum(const char* fourcc) { - if (len < 12) { + if (fourcc==nullptr || !fourcc[0] || !fourcc[1] || !fourcc[2] || !fourcc[3]) { return heif_unknown_brand; } - + char brand[5]; - brand[0] = data[8]; - brand[1] = data[9]; - brand[2] = data[10]; - brand[3] = data[11]; + brand[0] = fourcc[0]; + brand[1] = fourcc[1]; + brand[2] = fourcc[2]; + brand[3] = fourcc[3]; brand[4] = 0; if (strcmp(brand, "heic") == 0) { @@ -190,6 +190,126 @@ } +enum heif_brand heif_main_brand(const uint8_t* data, int len) +{ + if (len < 12) { + return heif_unknown_brand; + } + + return heif_fourcc_to_brand_enum((char*)(data+8)); +} + + +heif_brand2 heif_read_main_brand(const uint8_t* data, int len) +{ + if (len < 12) { + return heif_unknown_brand; + } + + return heif_fourcc_to_brand((char*)(data+8)); +} + + +#define fourcc_to_uint32(id) (((uint32_t)(id[0])<<24) | (id[1]<<16) | (id[2]<<8) | (id[3])) + +heif_brand2 heif_fourcc_to_brand(const char* fourcc) +{ + if (fourcc==nullptr || !fourcc[0] || !fourcc[1] || !fourcc[2] || !fourcc[3]) { + return 0; + } + + return fourcc_to_uint32(fourcc); +} + + +void heif_brand_to_fourcc(heif_brand2 brand, char* out_fourcc) +{ + if (out_fourcc) { + out_fourcc[0] = (char)((brand >> 24) & 0xFF); + out_fourcc[1] = (char)((brand >> 16) & 0xFF); + out_fourcc[2] = (char)((brand >> 8) & 0xFF); + out_fourcc[3] = (char)((brand >> 0) & 0xFF); + } +} + + +int heif_has_compatible_brand(const uint8_t* data, int len, const char* brand_fourcc) +{ + if (data == nullptr || len<=0 || brand_fourcc == nullptr || !brand_fourcc[0] || !brand_fourcc[1] || !brand_fourcc[2] || !brand_fourcc[3]) { + return -1; + } + + auto stream = std::make_shared<StreamReader_memory>(data, len, false); + BitstreamRange range(stream, len); + + std::shared_ptr<heif::Box> box; + Error err = Box::read(range, &box); + if (err) { + if (err.sub_error_code == heif_suberror_End_of_data) { + return -1; + } + + return -2; + } + + auto ftyp = std::dynamic_pointer_cast<Box_ftyp>(box); + if (!ftyp) { + return -2; + } + + return ftyp->has_compatible_brand(fourcc_to_uint32(brand_fourcc)) ? 1 : 0; +} + + + +struct heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif_brand2** out_brands, int* out_size) +{ + if (data == nullptr || out_brands==nullptr || out_size==nullptr) { + return {heif_error_Usage_error, heif_suberror_Null_pointer_argument, "NULL argument"}; + } + + if (len<=0) { + return {heif_error_Usage_error, heif_suberror_Invalid_parameter_value, "data length must be positive"}; + } + + auto stream = std::make_shared<StreamReader_memory>(data, len, false); + BitstreamRange range(stream, len); + + std::shared_ptr<heif::Box> box; + Error err = Box::read(range, &box); + if (err) { + if (err.sub_error_code == heif_suberror_End_of_data) { + return {err.error_code, err.sub_error_code, "insufficient input data"}; + } + + return {err.error_code, err.sub_error_code, "error reading ftyp box"}; + } + + auto ftyp = std::dynamic_pointer_cast<Box_ftyp>(box); + if (!ftyp) { + return {heif_error_Invalid_input, heif_suberror_No_ftyp_box, "input is no ftyp box"}; + } + + auto brands = ftyp->list_brands(); + *out_brands = (heif_brand2*)malloc(sizeof(heif_brand2) * brands.size()); + *out_size = (int)brands.size(); + + for (int i=0;i<(int)brands.size();i++) { + (*out_brands)[i] = brands[i]; + } + + return {heif_error_Ok, heif_suberror_Unspecified, Error::kSuccess}; +} + + +void heif_free_list_of_compatible_brands(heif_brand2* brands_list) +{ + if (brands_list) { + free(brands_list); + } +} + + enum class TriBool { No, Yes, Unknown @@ -554,6 +674,16 @@ } +void heif_image_handle_free_auxiliary_types(const struct heif_image_handle* handle, + const char** out_type) +{ + if (out_type && *out_type) { + free((void*)*out_type); + *out_type = nullptr; + } +} + + struct heif_error heif_image_handle_get_auxiliary_image_handle(const struct heif_image_handle* main_image_handle, heif_item_id auxiliary_id, struct heif_image_handle** out_auxiliary_handle) @@ -655,10 +785,20 @@ heif_item_id depth_image_id, const struct heif_depth_representation_info** out) { + std::shared_ptr<HeifContext::Image> depth_image; + if (out) { - if (handle->image->has_depth_representation_info()) { + if (handle->image->is_depth_channel()) { + // Because of an API bug before v1.11.0, the input handle may be the depth image (#422). + depth_image = handle->image; + } + else { + depth_image = handle->image->get_depth_channel(); + } + + if (depth_image->has_depth_representation_info()) { auto info = new heif_depth_representation_info; - *info = handle->image->get_depth_representation_info(); + *info = depth_image->get_depth_representation_info(); *out = info; return true; } @@ -1010,10 +1150,8 @@ int heif_image_handle_get_number_of_metadata_blocks(const struct heif_image_handle* handle, const char* type_filter) { - auto metadata_list = handle->image->get_metadata(); - int cnt = 0; - for (const auto& metadata : metadata_list) { + for (const auto& metadata : handle->image->get_metadata()) { if (type_filter == nullptr || metadata->item_type == type_filter) { cnt++; @@ -1028,10 +1166,8 @@ const char* type_filter, heif_item_id* ids, int count) { - auto metadata_list = handle->image->get_metadata(); - int cnt = 0; - for (const auto& metadata : metadata_list) { + for (const auto& metadata : handle->image->get_metadata()) { if (type_filter == nullptr || metadata->item_type == type_filter) { if (cnt < count) { @@ -1051,39 +1187,33 @@ const char* heif_image_handle_get_metadata_type(const struct heif_image_handle* handle, heif_item_id metadata_id) { - auto metadata_list = handle->image->get_metadata(); - - for (auto metadata : metadata_list) { + for (auto& metadata : handle->image->get_metadata()) { if (metadata->item_id == metadata_id) { return metadata->item_type.c_str(); } } - return NULL; + return nullptr; } const char* heif_image_handle_get_metadata_content_type(const struct heif_image_handle* handle, heif_item_id metadata_id) { - auto metadata_list = handle->image->get_metadata(); - - for (auto metadata : metadata_list) { + for (auto& metadata : handle->image->get_metadata()) { if (metadata->item_id == metadata_id) { return metadata->content_type.c_str(); } } - return NULL; + return nullptr; } size_t heif_image_handle_get_metadata_size(const struct heif_image_handle* handle, heif_item_id metadata_id) { - auto metadata_list = handle->image->get_metadata(); - - for (auto metadata : metadata_list) { + for (auto& metadata : handle->image->get_metadata()) { if (metadata->item_id == metadata_id) { return metadata->m_data.size(); } @@ -1097,19 +1227,20 @@ heif_item_id metadata_id, void* out_data) { - if (out_data == nullptr) { - Error err(heif_error_Usage_error, - heif_suberror_Null_pointer_argument); - return err.error_struct(handle->image.get()); - } + for (auto& metadata : handle->image->get_metadata()) { + if (metadata->item_id == metadata_id) { - auto metadata_list = handle->image->get_metadata(); + if (!metadata->m_data.empty()) { + if (out_data == nullptr) { + Error err(heif_error_Usage_error, + heif_suberror_Null_pointer_argument); + return err.error_struct(handle->image.get()); + } - for (auto metadata : metadata_list) { - if (metadata->item_id == metadata_id) { - memcpy(out_data, - metadata->m_data.data(), - metadata->m_data.size()); + memcpy(out_data, + metadata->m_data.data(), + metadata->m_data.size()); + } return Error::Ok.error_struct(handle->image.get()); } @@ -1604,7 +1735,7 @@ if (strcmp((*params)->name, parameter_name) == 0) { int have_minimum = 0, have_maximum = 0, minimum = 0, maximum = 0, num_valid_values = 0; - const int* valid_values; + const int* valid_values = nullptr; heif_error err = heif_encoder_parameter_get_valid_integer_values((*params), &have_minimum, &have_maximum, &minimum, &maximum, &num_valid_values, @@ -1941,11 +2072,33 @@ static void set_default_options(heif_encoding_options& options) { - options.version = 3; + options.version = 4; options.save_alpha_channel = true; options.macOS_compatibility_workaround = true; options.save_two_colr_boxes_when_ICC_and_nclx_available = false; + options.output_nclx_profile = nullptr; + options.macOS_compatibility_workaround_no_nclx_profile = true; +} + +static void copy_options(heif_encoding_options& options, const heif_encoding_options& input_options) +{ + set_default_options(options); + + switch (input_options.version) { + case 4: + options.output_nclx_profile = input_options.output_nclx_profile; + options.macOS_compatibility_workaround_no_nclx_profile = input_options.macOS_compatibility_workaround_no_nclx_profile; + // fallthrough + case 3: + options.save_two_colr_boxes_when_ICC_and_nclx_available = input_options.save_two_colr_boxes_when_ICC_and_nclx_available; + // fallthrough + case 2: + options.macOS_compatibility_workaround = input_options.macOS_compatibility_workaround; + // fallthrough + case 1: + options.save_alpha_channel = input_options.save_alpha_channel; + } } @@ -1967,7 +2120,7 @@ struct heif_error heif_context_encode_image(struct heif_context* ctx, const struct heif_image* input_image, struct heif_encoder* encoder, - const struct heif_encoding_options* options, + const struct heif_encoding_options* input_options, struct heif_image_handle** out_image_handle) { if (!encoder) { @@ -1975,18 +2128,34 @@ heif_suberror_Null_pointer_argument).error_struct(ctx->context.get()); } - heif_encoding_options default_options; - if (options == nullptr) { - set_default_options(default_options); - options = &default_options; + heif_encoding_options options; + heif_color_profile_nclx nclx; + if (input_options == nullptr) { + set_default_options(options); + } + else { + copy_options(options, *input_options); + + if (options.output_nclx_profile == nullptr) { + auto input_nclx = input_image->image->get_color_profile_nclx(); + if (input_nclx) { + options.output_nclx_profile = &nclx; + nclx.version = 1; + nclx.color_primaries = (enum heif_color_primaries)input_nclx->get_colour_primaries(); + nclx.transfer_characteristics = (enum heif_transfer_characteristics)input_nclx->get_transfer_characteristics(); + nclx.matrix_coefficients = (enum heif_matrix_coefficients)input_nclx->get_matrix_coefficients(); + nclx.full_range_flag = input_nclx->get_full_range_flag(); + } + } } std::shared_ptr<HeifContext::Image> image; Error error; + error = ctx->context->encode_image(input_image->image, encoder, - options, + &options, heif_image_input_class_normal, image); if (error != Error::Ok) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/heif.h new/libheif-1.11.0/libheif/heif.h --- old/libheif-1.10.0/libheif/heif.h 2020-12-15 14:54:48.000000000 +0100 +++ new/libheif-1.11.0/libheif/heif.h 2021-02-01 15:10:13.000000000 +0100 @@ -42,6 +42,7 @@ // 1.7 1 2 1 1 1 1 // 1.9.2 1 2 2 1 1 1 // 1.10 1 2 3 1 1 1 +// 1.11 1 2 4 1 1 1 #if defined(_MSC_VER) && !defined(LIBHEIF_STATIC_BUILD) @@ -297,6 +298,7 @@ enum heif_filetype_result heif_check_filetype(const uint8_t* data, int len); +// DEPRECATED, use heif_brand2 instead enum heif_brand { heif_unknown_brand, @@ -314,10 +316,42 @@ }; // input data should be at least 12 bytes +// DEPRECATED, use heif_read_main_brand() instead LIBHEIF_API enum heif_brand heif_main_brand(const uint8_t* data, int len); +typedef uint32_t heif_brand2; + +// input data should be at least 12 bytes +LIBHEIF_API +heif_brand2 heif_read_main_brand(const uint8_t* data, int len); + +// 'brand_fourcc' must be 4 character long, but need not be 0-terminated +LIBHEIF_API +heif_brand2 heif_fourcc_to_brand(const char* brand_fourcc); + +// the output buffer must be at least 4 bytes long +LIBHEIF_API +void heif_brand_to_fourcc(heif_brand2 brand, char* out_fourcc); + +// 'brand_fourcc' must be 4 character long, but need not be 0-terminated +// returns 1 if file includes the brand, and 0 if it does not +// returns -1 if the provided data is not sufficient +// (you should input at least as many bytes as indicated in the first 4 bytes of the file, usually ~50 bytes will do) +// returns -2 on other errors +LIBHEIF_API +int heif_has_compatible_brand(const uint8_t* data, int len, const char* brand_fourcc); + +// Returns an array of compatible brands. The array is allocated by this function and has to be freed with 'heif_free_list_of_compatible_brands()'. +// The number of entries is returned in out_size. +LIBHEIF_API +struct heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif_brand2** out_brands, int* out_size); + +LIBHEIF_API +void heif_free_list_of_compatible_brands(heif_brand2* brands_list); + + // Returns one of these MIME types: // - image/heic HEIF file using h265 compression // - image/heif HEIF file using any other compression @@ -562,6 +596,10 @@ void heif_depth_representation_info_free(const struct heif_depth_representation_info* info); // Returns true when there is depth_representation_info available +// Note 1: depth_image_id is currently unused because we support only one depth channel per image, but +// you should still provide the correct ID for future compatibility. +// Note 2: Because of an API bug before v1.11.0, the function also works when 'handle' is the handle of the depth image. +// However, you should pass the handle of the main image. Please adapt your code if needed. LIBHEIF_API int heif_image_handle_get_depth_image_representation_info(const struct heif_image_handle* handle, heif_item_id depth_image_id, @@ -601,11 +639,15 @@ int aux_filter, heif_item_id* ids, int count); -// You are responsible to deallocate the returned buffer with free(). +// You are responsible to deallocate the returned buffer with heif_image_handle_free_auxiliary_types(). LIBHEIF_API struct heif_error heif_image_handle_get_auxiliary_type(const struct heif_image_handle* handle, const char** out_type); +LIBHEIF_API +void heif_image_handle_free_auxiliary_types(const struct heif_image_handle* handle, + const char** out_type); + // Get the image handle of an auxiliary image. LIBHEIF_API struct heif_error heif_image_handle_get_auxiliary_image_handle(const struct heif_image_handle* main_image_handle, @@ -1263,6 +1305,14 @@ // version 3 options uint8_t save_two_colr_boxes_when_ICC_and_nclx_available; // default: false + + // version 4 options + + // Set this to the NCLX parameters to be used in the output image or set to NULL + // when the same parameters as in the input image should be used. + struct heif_color_profile_nclx* output_nclx_profile; + + uint8_t macOS_compatibility_workaround_no_nclx_profile; }; LIBHEIF_API diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/heif_colorconversion.cc new/libheif-1.11.0/libheif/heif_colorconversion.cc --- old/libheif-1.10.0/libheif/heif_colorconversion.cc 2020-11-13 16:07:00.000000000 +0100 +++ new/libheif-1.11.0/libheif/heif_colorconversion.cc 2021-01-24 20:56:58.000000000 +0100 @@ -1972,6 +1972,9 @@ if (has_alpha) { out_a = outimg->get_plane(heif_channel_Alpha, &out_a_stride); } + else { + out_a = nullptr; + } RGB_to_YCbCr_coefficients coeffs = RGB_to_YCbCr_coefficients::defaults(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/heif_context.cc new/libheif-1.11.0/libheif/heif_context.cc --- old/libheif-1.10.0/libheif/heif_context.cc 2020-12-15 16:24:08.000000000 +0100 +++ new/libheif-1.11.0/libheif/heif_context.cc 2021-02-01 13:11:01.000000000 +0100 @@ -227,6 +227,7 @@ flags |= 1; } + data[1] = flags; data[2] = (uint8_t) (m_rows - 1); data[3] = (uint8_t) (m_columns - 1); @@ -397,13 +398,10 @@ HeifContext::~HeifContext() { - // Break circular references + // Break circular references between Images (when a faulty input image has circular image references) for (auto& it : m_all_images) { std::shared_ptr<Image> image = it.second; - image->get_thumbnails().clear(); - image->set_alpha_channel(nullptr); - image->set_depth_channel(nullptr); - image->get_aux_images().clear(); + image->clear(); } } @@ -2039,7 +2037,9 @@ image_id = grid_image_id; } } - + else { + m_heif_file->add_ispe_property(image_id, out_image->get_width(), out_image->get_height()); + } // --- choose which color profile to put into 'colr' box @@ -2049,9 +2049,22 @@ m_heif_file->set_color_profile(image_id, icc_profile); } - if (nclx_profile && - (!icc_profile || (options->version >= 3 && - options->save_two_colr_boxes_when_ICC_and_nclx_available))) { + // save nclx profile + + bool save_nclx_profile = (nclx_profile != nullptr); + + // if there is an ICC profile, only save NCLX when we chose to save both profiles + if (icc_profile && !(options->version >= 3 && + options->save_two_colr_boxes_when_ICC_and_nclx_available)) { + save_nclx_profile = false; + } + + // we might have turned off nclx completely because macOS/iOS cannot read it + if (options->version >= 4 && options->macOS_compatibility_workaround_no_nclx_profile) { + save_nclx_profile = false; + } + + if (save_nclx_profile) { m_heif_file->set_color_profile(image_id, nclx_profile); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/heif_context.h new/libheif-1.11.0/libheif/heif_context.h --- old/libheif-1.10.0/libheif/heif_context.h 2020-12-15 14:54:48.000000000 +0100 +++ new/libheif-1.11.0/libheif/heif_context.h 2021-02-01 13:20:52.000000000 +0100 @@ -91,6 +91,13 @@ ~Image(); + void clear() { + m_thumbnails.clear(); + m_alpha_channel.reset(); + m_depth_channel.reset(); + m_aux_images.clear(); + } + void set_resolution(int w, int h) { m_width = w; @@ -142,7 +149,7 @@ bool is_thumbnail() const { return m_is_thumbnail; } - std::vector<std::shared_ptr<Image>> get_thumbnails() const { return m_thumbnails; } + const std::vector<std::shared_ptr<Image>>& get_thumbnails() const { return m_thumbnails; } // --- alpha channel @@ -158,7 +165,7 @@ bool is_alpha_channel() const { return m_is_alpha_channel; } - std::shared_ptr<Image> get_alpha_channel() const { return m_alpha_channel; } + const std::shared_ptr<Image>& get_alpha_channel() const { return m_alpha_channel; } // --- depth channel @@ -173,7 +180,7 @@ bool is_depth_channel() const { return m_is_depth_channel; } - std::shared_ptr<Image> get_depth_channel() const { return m_depth_channel; } + const std::shared_ptr<Image>& get_depth_channel() const { return m_depth_channel; } void set_depth_representation_info(struct heif_depth_representation_info& info) @@ -206,7 +213,7 @@ bool is_aux_image() const { return m_is_aux_image; } - std::string get_aux_type() const { return m_aux_image_type; } + const std::string& get_aux_type() const { return m_aux_image_type; } std::vector<std::shared_ptr<Image>> get_aux_images(int aux_image_filter = 0) const { @@ -241,7 +248,7 @@ m_metadata.push_back(std::move(metadata)); } - std::vector<std::shared_ptr<ImageMetadata>> get_metadata() const { return m_metadata; } + const std::vector<std::shared_ptr<ImageMetadata>>& get_metadata() const { return m_metadata; } // === writing === @@ -253,9 +260,9 @@ const struct heif_encoding_options* options, enum heif_image_input_class input_class); - std::shared_ptr<const color_profile_nclx> get_color_profile_nclx() const { return m_color_profile_nclx; } + const std::shared_ptr<const color_profile_nclx>& get_color_profile_nclx() const { return m_color_profile_nclx; } - std::shared_ptr<const color_profile_raw> get_color_profile_icc() const { return m_color_profile_icc; } + const std::shared_ptr<const color_profile_raw>& get_color_profile_icc() const { return m_color_profile_icc; } void set_color_profile(std::shared_ptr<const color_profile> profile) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/libheif/heif_version.h new/libheif-1.11.0/libheif/heif_version.h --- old/libheif-1.10.0/libheif/heif_version.h 2020-12-16 15:05:22.000000000 +0100 +++ new/libheif-1.11.0/libheif/heif_version.h 2021-02-02 09:19:54.000000000 +0100 @@ -28,9 +28,9 @@ #define LIBHEIF_HEIF_VERSION_H /* Numeric representation of the version */ -#define LIBHEIF_NUMERIC_VERSION ((1<<24) | (10<<16) | (0<<8) | 0) +#define LIBHEIF_NUMERIC_VERSION ((1<<24) | (11<<16) | (0<<8) | 0) /* Version string */ -#define LIBHEIF_VERSION "1.10.0" +#define LIBHEIF_VERSION "1.11.0" #endif // LIBHEIF_HEIF_VERSION_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/m4/libtool.m4 new/libheif-1.11.0/m4/libtool.m4 --- old/libheif-1.10.0/m4/libtool.m4 2020-12-16 15:05:10.000000000 +0100 +++ new/libheif-1.11.0/m4/libtool.m4 2021-02-02 09:19:45.000000000 +0100 @@ -1041,8 +1041,8 @@ _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF @@ -1492,7 +1492,7 @@ m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cru} +: ${AR_FLAGS=cr} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) @@ -4063,7 +4063,8 @@ if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4703,6 +4704,12 @@ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -6438,7 +6445,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -6813,7 +6820,7 @@ # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6878,7 +6885,7 @@ # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -7217,7 +7224,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -7301,7 +7308,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7312,7 +7319,7 @@ # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/missing new/libheif-1.11.0/missing --- old/libheif-1.10.0/missing 2020-12-16 15:05:13.000000000 +0100 +++ new/libheif-1.11.0/missing 2021-02-02 09:19:47.000000000 +0100 @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2013-10-28.13; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard <[email protected]>, 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ exit $st fi -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software program_details () { @@ -207,9 +207,9 @@ exit $st # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/scripts/cpplint.py new/libheif-1.11.0/scripts/cpplint.py --- old/libheif-1.10.0/scripts/cpplint.py 2019-02-02 18:08:35.000000000 +0100 +++ new/libheif-1.11.0/scripts/cpplint.py 2021-02-01 12:45:05.000000000 +0100 @@ -55,7 +55,7 @@ import unicodedata -_USAGE = """ +_USAGE = r""" Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] [--counting=total|toplevel|detailed] [--root=subdir] [--linelength=digits] @@ -188,6 +188,7 @@ 'build/header_guard', 'build/include', 'build/include_alpha', + 'build/include_directory', 'build/include_order', 'build/include_what_you_use', 'build/namespaces', @@ -368,6 +369,7 @@ 'stdexcept', 'streambuf', 'string', + 'string_view', 'strstream', 'system_error', 'thread', @@ -423,8 +425,8 @@ r')$') -# These headers are excluded from [build/include] and [build/include_order] -# checks: +# These headers are excluded from [build/include], [build/include_directory], +# and [build/include_order] checks: # - Anything not following google file name conventions (containing an # uppercase character, such as Python.h or nsStringAPI.h, for example). # - Lua headers. @@ -908,7 +910,7 @@ def PrintErrorCounts(self): """Print a summary of errors by category, and the total.""" - for category, count in self.errors_by_category.iteritems(): + for category, count in self.errors_by_category.items(): sys.stderr.write('Category \'%s\' errors found: %d\n' % (category, count)) sys.stderr.write('Total errors found: %d\n' % self.error_count) @@ -1057,7 +1059,7 @@ return os.path.abspath(self._filename).replace('\\', '/') def RepositoryName(self): - """FullName after removing the local path to the repository. + r"""FullName after removing the local path to the repository. If we have a real absolute path name here we can try to do something smart: detecting the root of the checkout and truncating /path/to/checkout from @@ -1480,7 +1482,7 @@ On finding an unclosed expression: (-1, None) Otherwise: (-1, new stack at end of this line) """ - for i in xrange(startpos, len(line)): + for i in range(startpos, len(line)): char = line[i] if char in '([{': # Found start of parenthesized expression, push to expression stack @@ -1709,7 +1711,7 @@ # We'll say it should occur by line 10. Don't forget there's a # dummy line at the front. - for line in xrange(1, min(len(lines), 11)): + for line in range(1, min(len(lines), 11)): if re.search(r'Copyright', lines[line], re.I): break else: # means no copyright line was found error(filename, 0, 'legal/copyright', 5, @@ -1837,7 +1839,7 @@ # contain any "//" comments at all, it could be that the compiler # only wants "/**/" comments, look for those instead. no_single_line_comments = True - for i in xrange(1, len(raw_lines) - 1): + for i in range(1, len(raw_lines) - 1): line = raw_lines[i] if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): no_single_line_comments = False @@ -2178,7 +2180,7 @@ # If there is a DISALLOW macro, it should appear near the end of # the class. seen_last_thing_in_class = False - for i in xrange(linenum - 1, self.starting_linenum, -1): + for i in range(linenum - 1, self.starting_linenum, -1): match = Search( r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + self.name + r'\)', @@ -2530,7 +2532,7 @@ # }; class_decl_match = Match( r'^(\s*(?:template\s*<[\w\s<>,:]*>\s*)?' - r'(class|struct)\s+(?:[A-Z_]+\s+)*(\w+(?:::\w+)*))' + r'(class|struct)\s+(?:[A-Z0-9_]+\s+)*(\w+(?:::\w+)*))' r'(.*)$', line) if (class_decl_match and (not self.stack or self.stack[-1].open_parentheses == 0)): @@ -2867,7 +2869,7 @@ 'Extra space after (') if (Search(r'\w\s+\(', fncall) and not Search(r'_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(', fncall) and - not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and + not Search(r'#\s*define|typedef|__except|using\s+\w+\s*=', fncall) and not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and not Search(r'\bcase\s+\(', fncall)): # TODO(unknown): Space after an operator function seem to be a common @@ -2955,12 +2957,12 @@ # ignore it, unless it's TEST or TEST_F. function_name = match_result.group(1).split()[-1] if function_name == 'TEST' or function_name == 'TEST_F' or ( - not Match(r'[A-Z_]+$', function_name)): + not Match(r'[A-Z_0-9]+$', function_name)): starting_func = True if starting_func: body_found = False - for start_linenum in xrange(linenum, clean_lines.NumLines()): + for start_linenum in range(linenum, clean_lines.NumLines()): start_line = lines[start_linenum] joined_line += ' ' + start_line.lstrip() if Search(r'(;|})', start_line): # Declarations and trivial functions @@ -3160,8 +3162,11 @@ line = clean_lines.elided[linenum] # You shouldn't have spaces before your brackets, except maybe after - # 'delete []' or 'return []() {};' - if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line): + # 'delete []' or 'return []() {};', or in the case of c++ attributes + # like 'class [[clang::lto_visibility_public]] MyClass'. + if (Search(r'\w\s+\[', line) + and not Search(r'(?:delete|return)\s+\[', line) + and not Search(r'\s+\[\[', line)): error(filename, linenum, 'whitespace/braces', 5, 'Extra space before [') @@ -3417,7 +3422,7 @@ continue # Look for typename in the specified range - for i in xrange(first_line, last_line + 1, 1): + for i in range(first_line, last_line + 1, 1): if Search(typename_pattern, clean_lines.elided[i]): return True block_index -= 1 @@ -3481,7 +3486,7 @@ trailing_text = '' if endpos > -1: trailing_text = endline[endpos:] - for offset in xrange(endlinenum + 1, + for offset in range(endlinenum + 1, min(endlinenum + 3, clean_lines.NumLines() - 1)): trailing_text += clean_lines.elided[offset] # We also suppress warnings for `uint64_t{expression}` etc., as the style @@ -3743,8 +3748,8 @@ # Block bodies should not be followed by a semicolon. Due to C++11 # brace initialization, there are more places where semicolons are - # required than not, so we use a whitelist approach to check these - # rather than a blacklist. These are the places where "};" should + # required than not, so we use an allowlist approach to check these + # rather than a blocklist. These are the places where "};" should # be replaced by just "}": # 1. Some flavor of block following closing parenthesis: # for (;;) {}; @@ -3801,11 +3806,11 @@ # - INTERFACE_DEF # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: # - # We implement a whitelist of safe macros instead of a blacklist of + # We implement an allowlist of safe macros instead of a blocklist of # unsafe macros, even though the latter appears less frequently in - # google code and would have been easier to implement. This is because - # the downside for getting the whitelist wrong means some extra - # semicolons, while the downside for getting the blacklist wrong + # google code and would have been easier to implement. This is because + # the downside for getting the allowlist wrong means some extra + # semicolons, while the downside for getting the blocklist wrong # would result in compile errors. # # In addition to macros, we also don't want to warn on @@ -4027,7 +4032,7 @@ expression = lines[linenum][start_pos + 1:end_pos - 1] else: expression = lines[linenum][start_pos + 1:] - for i in xrange(linenum + 1, end_line): + for i in range(linenum + 1, end_line): expression += lines[i] expression += last_line[0:end_pos - 1] @@ -4155,7 +4160,7 @@ The width of the line in column positions, accounting for Unicode combining characters and wide characters. """ - if isinstance(line, unicode): + if sys.version_info == 2 and isinstance(line, unicode): width = 0 for uc in unicodedata.normalize('NFC', line): if unicodedata.east_asian_width(uc) in ('W', 'F'): @@ -4408,7 +4413,7 @@ # naming convention but not the include convention. match = Match(r'#include\s*"([^/]+\.h)"', line) if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)): - error(filename, linenum, 'build/include', 4, + error(filename, linenum, 'build/include_directory', 4, 'Include the directory when naming .h files') # we shouldn't include a file more than once. actually, there are a @@ -4481,7 +4486,7 @@ # Give opening punctuations to get the matching close-punctuations. matching_punctuation = {'(': ')', '{': '}', '[': ']'} - closing_punctuation = set(matching_punctuation.itervalues()) + closing_punctuation = set(matching_punctuation.values()) # Find the position to start extracting text. match = re.search(start_pattern, text, re.M) @@ -4665,6 +4670,9 @@ if Search(r'sizeof\(.+\)', tok): continue if Search(r'arraysize\(\w+\)', tok): continue + if Search(r'base::size\(.+\)', tok): continue + if Search(r'std::size\(.+\)', tok): continue + if Search(r'std::extent<.+>', tok): continue tok = tok.lstrip('(') tok = tok.rstrip(')') @@ -4800,7 +4808,7 @@ virt-specifier. """ # Scan back a few lines for start of current function - for i in xrange(linenum, max(-1, linenum - 10), -1): + for i in range(linenum, max(-1, linenum - 10), -1): match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) if match: # Look for "override" after the matching closing parenthesis @@ -4821,7 +4829,7 @@ True if current line contains an out-of-line method definition. """ # Scan back a few lines for start of current function - for i in xrange(linenum, max(-1, linenum - 10), -1): + for i in range(linenum, max(-1, linenum - 10), -1): if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]): return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None return False @@ -4837,7 +4845,7 @@ True if current line appears to be inside constructor initializer list, False otherwise. """ - for i in xrange(linenum, 1, -1): + for i in range(linenum, 1, -1): line = clean_lines.elided[i] if i == linenum: remove_function_body = Match(r'^(.*)\{\s*$', line) @@ -4938,7 +4946,7 @@ # Found the matching < on an earlier line, collect all # pieces up to current line. line = '' - for i in xrange(startline, linenum + 1): + for i in range(startline, linenum + 1): line += clean_lines.elided[i].strip() # Check for non-const references in function parameters. A single '&' may @@ -4962,7 +4970,7 @@ # appear inside the second set of parentheses on the current line as # opposed to the first set. if linenum > 0: - for i in xrange(linenum - 1, max(0, linenum - 10), -1): + for i in range(linenum - 1, max(0, linenum - 10), -1): previous_line = clean_lines.elided[i] if not Search(r'[),]\s*$', previous_line): break @@ -4983,19 +4991,19 @@ # # We also accept & in static_assert, which looks like a function but # it's actually a declaration expression. - whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|' + allowlisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|' r'operator\s*[<>][<>]|' r'static_assert|COMPILE_ASSERT' r')\s*\(') - if Search(whitelisted_functions, line): + if Search(allowlisted_functions, line): return elif not Search(r'\S+\([^)]*$', line): - # Don't see a whitelisted function on this line. Actually we + # Don't see an allowlisted function on this line. Actually we # didn't see any function name on this line, so this is likely a # multi-line parameter list. Try a bit harder to catch this case. - for i in xrange(2): + for i in range(2): if (linenum > i and - Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): + Search(allowlisted_functions, clean_lines.elided[linenum - i - 1])): return decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body @@ -5156,7 +5164,7 @@ # Try expanding current context to see if we one level of # parentheses inside a macro. if linenum > 0: - for i in xrange(linenum - 1, max(0, linenum - 5), -1): + for i in range(linenum - 1, max(0, linenum - 5), -1): context = clean_lines.elided[i] + context if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): return False @@ -5375,7 +5383,7 @@ required = {} # A map of header name to linenumber and the template entity. # Example of required: { '<functional>': (1219, 'less<>') } - for linenum in xrange(clean_lines.NumLines()): + for linenum in range(clean_lines.NumLines()): line = clean_lines.elided[linenum] if not line or line[0] == '#': continue @@ -5429,7 +5437,7 @@ # include_dict is modified during iteration, so we iterate over a copy of # the keys. - header_keys = include_dict.keys() + header_keys = list(include_dict.keys()) for header in header_keys: (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) fullpath = common_path + header @@ -5511,7 +5519,7 @@ end_col = -1 end_line = -1 start_col = len(virtual.group(2)) - for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): + for start_line in range(linenum, min(linenum + 3, clean_lines.NumLines())): line = clean_lines.elided[start_line][start_col:] parameter_list = Match(r'^([^(]*)\(', line) if parameter_list: @@ -5526,7 +5534,7 @@ # Look for "override" or "final" after the parameter list # (possibly on the next few lines). - for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())): + for i in range(end_line, min(end_line + 3, clean_lines.NumLines())): line = clean_lines.elided[i][end_col:] match = Search(r'\b(override|final)\b', line) if match: @@ -5783,7 +5791,7 @@ if file_extension == 'h': CheckForHeaderGuard(filename, clean_lines, error) - for line in xrange(clean_lines.NumLines()): + for line in range(clean_lines.NumLines()): ProcessLine(filename, file_extension, clean_lines, line, include_state, function_state, nesting_state, error, extra_check_functions) @@ -6001,14 +6009,16 @@ """ try: (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', + 'headers=', # We understand but ignore headers. 'counting=', 'filter=', 'root=', 'linelength=', 'extensions=', - 'project_root=']) - except getopt.GetoptError: - PrintUsage('Invalid arguments.') + 'project_root=', + 'repository=']) + except getopt.GetoptError as e: + PrintUsage('Invalid arguments: {}'.format(e)) verbosity = _VerboseLevel() output_format = _OutputFormat() @@ -6035,7 +6045,7 @@ elif opt == '--root': global _root _root = val - elif opt == '--project_root': + elif opt == '--project_root' or opt == "--repository": global _project_root _project_root = val if not os.path.isabs(_project_root): @@ -6069,10 +6079,11 @@ # Change stderr to write with replacement characters so we don't die # if we try to print something containing non-ASCII characters. - sys.stderr = codecs.StreamReaderWriter(sys.stderr, - codecs.getreader('utf8'), - codecs.getwriter('utf8'), - 'replace') + # We use sys.stderr.buffer in Python 3, since StreamReaderWriter writes bytes + # to the specified stream. + sys.stderr = codecs.StreamReaderWriter( + getattr(sys.stderr, 'buffer', sys.stderr), + codecs.getreader('utf8'), codecs.getwriter('utf8'), 'replace') _cpplint_state.ResetErrorCounts() for filename in filenames: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/scripts/pre-commit.hook new/libheif-1.11.0/scripts/pre-commit.hook --- old/libheif-1.10.0/scripts/pre-commit.hook 2019-02-27 02:10:04.000000000 +0100 +++ new/libheif-1.11.0/scripts/pre-commit.hook 2021-02-01 12:45:05.000000000 +0100 @@ -28,12 +28,25 @@ CPPLINT="$ROOT/cpplint.py" fi +PYTHON=$(which python || true) +if [ -z "$PYTHON" ]; then + PYTHON=$(which python3 || true) +fi + # Run cpplint against changed C/C++ files and check if all enums from the API # are also updated in the Emscripten/Go files. check_c_enums= check_go_enums= +logged_python= for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep -E "\.cc$|\.h$|\.c$"` ; do - "$CPPLINT" "$file" + if [ -z "$PYTHON" ]; then + if [ -z "$logged_python" ]; then + echo "WARNING: Could not find valid Python interpreter to run cpplint, skipping checks..." + logged_python=1 + fi + else + "$PYTHON" "$CPPLINT" "$file" + fi if [ "$file" = "libheif/heif.h" ] ; then check_c_enums=1 check_go_enums=1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libheif-1.10.0/scripts/run-ci.sh new/libheif-1.11.0/scripts/run-ci.sh --- old/libheif-1.10.0/scripts/run-ci.sh 2020-11-12 23:19:08.000000000 +0100 +++ new/libheif-1.11.0/scripts/run-ci.sh 2021-02-01 12:45:05.000000000 +0100 @@ -44,8 +44,17 @@ fi if [ ! -z "$CPPLINT" ]; then - echo "Running cpplint ..." - find -name "*.c" -o -name "*.cc" -o -name "*.h" | sort | xargs ./scripts/cpplint.py --extensions=c,cc,h + PYTHON=$(which python || true) + if [ -z "$PYTHON" ]; then + PYTHON=$(which python3 || true) + if [ -z "$PYTHON" ]; then + echo "Could not find valid Python interpreter to run cpplint." + echo "Make sure you have either python or python3 in your PATH." + exit 1 + fi + fi + echo "Running cpplint with $PYTHON ..." + find -name "*.c" -o -name "*.cc" -o -name "*.h" | sort | xargs "$PYTHON" ./scripts/cpplint.py --extensions=c,cc,h ./scripts/check-emscripten-enums.sh ./scripts/check-go-enums.sh
