diff -Nru exiv2-0.27.5/appveyor_mingw_cygwin.yml exiv2-0.27.6/appveyor_mingw_cygwin.yml --- exiv2-0.27.5/appveyor_mingw_cygwin.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/appveyor_mingw_cygwin.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -init: - - echo %PYTHON% - -environment: - PYTHON: "C:/Python37-x64" - - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD: MINGW64 - INTEGRATION_TESTS: 1 - ARCHITECTURE: x86_64 - UNIT_TESTS: 1 - WEBREADY: False - WARNINGS_AS_ERRORS: ON - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD: CYGWIN64 - INTEGRATION_TESTS: 1 - ARCHITECTURE: x86_64 - UNIT_TESTS: 1 - WEBREADY: False - WARNINGS_AS_ERRORS: ON - -shallow_clone: true - -install: - - echo %APPVEYOR_BUILD_FOLDER% - - if "%BUILD%"=="MINGW64" set "PATH=c:\msys64\mingw64\bin;c:\msys64\usr\bin;c:\msys64\usr\local\bin;" - - if "%BUILD%"=="MINGW64" C:\msys64\usr\bin\bash -c "python -m pip install --upgrade pip;pip3.exe install lxml ; for i in base-devel git coreutils dos2unix tar diffutils make \ - mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb \ - mingw-w64-x86_64-cmake mingw-w64-x86_64-gettext mingw-w64-x86_64-python3 \ - mingw-w64-x86_64-libexpat mingw-w64-x86_64-libiconv mingw-w64-x86_64-zlib \ - mingw-w64-x86_64-gtest ; do (echo y | pacman -S $i) ; done - - cd %APPVEYOR_BUILD_FOLDER% - - if "%BUILD%"=="CYGWIN64" set "PATH=c:\cygwin64\usr\local\bin;c:\cygwin64\bin;c:\cygwin64\usr\bin;c:\cygwin64\usr\sbin;" - - if "%BUILD%"=="CYGWIN64" C:\cygwin64\bin\bash -c "wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg ; chmod +x apt-cyg; mv apt-cyg /usr/local/bin" - - if "%BUILD%"=="CYGWIN64" C:\cygwin64\bin\bash -c "apt-cyg install cmake zlib-devel libexpat-devel libxml2-devel libxslt-devel python38 python38-pip python38-libxml2" - - if "%BUILD%"=="CYGWIN64" C:\cygwin64\bin\bash -c "/usr/bin/python3.8.exe -m pip install --upgrade pip" - -build_script: - - cmd: set CMD=mkdir -p build - - cmd: set CMD=%CMD%; cd build - - cmd: set CMD=%CMD%; cmake .. -G 'Unix Makefiles' -DCMAKE_CXX_STANDARD=98 -DCMAKE_CXX_FLAGS=-Wno-deprecated - - cmd: set CMD=%CMD%; cmake --build . --config Release - - cmd: rem echo %CMD% - - cd %APPVEYOR_BUILD_FOLDER% - - cmd: if "%BUILD%"=="MINGW64" C:\msys64\usr\bin\bash -c "%CMD%" - - cmd: set CMD=which python3 python - - cmd: set CMD=%CMD%; python --version - - cmd: set CMD=%CMD%; build/bin/exiv2 --verbose --version; pwd ; ls -l - - cmd: set CMD=%CMD%; cd build ; cmake --build . --config Release --target python_tests - - cmd: echo %CMD% - - cd %APPVEYOR_BUILD_FOLDER% - - cmd: if "%BUILD%"=="MINGW64" C:\msys64\usr\bin\bash -c "%CMD%" - - cmd: set "PATH=c:\cygwin64\usr\local\bin;c:\cygwin64\bin;c:\cygwin64\usr\bin;c:\cygwin64\usr\sbin;" - - cmd: set CMD=rm -rf build - - cmd: set CMD=%CMD%; mkdir -p build - - cmd: set CMD=%CMD%; cd build - - cmd: set CMD=%CMD%;cmake .. -DCMAKE_CXX_STANDARD=98 -DCMAKE_CXX_FLAGS=-Wno-deprecated - - cmd: set CMD=%CMD%; make - - cmd: set CMD=%CMD%; make python_tests - - cmd: echo %CMD% - - cd %APPVEYOR_BUILD_FOLDER% - - cmd: if "%BUILD%"=="CYGWIN64" C:\cygwin64\bin\bash -c "%CMD%" - diff -Nru exiv2-0.27.5/appveyor.yml exiv2-0.27.6/appveyor.yml --- exiv2-0.27.5/appveyor.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -init: - - echo %PYTHON% - -environment: - PYTHON: "C:/Python37-x64" - - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - CMAKE_GENERATOR: Ninja - INTEGRATION_TESTS: 1 - VS_COMPILER_VERSION: 16 - VCVARS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat - ARCHITECTURE: x86_64 - UNIT_TESTS: 1 - WEBREADY: False - WARNINGS_AS_ERRORS: ON - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - CMAKE_GENERATOR: Ninja - INTEGRATION_TESTS: 1 - VS_COMPILER_VERSION: 15 - VCVARS: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat - ARCHITECTURE: x86_64 - UNIT_TESTS: 1 - WEBREADY: False - WARNINGS_AS_ERRORS: ON - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - CMAKE_GENERATOR: Ninja - INTEGRATION_TESTS: 1 - VS_COMPILER_VERSION: 14 - VCVARS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat - ARCHITECTURE: x86_64 - UNIT_TESTS: 1 - WEBREADY: False - WARNINGS_AS_ERRORS: ON - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - CMAKE_GENERATOR: Ninja - INTEGRATION_TESTS: 0 - VS_COMPILER_VERSION: 12 - VCVARS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat - ARCHITECTURE: x86_64 - UNIT_TESTS: 0 - WEBREADY: False - WARNINGS_AS_ERRORS: OFF - -shallow_clone: true - -install: - - set PATH=%PATH%;%PYTHON%/Scripts/ - - echo %APPVEYOR_BUILD_FOLDER% - - mkdir C:\projects\deps - - cd C:\projects\deps - - appveyor DownloadFile https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-win.zip -FileName ninja.zip - - 7z x ninja.zip -oC:\projects\deps\ninja > nul - - set PATH=C:\projects\deps\ninja;%PATH% - - ninja --version - - python -m pip install --upgrade pip - - pip3.exe install conan==1.30.2 - - pip3.exe install lxml - - cd %APPVEYOR_BUILD_FOLDER% - -before_build: - - cmd: conan config install https://github.com/conan-io/conanclientcert.git - - cmd: conan remote list - - cmd: conan config set storage.path=c:\Users\appveyor\conanCache - - cmd: conan profile new --detect default - - cmd: conan profile update settings.compiler.version=%VS_COMPILER_VERSION% default - - cmd: conan profile update settings.arch=%ARCHITECTURE% default - - cmd: conan profile update settings.arch_build=%ARCHITECTURE% default - - cmd: cat c:\Users\appveyor\.conan\conan.conf - -build_script: - - cmd: md build - - cmd: cd build - - cmd: call "%VCVARS%" x86_amd64 - - cmd: conan --version - - cmd: conan install .. -o webready=%WEBREADY% --build missing - - cmd: echo %CMAKE_GENERATOR% - - cmd: cmake -G "%CMAKE_GENERATOR%" -DEXIV2_TEAM_WARNINGS_AS_ERRORS=%WARNINGS_AS_ERRORS% -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_NLS=OFF -DEXIV2_ENABLE_PNG=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_ENABLE_WEBREADY=%WEBREADY% -DEXIV2_BUILD_UNIT_TESTS=%UNIT_TESTS% -DCMAKE_INSTALL_PREFIX=install .. - - cmd: cmake --build . --config Release - - cmd: cmake --build . --config Release --target install - - cmd: cd bin - - cmd: if %UNIT_TESTS% == 1 unit_tests.exe - - cmd: cd ../../tests/ - - cmd: if %INTEGRATION_TESTS% == 1 %PYTHON%/python.exe runner.py -v - - cmd: cd ../build/bin - - cmd: exiv2 --version --verbose diff -Nru exiv2-0.27.5/ci/install.sh exiv2-0.27.6/ci/install.sh --- exiv2-0.27.5/ci/install.sh 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/ci/install.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -#!/bin/bash -set -e # Enables cheking of return values from each command -set -x # Prints every command - -# This file is only used from Travis CI, where the only Linux distro used is Ubuntu - -python3 --version - -if [[ "$(uname -s)" == 'Linux' ]]; then - sudo apt-get update - - sudo apt-get install cmake zlib1g-dev libssh-dev python3-pip libxml2-utils - - if [ -n "$WITH_VALGRIND" ]; then - # https://travis-ci.community/t/clang-10-was-recently-broken-on-linux-unmet-dependencies-for-clang-10-clang-tidy-10-valgrind/11527 - sudo apt-get install -yq --allow-downgrades libc6=2.31-0ubuntu9.2 libc6-dev=2.31-0ubuntu9.2 - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --allow-downgrades --allow-remove-essential --allow-change-held-packages install valgrind - fi - sudo pip3 install virtualenv - virtualenv conan - source conan/bin/activate - pip install conan==1.30.2 - pip install codecov - pip install lxml -else - sudo pip3 install virtualenv - virtualenv conan - source conan/bin/activate - pip3 install conan==1.30.2 - pip3 install codecov - pip3 install lxml -fi - -conan --version -conan config install https://github.com/conan-io/conanclientcert.git -conan config set storage.path=~/conanData -conan profile new default --detect - -if [[ "$(uname -s)" == 'Linux' ]]; then - conan profile update settings.compiler.libcxx=libstdc++11 default -fi - diff -Nru exiv2-0.27.5/ci/run.sh exiv2-0.27.6/ci/run.sh --- exiv2-0.27.5/ci/run.sh 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/ci/run.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -#!/bin/bash - -set -e -set -x - -source conan/bin/activate - -if [[ "$(uname -s)" == 'Linux' ]]; then - if [ "$CC" == "clang" ]; then - # clang + Ubuntu don't like to run with UBSAN, but ASAN works - export CMAKE_OPTIONS="$COMMON_CMAKE_OPTIONS" - elif [ -n "$WITH_VALGRIND" ]; then - export EXIV2_VALGRIND="valgrind --quiet" - else - export CMAKE_OPTIONS="$COMMON_CMAKE_OPTIONS -DEXIV2_TEAM_USE_SANITIZERS=OFF" - fi -else - export CMAKE_OPTIONS="$COMMON_CMAKE_OPTIONS -DEXIV2_TEAM_USE_SANITIZERS=OFF" -fi -CMAKE_OPTIONS="$COMMON_CMAKE_OPTIONS -DCMAKE_CXX_FLAGS=-Wno-deprecated -DCMAKE_CXX_STANDARD=98 -DCMAKE_BUILD_TYPE=$BUILD_TYPE" - -mkdir build -cd build -conan install .. -o webready=True --build missing -cmake ${CMAKE_OPTIONS} .. -make -j -make tests -make install - -# Check for detecting issues with the installation of headers -if [ `ls install/include/exiv2/ | wc -l` > 10 ]; then - echo Headers installed correctly -else - echo There was some problem with the installation of the public headers - exit 1 -fi - -if [ -n "$COVERAGE" ]; then - bash <(curl -s https://codecov.io/bash) -fi - diff -Nru exiv2-0.27.5/ci/test_build.py exiv2-0.27.6/ci/test_build.py --- exiv2-0.27.5/ci/test_build.py 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/ci/test_build.py 2023-01-18 21:57:53.000000000 +0000 @@ -41,7 +41,7 @@ os.mkdir(cwd) cmake = "{cmake_bin} {!s} -DCMAKE_BUILD_TYPE={build_type} -DCMAKE_CXX_FLAGS=-Wno-deprecated " \ - "-DBUILD_SHARED_LIBS={lib_type} -DEXIV2_BUILD_UNIT_TESTS={tests} -DCMAKE_CXX_STANDARD=98 "\ + "-DBUILD_SHARED_LIBS={lib_type} -DEXIV2_BUILD_UNIT_TESTS={tests} "\ "../..".format( cmake_options, cmake_bin=cmake_bin, build_type=build_type, lib_type=lib_type, tests="ON" if tests else "OFF" diff -Nru exiv2-0.27.5/cmake/findDependencies.cmake exiv2-0.27.6/cmake/findDependencies.cmake --- exiv2-0.27.5/cmake/findDependencies.cmake 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/cmake/findDependencies.cmake 2023-01-18 21:57:53.000000000 +0000 @@ -1,17 +1,23 @@ # set include path for FindXXX.cmake files set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") +if (APPLE) + # On Apple, we use the conan cmake_paths generator + if (EXISTS ${CMAKE_BINARY_DIR}/conan_paths.cmake) + include(${CMAKE_BINARY_DIR}/conan_paths.cmake) + endif() +else() + # Otherwise, we rely on the conan cmake_find_package generator + list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) + list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}) +endif() + # don't use Frameworks on the Mac (#966) if (APPLE) set(CMAKE_FIND_FRAMEWORK NEVER) endif() -# Check if the conan file exist to find the dependencies -if (EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) - set(USING_CONAN ON) - include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) - conan_basic_setup(NO_OUTPUT_DIRS KEEP_RPATHS TARGETS) -endif() +find_package (Python3 COMPONENTS Interpreter) find_package(Threads REQUIRED) diff -Nru exiv2-0.27.5/cmake/mainSetup.cmake exiv2-0.27.6/cmake/mainSetup.cmake --- exiv2-0.27.5/cmake/mainSetup.cmake 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/cmake/mainSetup.cmake 2023-01-18 21:57:53.000000000 +0000 @@ -6,6 +6,7 @@ include(GenerateExportHeader) include(CMakeDependentOption) include(cmake/JoinPaths.cmake) +include(CTest) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -19,6 +20,10 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) endif() +if (NOT CMAKE_CXX_STANDARD) + set (CMAKE_CXX_STANDARD 98) +endif() + if (UNIX) if (APPLE) set(CMAKE_MACOSX_RPATH ON) diff -Nru exiv2-0.27.5/CMakeLists.txt exiv2-0.27.6/CMakeLists.txt --- exiv2-0.27.5/CMakeLists.txt 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/CMakeLists.txt 2023-01-18 21:57:53.000000000 +0000 @@ -1,15 +1,15 @@ -cmake_minimum_required( VERSION 3.3.2 ) +# Minimum version imposed by Debian:9 +cmake_minimum_required( VERSION 3.7.2 ) -project(exiv2 # use TWEAK to categorize the build - VERSION 0.27.5 # 0.27.5 = GM (tagged and released) - # 0.27.5.3 = RC3 - # 0.27.5.9 = 27.4.9 Development - # 0.27.5.00 = GM Preview - # 0.27.5.3 = RC3 (tagged and released) - # 0.27.5.30 = RC2 Preview - # 0.27.5.39 = RC2 Development +project(exiv2 + VERSION 0.27.6 LANGUAGES CXX ) + +if(NOT CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Release) +endif() + include(cmake/mainSetup.cmake REQUIRED) # options and their default values @@ -87,17 +87,8 @@ if( EXIV2_BUILD_UNIT_TESTS ) add_subdirectory ( unitTests ) - add_custom_target(unit_test - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/unit_test.py - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests" - ) endif() -add_custom_target(version_test - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/version_test.py - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests" -) - if( EXIV2_BUILD_FUZZ_TESTS ) if ((NOT COMPILER_IS_CLANG) OR (NOT EXIV2_TEAM_USE_SANITIZERS)) message(FATAL_ERROR "You need to build with Clang and sanitizers for the fuzzers to work. " @@ -107,35 +98,26 @@ endif() if( EXIV2_BUILD_SAMPLES ) - ## - # tests - if( EXIV2_BUILD_UNIT_TESTS ) - add_custom_target(tests - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/unit_test.py - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/testcases.py --verbose - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/version_test.py - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests" + add_subdirectory( samples ) + get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS) + if (Python3_Interpreter_FOUND) + add_test(NAME bashTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bash_tests + ) + add_test(NAME bugfixTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bugfixes + ) + add_test(NAME tiffTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose tiff_test ) - else() - add_custom_target(tests - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/testcases.py --verbose - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/version_test.py - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests" + add_test(NAME versionTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bash_tests/version_test.py ) endif() - add_custom_target(python_tests - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests" - ) - add_custom_target(bash_tests - COMMAND env EXIV2_BINDIR="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" python3 runner.py bash_tests/testcases.py --verbose - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/tests" - ) - add_subdirectory( samples ) - get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS) - add_dependencies(tests exiv2lib exiv2 ${SAMPLES}) endif() if( EXIV2_ENABLE_NLS ) diff -Nru exiv2-0.27.5/conanfile.py exiv2-0.27.6/conanfile.py --- exiv2-0.27.5/conanfile.py 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/conanfile.py 2023-01-18 21:57:53.000000000 +0000 @@ -4,7 +4,7 @@ class Exiv2Conan(ConanFile): settings = 'os', 'compiler', 'build_type', 'arch' - generators = 'cmake' + generators = 'cmake_find_package', 'cmake_paths' options = {'unitTests': [True, False], 'xmp': [True, False], 'iconv': [True, False], @@ -17,38 +17,27 @@ ) def configure(self): - self.options['libcurl'].shared = False - self.options['libcurl'].with_openssl = True - self.options['gtest'].shared = True + self.options['libcurl'].shared = True + self.options['gtest'].shared = False def requirements(self): - self.requires('zlib/1.2.11@conan/stable') + self.requires('zlib/1.2.12') if os_info.is_windows and self.options.iconv: - self.requires('libiconv/1.15@bincrafters/stable') + self.requires('libiconv/1.16') if self.options.unitTests: - if self.settings.compiler == "Visual Studio" and Version(self.settings.compiler.version.value) <= "12": - self.requires('gtest/1.8.0@bincrafters/stable') - else: - self.requires('gtest/1.8.1@bincrafters/stable') - - if self.options.webready and not os_info.is_macos: - # Note: This difference in versions is just due to a combination of corner cases in the - # recipes and the OS & compiler versions used in Travis and AppVeyor. In normal cases we - # could use any of the versions.Also note that the issue was not with libcurl but with - # libopenssl (a transitive dependency) - if os_info.is_windows: - self.requires('libcurl/7.69.1') - self.options['libcurl'].with_openssl = False - self.options['libcurl'].with_winssl = True - else: - self.requires('libcurl/7.64.1@bincrafters/stable') + self.requires('gtest/1.8.1') + if self.settings.build_type == "Debug": + self.options['gtest'].debug_postfix = '' + + if self.options.webready: + self.requires('libcurl/7.80.0') if self.options.xmp: self.requires('XmpSdk/2016.7@piponazo/stable') # from conan-piponazo else: - self.requires('Expat/2.2.6@pix4d/stable') + self.requires('expat/2.4.8') def imports(self): self.copy('*.dll', dst='conanDlls', src='bin') diff -Nru exiv2-0.27.5/debian/changelog exiv2-0.27.6/debian/changelog --- exiv2-0.27.5/debian/changelog 2022-04-12 16:24:17.000000000 +0000 +++ exiv2-0.27.6/debian/changelog 2023-03-17 00:20:35.000000000 +0000 @@ -1,20 +1,40 @@ -exiv2 (0.27.5-3ubuntu1+22.04.sav0) jammy; urgency=medium +exiv2 (0.27.6-1~22.04.sav0) jammy; urgency=medium - * Rebuild for Jammy with some improvements - * Build with support for curl also: - - d/control: Add libcurl4-gnutls-dev BD for libcurl in httpIO - - d/rules: Add EXIV2_ENABLE_CURL config for CURL support + * Backport to Jammy + * Build with support for more features: + - debian/control: Add libcurl4-gnutls-dev BD for libcurl in httpIO + - debian/rules: Add EXIV2_ENABLE_CURL config for curl support * d/patches/: Restore fix-man-page-table-formatting.patch and rebase * Update symbols from build logs - -- Rob Savoury Tue, 12 Apr 2022 09:24:17 -0700 + -- Rob Savoury Thu, 16 Mar 2023 17:20:35 -0700 -exiv2 (0.27.5-3ubuntu1) jammy; urgency=medium +exiv2 (0.27.6-1) unstable; urgency=medium - * Sync with Debian (LP: #1959508). Remaining change: - - Mark symbols as optional not seen when building with lto + * Team upload. + * New upstream release. + * Update standards version to 4.6.2, no changes needed. + * Update Vcs-* fields. + * Use execute_after_dh_* to avoid invoking dh_* manually + * Execute chrpath right after dh_auto_install, rather than after dh_install. + * Update the build dependencies according to the upstream build system: + - bump cmake to 3.7.2 + * Remove non-existing file from copyright. + * Rename debian/docs to debian/exiv2.docs, to make it clearer (and consistent + with other files) to which package it refers to. + + -- Pino Toscano Sat, 28 Jan 2023 11:45:47 +0100 + +exiv2 (0.27.5-4) unstable; urgency=medium + + * Team upload. - -- Jeremy Bicha Mon, 11 Apr 2022 13:55:15 -0400 + [ Sandro Knauß ] + * Update symbol file for gcc-12 (Closes: #1012920). + * Update Standards-Version to 4.6.1 (No changes needed). + * Update symbols for link time optimation (Closes: #1015399). + + -- Sandro Knauß Mon, 22 Aug 2022 14:33:14 +0200 exiv2 (0.27.5-3) unstable; urgency=medium @@ -38,14 +58,6 @@ -- Sandro Knauß Fri, 25 Mar 2022 01:00:00 +0100 -exiv2 (0.27.5-1ubuntu1) jammy; urgency=medium - - * Sync with Debian. Remaining change: - - Mark symbols as optional not seen when building with lto - * Mark additional symbols as optional not seen on latest Ubuntu build - - -- Jeremy Bicha Thu, 10 Feb 2022 17:03:25 -0500 - exiv2 (0.27.5-1) unstable; urgency=medium * Team upload. @@ -779,7 +791,7 @@ * New Upstream Release. (Fixes: #370151) - -- KELEMEN Peter Tue, 14 Jun 2006 00:02:57 +0200 + -- KELEMEN Peter Wed, 14 Jun 2006 00:02:57 +0200 exiv2 (0.9.1-1) unstable; urgency=low diff -Nru exiv2-0.27.5/debian/control exiv2-0.27.6/debian/control --- exiv2-0.27.5/debian/control 2022-04-12 16:24:17.000000000 +0000 +++ exiv2-0.27.6/debian/control 2023-03-17 00:20:35.000000000 +0000 @@ -1,12 +1,11 @@ Source: exiv2 Section: graphics Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian KDE Extras Team +Maintainer: Debian KDE Extras Team Uploaders: Mark Purcell , Steve M. Robbins Build-Depends: chrpath, - cmake, + cmake (>= 3.7.2~), debhelper-compat (= 13), gettext, libcurl4-gnutls-dev, @@ -14,11 +13,11 @@ pkg-kde-tools, zlib1g-dev, Build-Depends-Indep: doxygen, graphviz, libjs-jquery, xsltproc -Standards-Version: 4.6.0 +Standards-Version: 4.6.2 Rules-Requires-Root: no Homepage: https://www.exiv2.org/ -Vcs-Browser: https://salsa.debian.org/qt-kde-team/extras/exiv2 -Vcs-Git: https://salsa.debian.org/qt-kde-team/extras/exiv2.git +Vcs-Browser: https://salsa.debian.org/qt-kde-team/3rdparty/exiv2 +Vcs-Git: https://salsa.debian.org/qt-kde-team/3rdparty/exiv2.git Package: exiv2 Architecture: any @@ -72,6 +71,7 @@ Package: libexiv2-dev Section: libdevel Architecture: any +Multi-Arch: same Depends: libexiv2-27 (= ${binary:Version}), ${misc:Depends} Breaks: libexiv2-27 (<< 0.27.2-8~) Replaces: libexiv2-27 (<< 0.27.2-8~) @@ -87,6 +87,7 @@ Depends: libjs-jquery, ${misc:Depends} Section: doc Architecture: all +Multi-Arch: foreign Description: EXIF/IPTC/XMP metadata manipulation library - HTML documentation Exiv2 is a C++ library and a command line utility to manage image metadata. It provides fast and easy read and write access to the Exif, IPTC and XMP diff -Nru exiv2-0.27.5/debian/copyright exiv2-0.27.6/debian/copyright --- exiv2-0.27.5/debian/copyright 2022-04-11 17:55:15.000000000 +0000 +++ exiv2-0.27.6/debian/copyright 2023-01-28 09:58:07.000000000 +0000 @@ -20,7 +20,6 @@ po/CMakeLists.txt samples/CMakeLists.txt src/CMakeLists.txt - src/Makefile xmpsdk/CMakeLists.txt Copyright: 1999-2008, Adobe Systems Incorporated 2010, Alexander Neundorf diff -Nru exiv2-0.27.5/debian/docs exiv2-0.27.6/debian/docs --- exiv2-0.27.5/debian/docs 2022-04-11 17:55:15.000000000 +0000 +++ exiv2-0.27.6/debian/docs 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -README.md diff -Nru exiv2-0.27.5/debian/exiv2.docs exiv2-0.27.6/debian/exiv2.docs --- exiv2-0.27.5/debian/exiv2.docs 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/debian/exiv2.docs 2020-08-08 16:04:51.000000000 +0000 @@ -0,0 +1 @@ +README.md diff -Nru exiv2-0.27.5/debian/patches/fix-man-page-table-formatting.patch exiv2-0.27.6/debian/patches/fix-man-page-table-formatting.patch --- exiv2-0.27.5/debian/patches/fix-man-page-table-formatting.patch 2021-07-29 03:02:02.000000000 +0000 +++ exiv2-0.27.6/debian/patches/fix-man-page-table-formatting.patch 2023-03-17 00:19:45.000000000 +0000 @@ -2,11 +2,16 @@ Date: Sun, 1 Sep 2019 12:08:49 +0200 Description: fix man page table width and separation -Last-Update: 2021-07-28 +Last-Update: 2023-03-16 +--- + man/man1/exiv2.1 | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) +diff --git a/man/man1/exiv2.1 b/man/man1/exiv2.1 +index 34ca3a9..291c632 100644 --- a/man/man1/exiv2.1 +++ b/man/man1/exiv2.1 -@@ -42,32 +42,32 @@ Type Exif IPTC XMP Image Comments ICC Profile +@@ -42,33 +42,33 @@ Type Exif IPTC XMP Image Comments ICC Profile ARW Read Read Read - - AVIF Read Read Read - - BMP - - - - - @@ -20,7 +25,7 @@ +CRW R/W - - R/W - +DNG R/W R/W R/W - R/W +EPS - - R/W - - -+EXV R/W R/W R/W R/W R/W ++EXV R/W R/W R/W R/W R/W GIF - - - - - HEIC Read Read Read - - HEIF Read Read Read - - @@ -28,6 +33,7 @@ -JPEG Read/Write Read/Write Read/Write Read/Write Read/Write +JP2 R/W R/W R/W - R/W +JPEG R/W R/W R/W R/W R/W + JPEG XL Read Read Read - - MRW Read Read Read - - -NEF Read/Write Read/Write Read/Write - Read/Write -ORF Read/Write Read/Write Read/Write - - diff -Nru exiv2-0.27.5/debian/rules exiv2-0.27.6/debian/rules --- exiv2-0.27.5/debian/rules 2022-04-12 16:20:34.000000000 +0000 +++ exiv2-0.27.6/debian/rules 2023-03-17 00:20:35.000000000 +0000 @@ -1,7 +1,6 @@ #!/usr/bin/make -f -export DEB_BUILD_MAINT_OPTIONS = hardening=+all - +export DEB_BUILD_MAINT_OPTIONS = hardening=+all optimize=+lto # exiv2 uses std::auto_ptr<> a lot, so avoid the lots of deprecation warnings export DEB_CXXFLAGS_MAINT_APPEND = -Wno-deprecated-declarations @@ -26,12 +25,10 @@ dh_auto_configure -a -- \ $(CMAKE_COMMON_ARGS) -override_dh_install: - dh_install +execute_after_dh_auto_install: find $(CURDIR)/debian -type f -name exiv2 | xargs /usr/bin/chrpath -d -override_dh_auto_build-indep: - dh_auto_build +execute_after_dh_auto_build-indep: dh_auto_build -- doc override_dh_installdocs: @@ -45,6 +42,5 @@ override_dh_compress: dh_compress -X.xls -X.js -X.idx -X.xml -X.php -X.cpp -override_dh_fixperms-indep: - dh_fixperms -i +execute_after_dh_fixperms-indep: find $(CURDIR)/debian/libexiv2-doc -name '*.ini' -exec chmod -x {} \; diff -Nru exiv2-0.27.5/doc/ChangeLog exiv2-0.27.6/doc/ChangeLog --- exiv2-0.27.5/doc/ChangeLog 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/doc/ChangeLog 2023-01-18 21:57:53.000000000 +0000 @@ -1,3 +1,15 @@ +Changes from version 0.27.5 to 0.27.6 +------------------------------------- + +Closed: +https://github.com/Exiv2/exiv2/milestone/10?closed=1 + +Open: +https://github.com/Exiv2/exiv2/milestone/10?open=1 + +Release Notes: +https://github.com/Exiv2/exiv2/issues/2406#issuecomment-1383302378 + Changes from version 0.27.4 to 0.27.5 ------------------------------------- diff -Nru exiv2-0.27.5/.github/workflows/codeql-analysis.yml exiv2-0.27.6/.github/workflows/codeql-analysis.yml --- exiv2-0.27.5/.github/workflows/codeql-analysis.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/codeql-analysis.yml 2023-01-18 21:57:53.000000000 +0000 @@ -28,7 +28,7 @@ steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff -Nru exiv2-0.27.5/.github/workflows/nightly_Linux_distributions.yml exiv2-0.27.6/.github/workflows/nightly_Linux_distributions.yml --- exiv2-0.27.5/.github/workflows/nightly_Linux_distributions.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/nightly_Linux_distributions.yml 2023-01-18 21:57:53.000000000 +0000 @@ -35,7 +35,7 @@ echo $distro_id if [[ "$distro_id" == "opensuse-tumbleweed" ]]; then zypper --non-interactive install tar gzip; fi - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: ./ci/install_dependencies.sh - name: build and compile diff -Nru exiv2-0.27.5/.github/workflows/on_PR_linux_fuzz.yml exiv2-0.27.6/.github/workflows/on_PR_linux_fuzz.yml --- exiv2-0.27.5/.github/workflows/on_PR_linux_fuzz.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_PR_linux_fuzz.yml 2023-01-18 21:57:53.000000000 +0000 @@ -14,7 +14,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: sudo ./ci/install_dependencies.sh - name: build and compile diff -Nru exiv2-0.27.5/.github/workflows/on_PR_linux_matrix.yml exiv2-0.27.6/.github/workflows/on_PR_linux_matrix.yml --- exiv2-0.27.5/.github/workflows/on_PR_linux_matrix.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_PR_linux_matrix.yml 2023-01-18 21:57:53.000000000 +0000 @@ -14,12 +14,12 @@ shared_libraries: [ON, OFF] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get install ninja-build - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -48,8 +48,5 @@ tree install - name: Test - env: - EXIV2_EXT: .exe run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure diff -Nru exiv2-0.27.5/.github/workflows/on_PR_linux_special_buils.yml exiv2-0.27.6/.github/workflows/on_PR_linux_special_buils.yml --- exiv2-0.27.5/.github/workflows/on_PR_linux_special_buils.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_PR_linux_special_buils.yml 2023-01-18 21:57:53.000000000 +0000 @@ -8,7 +8,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 2 # Trying to deal with warning: -> Issue detecting commit SHA. Please run actions/checkout with fetch-depth > 1 or set to 0 @@ -16,7 +16,7 @@ - name: install dependencies run: | sudo apt-get install ninja-build - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -38,11 +38,9 @@ cmake --build . - name: Tests + Upload coverage - env: - EXIV2_EXT: .exe run: | cd build - cmake --build . --target tests + ctest --output-on-failure pip install gcovr gcovr -r ./../ -x --exclude-unreachable-branches --exclude-throw-branches -o coverage.xml . curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import @@ -59,13 +57,13 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get update sudo apt-get install valgrind ninja-build - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -87,8 +85,6 @@ cmake --build . - name: Tests with valgrind - env: - EXIV2_EXT: .exe run: | cd build/bin valgrind ./unit_tests @@ -99,12 +95,12 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get install ninja-build - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -126,24 +122,21 @@ cmake --build . - name: Tests - env: - EXIV2_EXT: .exe run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure special_allEnabled: name: 'Ubuntu 20.04 - GCC - All Options Enabled' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get update sudo apt-get install valgrind doxygen graphviz gettext - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -167,21 +160,3 @@ - name: Generate documentation run: | make doc - - special_FedoraMinGW: - name: 'Fedora MinGW' - runs-on: ubuntu-latest - container: - image: "fedora:latest" - - steps: - - uses: actions/checkout@v2 - - - name: install dependencies - run: | - dnf -y upgrade - dnf -y install mingw64-gcc-c++ mingw64-filesystem mingw64-expat mingw64-zlib cmake make - - - name: Build - run: - python3 ci/test_build.py --without-tests --cmake-executable "mingw64-cmake" --cmake-options "-DEXIV2_TEAM_EXTRA_WARNINGS=OFF -DEXIV2_TEAM_WARNINGS_AS_ERRORS=OFF -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_WIN_UNICODE=ON " --compilers --shared-libs OFF diff -Nru exiv2-0.27.5/.github/workflows/on_PR_mac_matrix.yml exiv2-0.27.6/.github/workflows/on_PR_mac_matrix.yml --- exiv2-0.27.5/.github/workflows/on_PR_mac_matrix.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_PR_mac_matrix.yml 2023-01-18 21:57:53.000000000 +0000 @@ -14,7 +14,7 @@ shared_libraries: [ON, OFF] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | @@ -36,12 +36,8 @@ - name: Install run: | - cd build - cmake --build . --target install + cmake --build build --target install - name: Test - env: - EXIV2_EXT: .exe run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure diff -Nru exiv2-0.27.5/.github/workflows/on_PR_windows_matrix.yml exiv2-0.27.6/.github/workflows/on_PR_windows_matrix.yml --- exiv2-0.27.5/.github/workflows/on_PR_windows_matrix.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_PR_windows_matrix.yml 2023-01-18 21:57:53.000000000 +0000 @@ -11,7 +11,7 @@ jobs: windows: name: 'Win10 Arch: ${{matrix.platform}} BuildType:${{matrix.build_type}} - SHARED:${{matrix.shared_libraries}}' - runs-on: windows-latest + runs-on: windows-2022 strategy: fail-fast: false @@ -19,26 +19,26 @@ build_type: [Release, Debug] shared_libraries: [ON, OFF] platform: [ x64, x86 ] - + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Visual Studio shell uses: egor-tensin/vs-shell@v2 with: arch: ${{matrix.platform}} - - name: Setup Ninja + - name: Set up Ninja uses: ashutoshvarma/setup-ninja@master with: version: 1.10.0 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v3 with: python-version: 3.7 - - name: Restore conan cache + - name: Restore Conan cache uses: actions/cache@v2 with: path: ${{github.workspace}}/conanCache @@ -46,13 +46,12 @@ - name: Install Conan & Common config run: | - pip.exe install "conan==1.39.0" - conan config install https://github.com/conan-io/conanclientcert.git + pip.exe install "conan==1.53.0" conan profile new --detect default conan profile update settings.build_type=${{matrix.build_type}} default + conan profile update settings.compiler="Visual Studio" default + conan profile update settings.compiler.version=17 default conan config set storage.path=$Env:GITHUB_WORKSPACE/conanCache - conan config get storage.path - tree /f ./conanCache - name: Conan Arch conditional config if: ${{matrix.platform == 'x86'}} @@ -68,23 +67,132 @@ conan install .. --build missing dir .. tree /f ../conanCache - + - name: Build run: | - cd build - cmake -GNinja -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} -DEXIV2_ENABLE_NLS=OFF -DEXIV2_ENABLE_PNG=ON -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_WIN_UNICODE=OFF -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DEXIV2_ENABLE_BMFF=ON -DCMAKE_INSTALL_PREFIX=install .. - ninja + cmake -GNinja ` + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} ` + -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} ` + -DEXIV2_ENABLE_NLS=OFF ` + -DEXIV2_ENABLE_WIN_UNICODE=OFF ` + -DEXIV2_ENABLE_WEBREADY=ON ` + -DEXIV2_ENABLE_BMFF=ON ` + -DEXIV2_BUILD_UNIT_TESTS=ON ` + -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON ` + -DCMAKE_INSTALL_PREFIX=install ` + -S . -B build && ` + cmake --build build --parallel - name: Install run: | cd build - ninja install + cmake --install . tree /f install - name: Test if: ${{matrix.platform == 'x64'}} - env: - EXIV2_EXT: .exe run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure + + msys2: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + build_type: [Release, Debug] + shared_libraries: [ON, OFF] + sys: [MINGW64] + name: MSYS2 ${{matrix.sys}} - BuildType:${{matrix.build_type}} - SHARED:${{matrix.shared_libraries}} + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v3 + + - name: Set up MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{matrix.sys}} + update: true + install: >- + base-devel + pacboy: >- + toolchain:p + cmake:p + ninja:p + expat:p + gettext:p + gtest:p + libiconv:p + python-lxml:p + zlib:p + + - name: Build + run: | + cmake -GNinja \ + -DCMAKE_CXX_FLAGS=-Wno-deprecated \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} \ + -DEXIV2_BUILD_SAMPLES=ON \ + -DEXIV2_ENABLE_NLS=ON \ + -DEXIV2_ENABLE_WIN_UNICODE=ON \ + -DEXIV2_ENABLE_WEBREADY=ON \ + -DEXIV2_ENABLE_BMFF=ON \ + -DEXIV2_BUILD_UNIT_TESTS=ON \ + -S . -B build && \ + cmake --build build --parallel + + - name: Test + run: | + ctest --test-dir build --output-on-failure + + cygwin: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + build_type: [Release] + shared_libraries: [ON] + platform: [x64] + name: Cygwin ${{matrix.platform}} - BuildType:${{matrix.build_type}} - SHARED:${{matrix.shared_libraries}} + env: + SHELLOPTS: igncr + defaults: + run: + shell: C:\tools\cygwin\bin\bash.exe -eo pipefail '{0}' + steps: + # Make sure we don't check out scripts using Windows CRLF line endings + - run: git config --global core.autocrlf input + shell: pwsh + - uses: actions/checkout@v3 + + - name: Set up Cygwin + uses: egor-tensin/setup-cygwin@v3 + with: + platform: ${{matrix.platform}} + packages: >- + gcc-g++ + cmake + ninja + libexpat-devel + libxml2-devel + libxslt-devel + python38-lxml + zlib-devel + - name: Build + run: | + cmake -GNinja \ + -DCMAKE_CXX_FLAGS=-Wno-deprecated \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} \ + -DEXIV2_ENABLE_NLS=OFF \ + -DEXIV2_ENABLE_WIN_UNICODE=OFF \ + -DEXIV2_ENABLE_WEBREADY=ON \ + -DEXIV2_ENABLE_BMFF=ON \ + -DEXIV2_BUILD_UNIT_TESTS=OFF \ + -S . -B build && \ + cmake --build build --parallel + + - name: Test + run: | + ctest --test-dir build --output-on-failure diff -Nru exiv2-0.27.5/.github/workflows/on_push_BasicWinLinMac.yml exiv2-0.27.6/.github/workflows/on_push_BasicWinLinMac.yml --- exiv2-0.27.5/.github/workflows/on_push_BasicWinLinMac.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_push_BasicWinLinMac.yml 2023-01-18 21:57:53.000000000 +0000 @@ -12,7 +12,7 @@ runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Ninja uses: ashutoshvarma/setup-ninja@master @@ -25,16 +25,19 @@ arch: x64 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v3 with: python-version: 3.9 - name: Install Conan & Common config run: | - pip.exe install "conan==1.39.0" + pip.exe install "conan==1.53.0" conan config install https://github.com/conan-io/conanclientcert.git conan profile new --detect default conan profile show default + conan profile update settings.compiler="Visual Studio" default + conan profile update settings.compiler.version=17 default + conan config set storage.path=$Env:GITHUB_WORKSPACE/conanCache - name: Run Conan run: | @@ -45,32 +48,40 @@ - name: Build run: | - cd build - cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DEXIV2_ENABLE_NLS=OFF -DEXIV2_ENABLE_PNG=ON -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_WIN_UNICODE=OFF -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install .. - cmake --build . - + cmake -GNinja ` + -DCMAKE_BUILD_TYPE=Release ` + -DBUILD_SHARED_LIBS=ON ` + -DEXIV2_BUILD_SAMPLES=ON ` + -DEXIV2_ENABLE_NLS=OFF ` + -DEXIV2_ENABLE_PNG=ON ` + -DEXIV2_ENABLE_WEBREADY=ON ` + -DEXIV2_ENABLE_BMFF=ON ` + -DEXIV2_BUILD_UNIT_TESTS=ON ` + -DEXIV2_ENABLE_WIN_UNICODE=OFF ` + -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON ` + -DCMAKE_INSTALL_PREFIX=install .. ` + -S . -B build && ` + cmake --build build --parallel - name: Test run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure Linux: name: 'Ubuntu 20.04 - GCC - Arch:x64 BuildType:Release - SHARED' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | sudo apt-get install ninja-build - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan run: | mkdir build && cd build - conan config install https://github.com/conan-io/conanclientcert.git conan profile new --detect default conan profile update settings.compiler.libcxx=libstdc++11 default conan profile show default @@ -78,21 +89,33 @@ - name: build and compile run: | - cd build - cmake -GNinja -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON .. - cmake --build . + cd build && \ + cmake -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DEXIV2_BUILD_SAMPLES=ON \ + -DEXIV2_ENABLE_PNG=ON \ + -DEXIV2_ENABLE_WEBREADY=ON \ + -DEXIV2_ENABLE_CURL=ON \ + -DEXIV2_BUILD_UNIT_TESTS=ON \ + -DEXIV2_ENABLE_BMFF=ON \ + -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON \ + -DCMAKE_INSTALL_PREFIX=install \ + -DCMAKE_CXX_FLAGS=-Wno-deprecated \ + .. && \ + cmake --build . --parallel + - name: Test run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure MacOS: name: 'MacOS - clang - Arch:x64 BuildType:Release - SHARED' runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | @@ -108,11 +131,22 @@ - name: build and compile run: | - mkdir build && cd build - cmake -GNinja -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" .. - cmake --build . + mkdir build && cd build && \ + cmake -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DEXIV2_BUILD_SAMPLES=ON \ + -DEXIV2_ENABLE_PNG=ON \ + -DEXIV2_ENABLE_WEBREADY=ON \ + -DEXIV2_ENABLE_CURL=ON \ + -DEXIV2_BUILD_UNIT_TESTS=ON \ + -DEXIV2_ENABLE_BMFF=ON \ + -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON \ + -DCMAKE_INSTALL_PREFIX=install \ + -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" \ + .. && \ + cmake --build . --parallel - name: Test run: | - cd build - cmake --build . --target tests + ctest --test-dir build --output-on-failure diff -Nru exiv2-0.27.5/.github/workflows/on_push_ExtraJobsForMain.yml exiv2-0.27.6/.github/workflows/on_push_ExtraJobsForMain.yml --- exiv2-0.27.5/.github/workflows/on_push_ExtraJobsForMain.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/on_push_ExtraJobsForMain.yml 2023-01-18 21:57:53.000000000 +0000 @@ -13,11 +13,11 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: install dependencies run: | - pip3 install conan==1.39.0 + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -39,11 +39,9 @@ make -j - name: Tests + Upload coverage - env: - EXIV2_EXT: .exe run: | cd build - cmake --build . --target tests + ctest --output-on-failure pip install gcovr gcovr -r ./../ -x --exclude-unreachable-branches --exclude-throw-branches -o coverage.xml . curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import diff -Nru exiv2-0.27.5/.github/workflows/release.yml exiv2-0.27.6/.github/workflows/release.yml --- exiv2-0.27.5/.github/workflows/release.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.github/workflows/release.yml 2023-01-18 21:57:53.000000000 +0000 @@ -3,6 +3,8 @@ push: tags: - v[0-9]+.[0-9]+.[0-9]+ + schedule: + - cron: '30 4 * * *' workflow_dispatch: inputs: tag_name: @@ -15,15 +17,12 @@ name: 'Build Linux Release' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | - sudo apt-get install ninja-build - sudo apt-get install gettext - sudo apt-get install doxygen - sudo apt-get install graphviz - pip3 install conan==1.39.0 + sudo apt-get install ninja-build gettext doxygen graphviz + pip3 install conan==1.53.0 - name: Conan common config run: | @@ -43,11 +42,11 @@ run: | cd build cmake -GNinja -DEXIV2_TEAM_PACKAGING=ON -DBUILD_SHARED_LIBS=ON -DEXIV2_ENABLE_WEBREADY=OFF -DEXIV2_ENABLE_NLS=ON -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DEXIV2_BUILD_DOC=ON .. - cmake --build . -t doc - cmake --build . -t package + cmake --build . --target doc + cmake --build . --target package tree -L 3 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: exiv2-linux64 path: ./build/exiv2-*.tar.gz @@ -58,25 +57,21 @@ name: 'Build macOS Release' runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | - brew install ninja - brew install tree - brew install gettext - brew install doxygen - brew install graphviz + brew install ninja tree gettext doxygen graphviz - name: Build packaged release run: | mkdir build && cd build cmake -GNinja -DEXIV2_TEAM_PACKAGING=ON -DBUILD_SHARED_LIBS=ON -DEXIV2_ENABLE_WEBREADY=OFF -DEXIV2_ENABLE_NLS=ON -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DEXIV2_BUILD_DOC=ON -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" .. - cmake --build . -t doc - cmake --build . -t package + cmake --build . --target doc + cmake --build . --target package tree -L 3 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: exiv2-macos path: ./build/exiv2-*.tar.gz @@ -87,7 +82,7 @@ name: 'Build Windows Release' runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Visual Studio shell uses: egor-tensin/vs-shell@v2 @@ -98,7 +93,7 @@ version: 1.10.0 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v3 with: python-version: 3.7 @@ -115,7 +110,7 @@ - name: Install Conan & Common config run: | - pip.exe install "conan==1.39.0" + pip.exe install "conan==1.53.0" conan config install https://github.com/conan-io/conanclientcert.git conan profile new --detect default conan profile update settings.build_type=Release default @@ -135,12 +130,12 @@ - name: Build packaged release run: | cd build - cmake -GNinja -DEXIV2_TEAM_PACKAGING=ON -DBUILD_SHARED_LIBS=ON -DEXIV2_ENABLE_WEBREADY=OFF -DEXIV2_ENABLE_NLS=OFF -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DEXIV2_BUILD_DOC=ON .. - cmake --build . -t doc - cmake --build . -t package + cmake -GNinja -DEXIV2_TEAM_PACKAGING=ON -DBUILD_SHARED_LIBS=ON -DEXIV2_ENABLE_WEBREADY=OFF -DEXIV2_ENABLE_NLS=OFF -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DEXIV2_BUILD_DOC=ON .. + cmake --build . --target doc + cmake --build . --target package tree -L 3 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: exiv2-win path: ./build/exiv2-*.zip @@ -182,7 +177,7 @@ - name: Cleanup old 0.27-nightly if: env.TAG_NAME == '0.27-nightly' - uses: actions/github-script@v4 + uses: actions/github-script@v6 with: script: | try{ @@ -215,11 +210,11 @@ console.log( "Failed with error\n", error); } - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 - name: List downloaded files run: tree -L 3 - - uses: softprops/action-gh-release@v0.1.8 + - uses: softprops/action-gh-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff -Nru exiv2-0.27.5/.gitlab-ci.yml exiv2-0.27.6/.gitlab-ci.yml --- exiv2-0.27.5/.gitlab-ci.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -# all builds use the same ccache folder in the project root that is cached -variables: - CCACHE_BASEDIR: '$CI_PROJECT_DIR' - CCACHE_DIR: '$CI_PROJECT_DIR/ccache' - -# default config for all distros: -# - install dependencies via script -# - create ccache dir & setup caching of it (for each job separately) -.build_config: &default_config - before_script: - - ci/install_dependencies.sh - - mkdir -p ccache - cache: - key: "$CI_JOB_NAME" - paths: - - ccache/ - -# default build job: -# - run build script -# - only create artifacts of the build directory when something fails -# (for cmake logs) -.build_template: &distro_build - script: - - python3 ci/test_build.py - artifacts: - when: on_failure - paths: - - build/ - -stages: - - test - - deploy - -# Fedora: -# image: fedora:latest -# <<: *default_config -# <<: *distro_build - -Fedora_MinGW: - image: fedora:latest - before_script: - - dnf -y upgrade - - dnf -y install mingw64-gcc-c++ mingw64-filesystem mingw64-expat mingw64-zlib cmake make - script: - - python3 ci/test_build.py --without-tests --cmake-executable "mingw64-cmake" --cmake-options "-DEXIV2_TEAM_EXTRA_WARNINGS=ON -DEXIV2_ENABLE_VIDEO=ON -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_WIN_UNICODE=ON " --compilers --shared-libs OFF - -Debian: - image: debian:9 - <<: *default_config - <<: *distro_build - -# Archlinux: -# image: archlinux/base -# <<: *default_config -# <<: *distro_build - -Ubuntu: - image: ubuntu:18.04 - <<: *default_config - <<: *distro_build - -# CentOS: -# image: centos:7 -# <<: *default_config -# <<: *distro_build - -# OpenSUSE: -# image: opensuse/tumbleweed -# <<: *default_config -# <<: *distro_build - -Install: - image: fedora:latest - stage: deploy - <<: *default_config - script: - - mkdir build && cd build - - cmake -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_VIDEO=ON -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DCMAKE_INSTALL_PREFIX=/usr/ -DBUILD_WITH_CCACHE=ON .. - - make -j $(nproc) - - make install - - make clean - - EXIV2_BINDIR=/usr/bin/ make tests - -pages: - image: fedora:latest - stage: deploy - <<: *default_config - script: - - dnf -y install doxygen graphviz - - mkdir build && cd build - - cmake -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_VIDEO=ON -DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_BUILD_DOC=ON .. - - make doc - - cd .. - - mv build/doc/html/ public/ - artifacts: - paths: - - public - only: - - master diff -Nru exiv2-0.27.5/man/man1/exiv2.1 exiv2-0.27.6/man/man1/exiv2.1 --- exiv2-0.27.5/man/man1/exiv2.1 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/man/man1/exiv2.1 2023-01-18 21:57:53.000000000 +0000 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH EXIV2 1 "August 10, 2021" +.TH EXIV2 1 "November 02, 2022" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -53,6 +53,7 @@ HEIF Read Read Read - - JP2 Read/Write Read/Write Read/Write - Read/Write JPEG Read/Write Read/Write Read/Write Read/Write Read/Write +JPEG XL Read Read Read - - MRW Read Read Read - - NEF Read/Write Read/Write Read/Write - Read/Write ORF Read/Write Read/Write Read/Write - - @@ -76,6 +77,19 @@ .IP \(bu 2 Reading other TIFF-like RAW image formats, which are not listed in the table, may also work. +.IP \(bu 2 +Support for BMFF file types such as CR3, HEIF, HEIC, AVIF, and +JPEG XL is a build option. To check if this is enabled, use: +.PP +.in +4n +.EX +$ exiv2 --version --verbose | grep bmff +enable_bmff=1 +.EE +.in +.PP +.IP \(bu 2 +Naked codestream JPEG XL files do not contain Exif, IPTC, or XMP metadata. .SH ACTIONS The \fIaction\fP argument is only required if it is not clear from the \fIoptions\fP which action is implied. @@ -114,7 +128,8 @@ timestamp. Uses the value of tag Exif.Photo.DateTimeOriginal or, if not present, Exif.Image.DateTime to determine the timestamp. The filename format can be set with \fB\-r\fP \fIfmt\fP, timestamp options -are \fB\-t\fP and \fB\-T\fP. +are \fB\-t\fP and \fB\-T\fP. When no rename format is provided, +the default is \'%Y%m%d_%H%M%S\' using definitions from \fBstrftime\fP(3). .TP .B fi | fixiso Copy the ISO setting from one of the proprietary Nikon or Canon @@ -312,15 +327,17 @@ .br .TP .B \-r \fIfmt\fP -Filename format for the 'rename' action. The format string follows -\fBstrftime\fP(3) and supports the following keywords: +Filename format for the 'rename' action. The format string +uses \fBstrftime\fP(3) definitions and supports the following +keywords: .TS l l. :basename: original filename without extension :dirname: name of the directory holding the original file :parentname: name of parent directory .TE -Default filename format is %Y%m%d_%H%M%S. +.sp 1 +Note that the colons are part of the keyword. .TP .B \-a \fItime\fP Time adjustment in the format [\-]HH[:MM[:SS]]. This option is only diff -Nru exiv2-0.27.5/README-CONAN.md exiv2-0.27.6/README-CONAN.md --- exiv2-0.27.5/README-CONAN.md 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/README-CONAN.md 2023-01-18 21:57:53.000000000 +0000 @@ -99,20 +99,19 @@ [env] ``` -_Profiles for Visual Studio are discussed in detail here: [Visual Studio Notes](#2-2)__ +_Profiles for Visual Studio are discussed in detail here: [Visual Studio Notes](#2-2)_ + ##### 1.4) Build dependencies, create build environment, build and test -| | Build Steps | Linux and macOS | Visual Studio | -|:-- |:--------------|--------------------------------|------------------------------| +| | Build Steps | Linux and macOS | Visual Studio | +|:-- |:-------------------------------------------------------------------------|-----------------------|------------------------------| | _**1**_ | Get conan to fetch dependencies

The output can be quite
long as conan downloads and/or builds
zlib, expat, curl and other dependencies.| $ conan install ..
     --build missing | c:\\..\\build> conan install .. --build missing
    --profile msvc2019Release64 | -| _**2**_ | Get cmake to generate
makefiles or sln/vcxproj | $ cmake .. | c:\\..\\build> cmake .. -G "Visual Studio 16 2019" -| _**3**_ | Build | $ cmake --build . | c:\\..\\build> cmake --build . --config Release
You may prefer to open exiv2.sln and build using the IDE. | -| _**4**_ | Optionally Run Test Suite | $ make tests | c:\\..\\build> cmake --build . --config Release --target tests
[README.md](README.md) | - - +| _**2**_ | Get cmake to generate
makefiles or sln/vcxproj | $ cmake .. | c:\\..\\build> cmake .. -G "Visual Studio 16 2019" +| _**3**_ | Build | $ cmake --build . | c:\\..\\build> cmake --build . --config Release
You may prefer to open exiv2.sln and build using the IDE. | +| _**4**_ | Optionally Run Test Suite
Test documentation: [README.md](README.md) | $ ctest | c:\\..\\build> ctest -C Release | [TOC](#TOC) @@ -573,4 +572,4 @@ [TOC](#TOC) -Written by Robin Mills
robin@clanmills.com
Updated: 2021-03-18 +Written by Robin Mills
robin@clanmills.com
Updated: 2021-12-19 diff -Nru exiv2-0.27.5/README.md exiv2-0.27.6/README.md --- exiv2-0.27.5/README.md 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/README.md 2023-01-18 21:57:53.000000000 +0000 @@ -1,10 +1,20 @@ -| Travis | AppVeyor | GitLab| Codecov| Repology| Chat | -|:-------------:|:-------------:|:-----:|:------:|:-------:|:----:| -| [![Build Status](https://travis-ci.org/Exiv2/exiv2.svg?branch=0.27-maintenance)](https://travis-ci.org/Exiv2/exiv2) | [![Build status](https://ci.appveyor.com/api/projects/status/d6vxf2n0cp3v88al/branch/0.27-maintenance?svg=true)](https://ci.appveyor.com/project/piponazo/exiv2-wutfp/branch/0.27-maintenance) | [![pipeline status](https://gitlab.com/D4N/exiv2/badges/0.27-maintenance/pipeline.svg)](https://gitlab.com/D4N/exiv2/commits/0.27-maintenance) | [![codecov](https://codecov.io/gh/Exiv2/exiv2/branch/0.27-maintenance/graph/badge.svg)](https://codecov.io/gh/Exiv2/exiv2) | [![Packaging status](https://repology.org/badge/tiny-repos/exiv2.svg)](https://repology.org/metapackage/exiv2/versions) | [![#exiv2-chat on matrix.org](matrix-standard-vector-logo-xs.png)](https://matrix.to/#/#exiv2-chat:matrix.org) | +| Codecov | OSS-Fuzz | Repology | Chat | +| :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | +| [![codecov](https://codecov.io/gh/Exiv2/exiv2/branch/main/graph/badge.svg?token=O9G7Iswx26)](https://codecov.io/gh/Exiv2/exiv2) | [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/exiv2.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:exiv2) | [![Packaging status](https://repology.org/badge/tiny-repos/exiv2.svg)](https://repology.org/metapackage/exiv2/versions) | [![#exiv2-chat on matrix.org](matrix-standard-vector-logo-xs.png)](https://matrix.to/#/#exiv2-chat:matrix.org) | + + + +| **CI Status:** | | | +|:-- |:-- |:-- | +| [![Basic CI for all platforms on push](https://github.com/Exiv2/exiv2/actions/workflows/on_push_BasicWinLinMac.yml/badge.svg?branch=main)](https://github.com/Exiv2/exiv2/actions/workflows/on_push_BasicWinLinMac.yml) | [![CI for different Linux distributions](https://github.com/Exiv2/exiv2/actions/workflows/nightly_Linux_distributions.yml/badge.svg?branch=main)](https://github.com/Exiv2/exiv2/actions/workflows/nightly_Linux_distributions.yml) | [![Linux Special Builds on PRs](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_linux_special_buils.yml/badge.svg)](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_linux_special_buils.yml) | +| [![Linux-Ubuntu Matrix on PRs](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_linux_matrix.yml/badge.svg)](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_linux_matrix.yml) | [![Mac Matrix on PRs](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_mac_matrix.yml/badge.svg)](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_mac_matrix.yml) | [![Win Matrix on PRs](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_windows_matrix.yml/badge.svg)](https://github.com/Exiv2/exiv2/actions/workflows/on_PR_windows_matrix.yml) |
+ # Welcome to Exiv2 +![Exiv2](exiv2.png) + Exiv2 is a C++ library and a command-line utility to read, write, delete and modify Exif, IPTC, XMP and ICC image metadata. @@ -16,8 +26,8 @@ The file ReadMe.txt in a build bundle describes how to install the library on the platform. ReadMe.txt also documents how to compile and link code on the platform.
+ ### TABLE OF CONTENTS -![Exiv2](exiv2.png) 1. [Welcome to Exiv2](#1) 2. [Building, Installing, Using and Uninstalling Exiv2](#2) @@ -39,16 +49,15 @@ 16. [Cross Platform Build and Test on Linux for MinGW](#2-16) 17. [Building with C++11 and other compilers](#2-17) 18. [Static and Shared Libraries](#2-18) - 19. [Support for bmff files (CR3, HEIF, HEIC, and AVIF)](#2-19) + 19. [Support for BMFF files (e.g., CR3, HEIF, HEIC, AVIF, and JPEG XL)](#2-19) 3. [License and Support](#3) 1. [License](#3-1) 2. [Support](#3-2) -4. [Test Suit](#4) +4. [Test Suite](#4) 1. [Running tests on a UNIX-like system](#4-1) 2. [Running tests on Visual Studio builds](#4-2) - 3. [Unit tests](#4-3) - 4. [Python tests](#4-4) - 5. [Test Summary](#4-5) + 3. [Unit Tests](#4-3) + 4. [Bugfix Tests](#4-4) 5. [Platform Notes](#5) 1. [Linux](#5-1) 2. [macOS](#5-2) @@ -59,11 +68,13 @@ [TOC](#TOC)
+ ## 2 Building, Installing, Using and Uninstalling Exiv2 You need [CMake](https://cmake.org/download/) to configure the Exiv2 project and the GCC or Clang compiler and associated tool chain.
+ ### 2.1 Build, Install, Use Exiv2 on a UNIX-like system ```bash @@ -71,8 +82,8 @@ $ mkdir build && cd build $ cmake .. -DCMAKE_BUILD_TYPE=Release $ cmake --build . -$ make tests -$ sudo make install +$ ctest +$ sudo cmake --build . --target install ``` This will install the library into the "standard locations". The library will be installed in `/usr/local/lib`, executables (including the exiv2 command-line program) in `/usr/local/bin/` and header files in `/usr/local/include/exiv2` @@ -108,6 +119,7 @@ [TOC](#TOC)
+ ### 2.2 Build and Install Exiv2 with Visual Studio We recommend that you use conan to download the Exiv2 external dependencies on Windows. On other platforms (maxOS, Ubuntu and others), you should use the platform package manger. These are discussed: [Platform Notes](#5) The options to configure and compile the project using Visual Studio are similar to UNIX like systems. @@ -122,6 +134,7 @@ [TOC](#TOC)
+ ### 2.3 Build options There are two groups of CMake options. There are many options defined by CMake. Here are some particularly useful options: @@ -154,6 +167,7 @@ [TOC](#TOC)
+ ### 2.4 Dependencies The following Exiv2 features require external libraries: @@ -193,6 +207,7 @@ [TOC](#TOC)
+ ### 2.5 Building and linking your code with Exiv2 There are detailed platform notes about compiling and linking in `releasenotes/{platform}/ReadMe.txt` @@ -219,6 +234,7 @@ [TOC](#TOC)
+ ### 2.6 Consuming Exiv2 with CMake When exiv2 is installed, the files required to consume Exiv2 are installed in `${CMAKE_INSTALL_PREFIX}/lib/cmake/exiv2` @@ -249,6 +265,7 @@ [TOC](#TOC)
+ ### 2.7 Using pkg-config to compile and link your code with Exiv2 When exiv2 is installed, the file exiv2.pc used by pkg-config is installed in `${CMAKE_INSTALL_PREFIX}/lib/pkgconfig` You will need to set the following in your environment: @@ -273,6 +290,7 @@ [TOC](#TOC)
+ ### 2.8 Localisation Localisation is supported on a UNIX-like platform: Linux, macOS, Cygwin and MinGW/msys2. Localisation is not supported for Visual Studio builds. @@ -362,6 +380,7 @@ [TOC](#TOC)
+ ### 2.9 Building Exiv2 Documentation Building documentation requires installing special tools. You will probably prefer to @@ -372,7 +391,7 @@ ```bash $ cmake ..options.. -DEXIV2_BUILD_DOC=On -$ make doc +$ cmake --build . --target doc ``` To build the documentation, you must install the following products: @@ -383,6 +402,7 @@ [TOC](#TOC)
+ ### 2.10 Building Exiv2 Packages To enable the building of Exiv2 packages, use the CMake option `-DEXIV2_TEAM_PACKAGING=On`. @@ -405,7 +425,7 @@ $ cmake --build . --config Release ... [100%] Built target addmoddel -$ make package +$ cmake --build . --target package ... CPack: - package: /path/to/exiv2/build/exiv2-0.27.1-Linux.tar.gz generated. ``` @@ -413,17 +433,15 @@ 2) Source Package ```bash -$ make package_source +$ cmake --build . --target package_source Run CPack packaging tool for source... ... CPack: - package: /path/to/exiv2/build/exiv2-0.27.1-Source.tar.gz generated. ``` -You may prefer to run `$ cmake --build . --config Release --target package_source` - - [TOC](#TOC)
+ ### 2.11 Debugging Exiv2 1) Generating and installing a debug library @@ -507,7 +525,7 @@ With the Unix Makefile generator, the targets can be listed: ```bash -$ make help +$ cmake --build . --target help The following are some of the valid targets for this Makefile: ... all (the default if no target is provided) ... clean @@ -518,6 +536,7 @@ [TOC](#TOC)
+ ### 2.12 Building Exiv2 with **clang** and other build chains 1) On Linux @@ -550,6 +569,7 @@ [TOC](#TOC)
+ ### 2.13 Building Exiv2 with ccache To speed up compilation, the utility ccache can be installed to cache the output of the compiler. This greatly speeds up the build when you frequently built code that has not been modified. @@ -566,16 +586,17 @@ $ cd $ mkdir build ; cd build ; cd build $ cmake .. -G "Unix Makefiles" -DBUILD_WITH_CCACHE=On -$ make +$ cmake --build . # Build again to appreciate the performance gain -$ make clean -$ make +$ cmake --build . --target clean +$ cmake --build . ``` Due to the way in which ccache is installed in Fedora (and other Linux distros), ccache effectively replaces the compiler. A default build or **-DBUILD\_WITH\_CCACHE=Off** is not effective and the environment variable CCACHE_DISABLE is required to disable ccache. [https://github.com/Exiv2/exiv2/issues/361](https://github.com/Exiv2/exiv2/issues/361) [TOC](#TOC)
+ ### 2.14 Thread Safety Exiv2 heavily relies on standard C++ containers. Static or global variables are used read-only, with the exception of the XMP namespace registration function (see below). Thus Exiv2 is thread safe in the same sense as C++ containers: @@ -599,10 +620,11 @@ ... } ``` -The use of the _**thread unsafe function**_ Exiv2::enableBMFF(true) is discussed in [2.19 Support for bmff files](#2-19) +The use of the _**thread unsafe function**_ Exiv2::enableBMFF(true) is discussed in [2.19 Support for BMFF files (e.g., CR3, HEIF, HEIC, AVIF, and JPEG XL)](#2-19) [TOC](#TOC)
+ ### 2.15 Library Initialisation and Cleanup As discussed in the section on Thread Safety, Exiv2 classes for Exif and IPTC metadata are fully reentrant and require no initialisation or cleanup. @@ -621,19 +643,20 @@ [TOC](#TOC)
+ ### 2.16 Cross Platform Build and Test on Linux for MinGW You can cross compile Exiv2 on Linux for MinGW. We have used the following method on **Fedora** and believe this is also possible on Ubuntu and other distros. Detailed instructions are provided here for **Fedora**. ### Cross Build and Test On Fedora -####1 Install the cross platform build tools +#### 1 Install the cross platform build tools ```bash $ sudo dnf install mingw64-gcc-c++ mingw64-filesystem mingw64-expat mingw64-zlib cmake make ``` -####2 Install Dependancies +#### 2 Install Dependancies You will need to install x86_64 libraries to support the options you wish to use. By default, you will need libz and expat. Your `dnf` command above has installed them for you. If you wish to use features such as `webready` you should install openssl and libcurl as follows: @@ -648,7 +671,7 @@ ... ``` -####3 Get the code and build +#### 3 Get the code and build ```bash $ git clone://github.com/exiv2/exiv2 --branch 0.27-maintenance exiv2 @@ -670,7 +693,7 @@ The options available for cross-compiling are the same as provided for all builds. See: [Build Options](#2-3) -####4 Copy "system dlls" in the bin directory +#### 4 Copy "system dlls" in the bin directory These DLLs are required to execute the cross-platform build in the bin from Windows @@ -680,7 +703,7 @@ done ``` -####5 Executing exiv2 in wine +#### 5 Executing exiv2 in wine You may wish to use wine to execute exiv2 from the command prompt. To do this: @@ -700,7 +723,7 @@ If you have not installed wine, Fedora will offer to install it for you. -####6 Running the test suite +#### 6 Running the test suite On a default wine installation, you are in the MSDOS/cmd.exe prompt. You cannot execute the exiv2 test suite in this environment as you require python3 and MSYS/bash to run the suite. @@ -722,16 +745,17 @@ $ cd //Mac/Home/gnu/github/exiv2/0.27/maintenance/build_mingw_fedora $ export EXIV2_BINDIR=$pwd/bin $ cd ../test -$ make tests +$ make test ``` You will find that 3 tests fail at the end of the test suite. It is safe to ignore those minor exceptions. [TOC](#TOC)
+ ### 2.17 Building with C++11 and other compilers -Exiv2 uses the default compiler for your system. Exiv2 v0.27 was written to the C++ 1998 standard and uses auto\_ptr. The C++11 and C++14 compilers will issue deprecation warnings about auto\_ptr. As _auto\_ptr support has been removed from C++17, you cannot build Exiv2 v0.27 with C++17 or later compilers._ Exiv2 v1.00 and later do not use auto\_ptr and will build with all modern C++ Standard Compilers. +Exiv2 with use the `-DCMAKE_CXX_STANDARD=98` compiler. Exiv2 v0.27 was written to the C++ 1998 standard and uses auto\_ptr. The C++11 and C++14 compilers will issue deprecation warnings about auto\_ptr. As _auto\_ptr support has been removed from C++17, you cannot build Exiv2 v0.27 with C++17 or later compilers._ Exiv2 v1.00 and later do not use auto\_ptr and will build with all modern C++ Standard Compilers. To build with C++11: @@ -739,7 +763,7 @@ $ cd $ mkdir build ; cd build $ cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_CXX_FLAGS=-Wno-deprecated -$ make +$ cmake --build . ``` The option -DCMAKE\_CXX\_STANDARD=11 specifies the C++ Language Standard. Possible values are 98, 11 or 14. @@ -750,6 +774,7 @@ [TOC](#TOC)
+ ### 2.18 Static and Shared Libraries You can build either static or shared libraries. Both can be linked with either static or shared run-time libraries. You specify the shared/static with the option `-BUILD_SHARED_LIBS=On|Off` You specify the run-time with the option `-DEXIV2_ENABLE_DYNAMIC_RUNTIME=On|Off`. The default for both options default is On. So you build shared and use the shared libraries which are `.dll` on Windows (msvc, Cygwin and MinGW/msys), `.dylib` on macOS and `.so` on Linux and UNIX. @@ -780,28 +805,31 @@ [TOC](#TOC)
-### 2.19 Support for bmff files (CR3, HEIF, HEIC, and AVIF) -**Attention is drawn to the possibility that bmff support may be the subject of patent rights. _Exiv2 shall not be held responsible for identifying any or all such patent rights. Exiv2 shall not be held responsible for the legal consequences of the use of this code_.** +### 2.19 Support for BMFF files (e.g., CR3, HEIF, HEIC, AVIF, and JPEG XL) + +**Attention is drawn to the possibility that BMFF support may be the subject of patent rights. _Exiv2 shall not be held responsible for identifying any or all such patent rights. Exiv2 shall not be held responsible for the legal consequences of the use of this code_.** -Access to the bmff code is guarded in two ways. Firstly, you have to build the library with the cmake option: `-DEXIV2_ENABLE_BMFF=On`. Secondly, the application must enable bmff support at run-time by calling the following function. +Access to the BMFF code is guarded in two ways. Firstly, you have to build the library with the cmake option: `-DEXIV2_ENABLE_BMFF=On`. Secondly, the application must enable BMFF support at run-time by calling the following function. ```cpp EXIV2API bool enableBMFF(bool enable); ``` -The return value from `enableBMFF()` is true if the library has been build with bmff support (cmake option -DEXIV2_ANABLE_BMFF=On). +The return value from `enableBMFF()` is true if the library has been build with BMFF support (cmake option -DEXIV2_ANABLE_BMFF=On). -Applications may wish to provide a preference setting to enable bmff support and thereby place the responsibility for the use of this code with the user of the application. +Applications may wish to provide a preference setting to enable BMFF support and thereby place the responsibility for the use of this code with the user of the application. [TOC](#TOC)
+ ## 3 License and Support All project resources are accessible from the project website. https://github.com/Exiv2/exiv2
+ ### 3.1 License Copyright (C) 2004-2021 Exiv2 authors. @@ -824,57 +852,82 @@ [TOC](#TOC)
+ ### 3.2 Support For new bug reports, feature requests and support: Please open an issue in Github. [https://github.com/exiv2/exiv2](https://github.com/exiv2/exiv2) [TOC](#TOC)
-## 4 Running the test suite -#### Different kinds of tests: +## 4 Test Suite -| Description | Language | Location | Command
_(in build directory)_ | CMake Option to Build | -|:-- |:-- |:-- |:-- |:-- | -| Run all tests | | | $ make tests | | -| Run all tests | | **Visual Studio Users** | > cmake --build . --target tests | | -| Bash tests | python | tests/bash\_tests | $ make bash_tests | -DEXIV2\_BUILD\_SAMPLES=On | -| Python tests | python | tests | $ make python_tests | -DEXIV2\_BUILD\_SAMPLES=On | -| Unit tests | C++ | unitTests | $ make unit_test | -DEXIV2\_BUILD\_UNIT\_TESTS=On | -| Version test | C++ | src/version.cpp | $ make version_test | Always in library | - -The term _**bash scripts**_ is historical. The implementation of the tests in this collection originally required bash. These -scripts have been rewritten in python. Visual Studio Users will appreciate the python implementation as it avoids the -installation of mingw/cygwin and special PATH settings. +You execute the Test Suite using CTest with the command `$ ctest`. + +The build creates 5 tests: bashTests, bugfixTests, tiffTests, unitTests and versionTests. You can run all tests or a subset. To list all available tests, execute ctest with the `-N` or `--show-only` option, which disables execution: + +```bash +.../build $ ctest -N +Test project .../build + Test #1: bashTests + Test #2: bugfixTests + Test #3: tiffTests + Test #4: versionTests + Test #5: unitTests + +Total Tests: 5 +.../build $ +``` + +ctest provides many option and the following show common use-case scenarios: + +```bash +$ ctest # run all tests and display summary +$ ctest --output-on-failure # run all tests and output failures +$ ctest -R bugfix # run only bugfixTests and display summary +$ ctest -R bugfix --verbose # run only bugfixTests and display all output +``` + +| Name | Language | Location | Command
_(in build directory)_ | CMake Option to Build | +|:-- |:-- |:-- |:-- |:-- | +| bashTests | python | tests/bash\_tests | $ ctest -R bash | -DEXIV2\_BUILD\_SAMPLES=On | +| bugfixTests | python | tests/bugfixes | $ ctest -R bugfix | -DEXIV2\_BUILD\_SAMPLES=On | +| tiffTests | python | tests/tiff_test | $ ctest -R tiff | -DEXIV2\_BUILD\_SAMPLES=On | +| unitTests | C++ | unitTests/ | $ ctest -R unit | -DEXIV2\_BUILD\_UNIT\_TESTS=On | +| versionTests | C++ | src/version.cpp | $ ctest -R version | Always in library | + +The term _**bashTests**_ is historical. These tests were originally bash scripts and have been rewritten in python. +Visual Studio Users will appreciate the python implementation as it avoids the installation of mingw/cygwin and special PATH settings. #### Environment Variables used by the test suite: If you build the code in the directory \build, tests will run using the default values of Environment Variables. -| Variable | Default | Platforms | Purpose | -|:-- |:-- |:-- |:-- | -| EXIV2_BINDIR | **\/build/bin** | All Platforms | Path of built binaries (exiv2.exe) | -| EXIV2_PORT | **12762**
**12671**
**12760** | Cygwin
MinGW/msys2
Other Platforms | Test TCP/IP Port | -| EXIV2_HTTP | **http://localhost** | All Platforms | Test http server | -| EXIV2_ECHO | _**not set**_ | All Platforms | For debugging bash scripts | -| VALGRIND | _**not set**_ | All Platforms | For debugging bash scripts | -| VERBOSE | _**not set**_ | All Platforms | Causes make to report its actions | +| Variable | Default | Platforms | Purpose | +|:-- |:-- |:-- |:-- | +| EXIV2_BINDIR | **\/build/bin** | All Platforms | Path of built binaries (exiv2.exe) | +| EXIV2_PORT | **12762**
**12671**
**12760** | Cygwin
MinGW/msys2
Other Platforms | Test TCP/IP Port | +| EXIV2_HTTP | **http://localhost** | All Platforms | Test http server | +| EXIV2_ECHO | _**not set**_ | All Platforms | For debugging bashTests | +| VALGRIND | _**not set**_ | All Platforms | For debugging bashTests | +| VERBOSE | _**not set**_ | Makefile platforms | Instructs make to report its actions | | PATH
DYLD\_LIBRARY\_PATH
LD\_LIBRARY\_PATH | $EXIV2\_BINDIR/../lib | Windows
macOS
Other platforms | Path of dynamic libraries | The Variable EXIV2\_PORT or EXIV2\_HTTP can be set to None to skip http tests. The http server is started with the command `python3 -m http.server $port`. On Windows, you will need to run this manually _**once**_ to authorise the firewall to permit python to use the port. [TOC](#TOC)
-### 4.1 Running tests on a UNIX-like system +### 4.1 Running tests on Unix-like systems You can run tests directly from the build: ```bash $ cmake .. -G "Unix Makefiles" -DEXIV2_BUILD_UNIT_TESTS=On -$ make -... lots of output ... -$ make tests +... lots of output and build summary ... +$ cmake --build . ... lots of output ... +$ ctest +... test summary ... $ ``` @@ -882,13 +935,13 @@ ```bash $ cd /build -$ make bash_tests +$ ctest -R bash --verbose addmoddel_test (testcases.TestCases) ... ok .... Ran 176 tests in 9.526s OK (skipped=6) -$ make python_tests +$ ctest -R bugfix --verbose ... lots of output ... test_run (tiff_test.test_tiff_test_program.TestTiffTestProg) ... ok ---------------------------------------------------------------------- @@ -901,22 +954,27 @@
### 4.2 Running tests on Visual Studio builds from cmd.exe -**Caution:** _The python3 interpreter must be on the PATH, build for DOS, and called python3.exe. I copied the python.exe program: +**Caution:** _The python3 interpreter must be on the PATH, build for DOS, and called python3.exe._ I copied the python.exe program: ```cmd > copy c:\Python37\python.exe c:\Python37\python3.exe -> set "PATH=c:\Python37;%PATH% +> set PATH=c:\Python37;%PATH% ``` -You can execute the test suite as described for UNIX-like systems. -The main difference is that you must use cmake to initiate the test -as make is not a system utility on Windows. +You can execute the test suite in a similar manner to that described for UNIX-like systems. You _**must**_ provide the `-C` config option to ctest for Visual Studio builds. -```bash +```cmd > cd /build -> cmake --build . --target tests -> cmake --build . --target python_tests +> ctest -C Release +> ctest -C Release -R bugfix --verbose ``` +Visual Studio can build different configs as follows: + +```cmd +> cmake --build . --config Release # or Debug or MinSizeRel or RelWithDebInfo +> ctest -C Release +``` +The default for **cmake** config option `--config` is `Release`. **ctest** does not have a default for config option `-C`. ##### Running tests from cmd.exe @@ -931,20 +989,20 @@ c:\...\exiv2\build>cmake .. -DEXIV2_BUILD_UNIT_TESTS=On -G "Visual Studio 16 2019" c:\...\exiv2\build>cmake --build . --config Release ... lots of output from compiler and linker ... -c:\...\exiv2\build> +c:\...\exiv2\build>ctest -C Release ``` If you wish to use an environment variables, use set: ``` -set VERBOSE=1 -cmake --build . --config Release --target tests -set VERBOSE= +set EXIV2_PORT=54321 +ctest -C Release --verbose -R bash +set EXIV2_PORT= ``` [TOC](#TOC)
-### 4.3 Unit tests +### 4.3 Unit Tests The code for the unit tests is in `/unitTests`. To include unit tests in the build, use the *cmake* option `-DEXIV2_BUILD_UNIT_TESTS=On`. @@ -963,23 +1021,23 @@ [TOC](#TOC)
-### 4.4 Python tests +### 4.4 Bugfix Tests -You can run the python tests from the build directory: +You can run the bugfix tests from the build directory: ```bash $ cd /build -$ make python_tests +$ ctest -R bugfix ``` If you wish to run in verbose mode: ```bash $ cd /build -$ make python_tests VERBOSE=1 +$ ctest -R bugfix --verbose ``` -The python tests are stored in the directory tests and you can run them all with the command: +The bugfix tests are stored in directory tests/ and you can run them all with the command: ```bash $ cd /tests @@ -998,26 +1056,12 @@ ```bash $ cd /build -$ make python_tests 2>&1 | grep FAIL +$ ctest -R bugfix --verbose 2>&1 | grep FAIL ``` [TOC](#TOC) -
-### 4.5 Test Summary - -| *Tests* | Unix Style Platforms _(bash)_ | Visual Studio _(cmd.exe)_ | -|:-- |:--- |:-- | -| | $ cd \/build | \> cd \/build | -| tests | $ make tests | \> cmake --build . --config Release --target tests | -| bash_tests | $ make bash_tests | \> cmake --build . --config Release --target bash_tests | -| python_tests | $ make python_tests | \> cmake --build . --config Release --target python_tests | -| unit_test | $ make unit_test | \> cmake --build . --config Release --target unit_test | -| version_test | $ make version_test | \> cmake --build . --config Release --target version_test | - -The name **bash_tests** is historical. They are implemented in python. - -[TOC](#TOC)
+ ## 5 Platform Notes There are many ways to set up and configure your platform. The following notes are provided as a guide. @@ -1048,6 +1092,7 @@ [TOC](#TOC)
+ ### 5.2 macOS You will need to install Xcode and the Xcode command-line tools to build on macOS. @@ -1058,6 +1103,7 @@ [TOC](#TOC)
+ ### 5.3 MinGW/msys2 Please note that the platform MinGW/msys2 32 is obsolete and superceded by MinGW/msys2 64. @@ -1088,12 +1134,7 @@ Install tools and dependencies: ```bash -for i in base-devel git coreutils dos2unix tar diffutils make \ - mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb \ - mingw-w64-x86_64-cmake mingw-w64-x86_64-gettext mingw-w64-x86_64-python3 \ - mingw-w64-x86_64-libexpat mingw-w64-x86_64-libiconv mingw-w64-x86_64-zlib \ - mingw-w64-x86_64-gtest -do (echo y | pacman -S $i) ; done +pacman --noconfirm -S --needed base-devel mingw-w64-x86_64-{toolchain,cmake,expat,gettext,gtest,libiconv,python-lxml,zlib} ``` #### Download exiv2 from github and build @@ -1121,6 +1162,7 @@ [TOC](#TOC)
+ ### 5.4 Cygwin/64 Please note that the platform Cygwin/32 is obsolete and superceded by Cygwin/64. @@ -1150,6 +1192,7 @@ [TOC](#TOC)
+ ### 5.5 Visual Studio We recommend that you use Conan to build Exiv2 using Visual Studio. Exiv2 v0.27 can be built with Visual Studio versions 2008 and later. We actively support and build with Visual Studio 2015, 2017 and 2019. @@ -1169,6 +1212,7 @@ [TOC](#TOC)
+ ### 5.6 Unix Exiv2 can be built on many Unix and Linux distros. With v0.27.2, we are starting to actively support the Unix Distributions NetBSD and FreeBSD. For v0.27.3, I have added support for Solaris 11.4 @@ -1258,5 +1302,5 @@ [TOC](#TOC) -Written by Robin Mills
robin@clanmills.com
Updated: 2021-08-10 +Written by Robin Mills
robin@clanmills.com
Updated: 2021-12-20 diff -Nru exiv2-0.27.5/samples/CMakeLists.txt exiv2-0.27.6/samples/CMakeLists.txt --- exiv2-0.27.5/samples/CMakeLists.txt 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/samples/CMakeLists.txt 2023-01-18 21:57:53.000000000 +0000 @@ -40,7 +40,6 @@ set_target_properties(${target} PROPERTIES COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS}) list(APPEND APPLICATIONS ${target}) - add_test( ${target}_test ${target} ) target_include_directories(${target} PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find unused.h if ( NOT ${target} MATCHES ".*test.*") # don't install tests install( TARGETS ${target} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff -Nru exiv2-0.27.5/samples/geotag.cpp exiv2-0.27.6/samples/geotag.cpp --- exiv2-0.27.5/samples/geotag.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/samples/geotag.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -636,9 +636,9 @@ , "Exif.Image.DateTime" , NULL }; - const char* dateString = dateStrings[0] ; - do { + for (size_t i = 0; !result && dateStrings[i]; i++) { + const char* dateString = dateStrings[i] ; try { Image::AutoPtr image = ImageFactory::open(path); if ( image.get() ) { @@ -649,7 +649,7 @@ if ( result && pS ) *pS = exifData[dateString].toString(); } } catch ( ... ) {}; - } while ( !result && ++dateString ); + } return result ; } diff -Nru exiv2-0.27.5/src/bmffimage.cpp exiv2-0.27.6/src/bmffimage.cpp --- exiv2-0.27.5/src/bmffimage.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/bmffimage.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -482,10 +482,10 @@ parseTiff(Internal::Tag::cmt4, box_length); break; case TAG_exif: - parseTiff(Internal::Tag::root, box_length,address+8); + parseTiff(Internal::Tag::root, buffer_size, io_->tell()); break; case TAG_xml: - parseXmp(box_length,io_->tell()); + parseXmp(buffer_size, io_->tell()); break; case TAG_thmb: switch (version) { @@ -533,7 +533,7 @@ // hunt for "II" or "MM" long eof = 0xffffffff; // impossible value for punt long punt = eof; - for ( long i = 0 ; i < exif.size_ -8 && punt==eof ; i+=2) { + for (long i = 0; i < exif.size_ - 9 && punt == eof; ++i) { if ( exif.pData_[i] == exif.pData_[i+1] ) if ( exif.pData_[i] == 'I' || exif.pData_[i] == 'M' ) punt = i; @@ -568,29 +568,27 @@ void BmffImage::parseXmp(uint64_t length,uint64_t start) { - if (length > 8) { - enforce(start <= io_->size(), kerCorruptedMetadata); - enforce(length <= io_->size() - start, kerCorruptedMetadata); + enforce(start <= io_->size(), kerCorruptedMetadata); + enforce(length <= io_->size() - start, kerCorruptedMetadata); - long restore = io_->tell() ; - enforce(start <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); - io_->seek(static_cast(start),BasicIo::beg); - - enforce(length < static_cast(std::numeric_limits::max()), kerCorruptedMetadata); - DataBuf xmp(static_cast(length+1)); - xmp.pData_[length]=0 ; // ensure xmp is null terminated! - if ( io_->read(xmp.pData_, static_cast(length)) != static_cast(length) ) - throw Error(kerInputDataReadFailed); - if ( io_->error() ) - throw Error(kerFailedToReadImageData); - try { - Exiv2::XmpParser::decode(xmpData(), std::string(reinterpret_cast(xmp.pData_))); - } catch (...) { - throw Error(kerFailedToReadImageData); - } + long restore = io_->tell() ; + enforce(start <= static_cast(std::numeric_limits::max()), kerCorruptedMetadata); + io_->seek(static_cast(start),BasicIo::beg); - io_->seek(restore,BasicIo::beg); + enforce(length < static_cast(std::numeric_limits::max()), kerCorruptedMetadata); + DataBuf xmp(static_cast(length+1)); + xmp.pData_[length]=0 ; // ensure xmp is null terminated! + if ( io_->read(xmp.pData_, static_cast(length)) != static_cast(length) ) + throw Error(kerInputDataReadFailed); + if ( io_->error() ) + throw Error(kerFailedToReadImageData); + try { + Exiv2::XmpParser::decode(xmpData(), std::string(reinterpret_cast(xmp.pData_))); + } catch (...) { + throw Error(kerFailedToReadImageData); } + + io_->seek(restore,BasicIo::beg); } void BmffImage::parseCr3Preview(DataBuf &data, @@ -713,7 +711,7 @@ void BmffImage::writeMetadata() { // bmff files are read-only - throw(Error(kerInvalidSettingForImage, "Image comment", "BMFF")); + throw(Error(kerWritingImageFormatUnsupported, "BMFF")); } // BmffImage::writeMetadata // ************************************************************************* diff -Nru exiv2-0.27.5/src/canonmn_int.cpp exiv2-0.27.6/src/canonmn_int.cpp --- exiv2-0.27.5/src/canonmn_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/canonmn_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -1669,9 +1669,9 @@ { 33, "Carl Zeiss Makro-Planar T* 50mm f/2 ZE" }, // 12 { 33, "Carl Zeiss Makro-Planar T* 100mm f/2 ZE" }, // 13 { 33, "Carl Zeiss Apo-Sonnar T* 135mm f/2 ZE" }, // 14 - { 35, "Canon EF 35-80mm f/4-5.6" }, + { 35, "Canon EF 35-80mm f/4-5.6 II" }, { 36, "Canon EF 38-76mm f/4.5-5.6" }, - { 37, "Canon EF 35-80mm f/4-5.6" }, + { 37, "Canon EF 35-80mm f/4-5.6 III" }, { 37, "Tamron 70-200mm f/2.8 Di LD IF Macro" }, // 1 { 37, "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro"}, // 2 { 37, "Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical [IF]" }, // 3 diff -Nru exiv2-0.27.5/src/CMakeLists.txt exiv2-0.27.6/src/CMakeLists.txt --- exiv2-0.27.5/src/CMakeLists.txt 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/CMakeLists.txt 2023-01-18 21:57:53.000000000 +0000 @@ -19,6 +19,7 @@ fujimn_int.cpp fujimn_int.hpp helper_functions.cpp helper_functions.hpp image_int.cpp image_int.hpp + jp2image_int.cpp jp2image_int.hpp makernote_int.cpp makernote_int.hpp minoltamn_int.cpp minoltamn_int.hpp nikonmn_int.cpp nikonmn_int.hpp diff -Nru exiv2-0.27.5/src/convert.cpp exiv2-0.27.6/src/convert.cpp --- exiv2-0.27.5/src/convert.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/convert.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -48,7 +48,7 @@ #endif #include -#if defined WIN32 && !defined __CYGWIN__ +#if defined _WIN32 && !defined __CYGWIN__ # include #endif @@ -71,7 +71,7 @@ // ***************************************************************************** // local declarations namespace { -#if defined WIN32 && !defined __CYGWIN__ +#if !defined EXV_HAVE_ICONV && defined _WIN32 && !defined __CYGWIN__ // Convert string charset with Windows functions. bool convertStringCharsetWindows(std::string& str, const char* from, const char* to); #endif @@ -1354,7 +1354,7 @@ bool ret = false; #if defined EXV_HAVE_ICONV ret = convertStringCharsetIconv(str, from, to); -#elif defined WIN32 && !defined __CYGWIN__ +#elif defined _WIN32 && !defined __CYGWIN__ ret = convertStringCharsetWindows(str, from, to); #else # ifndef SUPPRESS_WARNINGS @@ -1372,7 +1372,7 @@ using namespace Exiv2; -#if defined WIN32 && !defined __CYGWIN__ +#if !defined EXV_HAVE_ICONV && defined _WIN32 && !defined __CYGWIN__ bool swapBytes(std::string& str) { // Naive byte-swapping, I'm sure this can be done more efficiently @@ -1526,7 +1526,7 @@ return ret; } -#endif // defined WIN32 && !defined __CYGWIN__ +#endif // !defined EXV_HAVE_ICONV && defined _WIN32 && !defined __CYGWIN__ #if defined EXV_HAVE_ICONV bool convertStringCharsetIconv(std::string& str, const char* from, const char* to) { diff -Nru exiv2-0.27.5/src/exif.cpp exiv2-0.27.6/src/exif.cpp --- exiv2-0.27.5/src/exif.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/exif.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -35,6 +35,7 @@ #include "types.hpp" #include "error.hpp" #include "basicio.hpp" +#include "safe_op.hpp" #include "tiffimage.hpp" #include "tiffimage_int.hpp" #include "tiffcomposite_int.hpp" // for Tag::root @@ -964,7 +965,7 @@ { long sum = 0; for (long i = 0; i < md.count(); ++i) { - sum += md.toLong(i); + sum = Safe::add(sum, md.toLong(i)); } return sum; } diff -Nru exiv2-0.27.5/src/image.cpp exiv2-0.27.6/src/image.cpp --- exiv2-0.27.5/src/image.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/image.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -882,6 +882,8 @@ if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) { return BasicIo::AutoPtr(new CurlIo(path)); // may throw } +#else + (void)(useCurl); #endif if (fProt == pHttp) @@ -892,8 +894,6 @@ return BasicIo::AutoPtr(new XPathIo(path)); // may throw return BasicIo::AutoPtr(new FileIo(path)); - - (void)(useCurl); } // ImageFactory::createIo #ifdef EXV_UNICODE_PATH @@ -909,6 +909,8 @@ if (useCurl && (fProt == pHttp || fProt == pHttps || fProt == pFtp)) { return BasicIo::AutoPtr(new CurlIo(wpath)); } +#else + (void)(useCurl); #endif if (fProt == pHttp) return BasicIo::AutoPtr(new HttpIo(wpath)); diff -Nru exiv2-0.27.5/src/jp2image.cpp exiv2-0.27.6/src/jp2image.cpp --- exiv2-0.27.5/src/jp2image.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/jp2image.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -21,137 +21,85 @@ // ***************************************************************************** // included header files -#include "config.h" - #include "jp2image.hpp" -#include "tiffimage.hpp" -#include "image.hpp" -#include "image_int.hpp" + #include "basicio.hpp" +#include "config.h" #include "enforce.hpp" #include "error.hpp" #include "futils.hpp" -#include "types.hpp" +#include "image.hpp" +#include "image_int.hpp" +#include "jp2image_int.hpp" #include "safe_op.hpp" +#include "tiffimage.hpp" +#include "types.hpp" // + standard includes -#include -#include -#include #include #include +#include +#include +#include +const size_t boxSize = sizeof(Exiv2::Internal::Jp2BoxHeader); // JPEG-2000 box types -const uint32_t kJp2BoxTypeJp2Header = 0x6a703268; // 'jp2h' -const uint32_t kJp2BoxTypeImageHeader = 0x69686472; // 'ihdr' -const uint32_t kJp2BoxTypeColorHeader = 0x636f6c72; // 'colr' -const uint32_t kJp2BoxTypeUuid = 0x75756964; // 'uuid' -const uint32_t kJp2BoxTypeClose = 0x6a703263; // 'jp2c' - -// from openjpeg-2.1.2/src/lib/openjp2/jp2.h -/*#define JPIP_JPIP 0x6a706970*/ - -#define JP2_JP 0x6a502020 /**< JPEG 2000 signature box */ -#define JP2_FTYP 0x66747970 /**< File type box */ -#define JP2_JP2H 0x6a703268 /**< JP2 header box (super-box) */ -#define JP2_IHDR 0x69686472 /**< Image header box */ -#define JP2_COLR 0x636f6c72 /**< Colour specification box */ -#define JP2_JP2C 0x6a703263 /**< Contiguous codestream box */ -#define JP2_URL 0x75726c20 /**< Data entry URL box */ -#define JP2_PCLR 0x70636c72 /**< Palette box */ -#define JP2_CMAP 0x636d6170 /**< Component Mapping box */ -#define JP2_CDEF 0x63646566 /**< Channel Definition box */ -#define JP2_DTBL 0x6474626c /**< Data Reference box */ -#define JP2_BPCC 0x62706363 /**< Bits per component box */ -#define JP2_JP2 0x6a703220 /**< File type fields */ - -/* For the future */ -/* #define JP2_RES 0x72657320 */ /**< Resolution box (super-box) */ -/* #define JP2_JP2I 0x6a703269 */ /**< Intellectual property box */ -/* #define JP2_XML 0x786d6c20 */ /**< XML box */ -/* #define JP2_UUID 0x75756994 */ /**< UUID box */ -/* #define JP2_UINF 0x75696e66 */ /**< UUID info box (super-box) */ -/* #define JP2_ULST 0x756c7374 */ /**< UUID list box */ +const uint32_t kJp2BoxTypeSignature = 0x6a502020; // signature box, required, +const uint32_t kJp2BoxTypeFileTypeBox = 0x66747970; // File type box, required +const uint32_t kJp2BoxTypeHeader = 0x6a703268; // Jp2 Header Box, required, Superbox +const uint32_t kJp2BoxTypeImageHeader = 0x69686472; // Image Header Box ('ihdr'), required, +const uint32_t kJp2BoxTypeColorSpec = 0x636f6c72; // Color Specification box ('colr'), required +const uint32_t kJp2BoxTypeUuid = 0x75756964; // 'uuid' +const uint32_t kJp2BoxTypeClose = 0x6a703263; // 'jp2c' // JPEG-2000 UUIDs for embedded metadata // // See http://www.jpeg.org/public/wg1n2600.doc for information about embedding IPTC-NAA data in JPEG-2000 files -// See http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf for information about embedding XMP data in JPEG-2000 files +// See http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf for information about embedding XMP data in JPEG-2000 +// files const unsigned char kJp2UuidExif[] = "JpgTiffExif->JP2"; const unsigned char kJp2UuidIptc[] = "\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38"; -const unsigned char kJp2UuidXmp[] = "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac"; +const unsigned char kJp2UuidXmp[] = "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac"; // See section B.1.1 (JPEG 2000 Signature box) of JPEG-2000 specification -const unsigned char Jp2Signature[12] = { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a }; +const unsigned char Jp2Signature[12] = {0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a}; -const unsigned char Jp2Blank[] = { 0x00,0x00,0x00,0x0c,0x6a,0x50,0x20,0x20,0x0d,0x0a,0x87,0x0a,0x00,0x00,0x00,0x14, - 0x66,0x74,0x79,0x70,0x6a,0x70,0x32,0x20,0x00,0x00,0x00,0x00,0x6a,0x70,0x32,0x20, - 0x00,0x00,0x00,0x2d,0x6a,0x70,0x32,0x68,0x00,0x00,0x00,0x16,0x69,0x68,0x64,0x72, - 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x07,0x07,0x00,0x00,0x00,0x00, - 0x00,0x0f,0x63,0x6f,0x6c,0x72,0x01,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x00, - 0x00,0x6a,0x70,0x32,0x63,0xff,0x4f,0xff,0x51,0x00,0x29,0x00,0x00,0x00,0x00,0x00, - 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07, - 0x01,0x01,0xff,0x64,0x00,0x23,0x00,0x01,0x43,0x72,0x65,0x61,0x74,0x6f,0x72,0x3a, - 0x20,0x4a,0x61,0x73,0x50,0x65,0x72,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20, - 0x31,0x2e,0x39,0x30,0x30,0x2e,0x31,0xff,0x52,0x00,0x0c,0x00,0x00,0x00,0x01,0x00, - 0x05,0x04,0x04,0x00,0x01,0xff,0x5c,0x00,0x13,0x40,0x40,0x48,0x48,0x50,0x48,0x48, - 0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0xff,0x90,0x00,0x0a,0x00,0x00, - 0x00,0x00,0x00,0x2d,0x00,0x01,0xff,0x5d,0x00,0x14,0x00,0x40,0x40,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x93,0xcf,0xb4, - 0x04,0x00,0x80,0x80,0x80,0x80,0x80,0xff,0xd9 - }; - -//! @cond IGNORE -struct Jp2BoxHeader -{ - uint32_t length; - uint32_t type; -}; - -struct Jp2ImageHeaderBox -{ - uint32_t imageHeight; - uint32_t imageWidth; - uint16_t componentCount; - uint8_t bitsPerComponent; - uint8_t compressionType; - uint8_t colorspaceIsUnknown; - uint8_t intellectualPropertyFlag; - uint16_t compressionTypeProfile; -}; - -struct Jp2UuidBox -{ - uint8_t uuid[16]; -}; -//! @endcond +const unsigned char Jp2Blank[] = { + 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x66, 0x74, + 0x79, 0x70, 0x6a, 0x70, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x70, 0x32, 0x20, 0x00, 0x00, 0x00, 0x2d, + 0x6a, 0x70, 0x32, 0x68, 0x00, 0x00, 0x00, 0x16, 0x69, 0x68, 0x64, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x63, 0x6f, 0x6c, 0x72, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x70, 0x32, 0x63, 0xff, 0x4f, 0xff, 0x51, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x07, 0x01, 0x01, 0xff, 0x64, 0x00, 0x23, 0x00, 0x01, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x3a, + 0x20, 0x4a, 0x61, 0x73, 0x50, 0x65, 0x72, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, + 0x39, 0x30, 0x30, 0x2e, 0x31, 0xff, 0x52, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, 0x04, 0x00, + 0x01, 0xff, 0x5c, 0x00, 0x13, 0x40, 0x40, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, 0x50, 0x48, 0x48, + 0x50, 0x48, 0x48, 0x50, 0xff, 0x90, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x01, 0xff, 0x5d, + 0x00, 0x14, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x93, 0xcf, 0xb4, 0x04, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0xff, 0xd9}; // ***************************************************************************** // class member definitions namespace Exiv2 { - - Jp2Image::Jp2Image(BasicIo::AutoPtr io, bool create) - : Image(ImageType::jp2, mdExif | mdIptc | mdXmp, io) + Jp2Image::Jp2Image(BasicIo::AutoPtr io, bool create) : Image(ImageType::jp2, mdExif | mdIptc | mdXmp, io) { - if (create) - { - if (io_->open() == 0) - { + if (create) { + if (io_->open() == 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Exiv2::Jp2Image:: Creating JPEG2000 image to memory" << std::endl; #endif IoCloser closer(*io_); - if (io_->write(Jp2Blank, sizeof(Jp2Blank)) != sizeof(Jp2Blank)) - { + if (io_->write(Jp2Blank, sizeof(Jp2Blank)) != sizeof(Jp2Blank)) { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Exiv2::Jp2Image:: Failed to create JPEG2000 image on memory" << std::endl; #endif } } } - } // Jp2Image::Jp2Image + } // Jp2Image::Jp2Image std::string Jp2Image::mimeType() const { @@ -162,14 +110,14 @@ { // Todo: implement me! throw(Error(kerInvalidSettingForImage, "Image comment", "JP2")); - } // Jp2Image::setComment + } // Jp2Image::setComment - static void lf(std::ostream& out,bool& bLF) + static void lf(std::ostream& out, bool& bLF) { - if ( bLF ) { + if (bLF) { out << std::endl; out.flush(); - bLF = false ; + bLF = false; } } @@ -178,221 +126,226 @@ union { uint32_t i; char c[4]; - } e = { 0x01000000 }; + } e = {0x01000000}; - return e.c[0]?true:false; + return e.c[0] ? true : false; } static std::string toAscii(long n) { - const char* p = (const char*) &n; + const char* p = (const char*)&n; std::string result; bool bBigEndian = isBigEndian(); - for ( int i = 0 ; i < 4 ; i++) { - result += p[ bBigEndian ? i : (3-i) ]; + for (int i = 0; i < 4; i++) { + result += p[bBigEndian ? i : (3 - i)]; } return result; } -static void boxes_check(size_t b,size_t m) -{ - if ( b > m ) { + static void boxes_check(size_t b, size_t m) + { + if (b > m) { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::readMetadata box maximum exceeded" << std::endl; + std::cout << "Exiv2::Jp2Image::readMetadata box maximum exceeded" << std::endl; #endif - throw Error(kerCorruptedMetadata); + throw Error(kerCorruptedMetadata); + } } -} void Jp2Image::readMetadata() { #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "Exiv2::Jp2Image::readMetadata: Reading JPEG-2000 file " << io_->path() << std::endl; #endif - if (io_->open() != 0) - { + if (io_->open() != 0) { throw Error(kerDataSourceOpenFailed, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type - if (!isJp2Type(*io_, true)) - { - if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); + if (!isJp2Type(*io_, false)) { throw Error(kerNotAnImage, "JPEG-2000"); } - long position = 0; - Jp2BoxHeader box = {0,0}; - Jp2BoxHeader subBox = {0,0}; - Jp2ImageHeaderBox ihdr = {0,0,0,0,0,0,0,0}; - Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - size_t boxes = 0 ; - size_t boxem = 1000 ; // boxes max - - while (io_->read((byte*)&box, sizeof(box)) == sizeof(box)) - { - boxes_check(boxes++,boxem ); - position = io_->tell(); + long position = 0; + Internal::Jp2BoxHeader box = {0, 0}; + Internal::Jp2BoxHeader subBox = {0, 0}; + Internal::Jp2ImageHeaderBox ihdr = {0, 0, 0, 0, 0, 0, 0}; + Internal::Jp2UuidBox uuid = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + size_t boxes = 0; + size_t boxem = 1000; // boxes max + uint32_t lastBoxTypeRead = 0; + bool boxSignatureFound = false; + bool boxFileTypeFound = false; + + while (io_->read((byte*)&box, sizeof(box)) == sizeof(box)) { + boxes_check(boxes++, boxem); + position = io_->tell(); box.length = getLong((byte*)&box.length, bigEndian); - box.type = getLong((byte*)&box.type, bigEndian); + box.type = getLong((byte*)&box.type, bigEndian); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::readMetadata: " - << "Position: " << position - << " box type: " << toAscii(box.type) - << " length: " << box.length + << "Position: " << position << " box type: " << toAscii(box.type) << " length: " << box.length << std::endl; #endif - enforce(box.length <= sizeof(box)+io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata); + enforce(box.length <= sizeof(box) + io_->size() - io_->tell(), Exiv2::kerCorruptedMetadata); - if (box.length == 0) return ; + if (box.length == 0) + return; - if (box.length == 1) - { - // FIXME. Special case. the real box size is given in another place. + if (box.length == 1) { + /// \todo In this case, the real box size is given in XLBox (bytes 8-15) } - switch(box.type) - { - case kJp2BoxTypeJp2Header: - { + switch (box.type) { + case kJp2BoxTypeSignature: { + if (boxSignatureFound) // Only one is allowed + throw Error(kerCorruptedMetadata); + boxSignatureFound = true; + break; + } + case kJp2BoxTypeFileTypeBox: { + // This box shall immediately follow the JPEG 2000 Signature box + if (boxFileTypeFound || lastBoxTypeRead != kJp2BoxTypeSignature) { // Only one is allowed + throw Error(kerCorruptedMetadata); + } + boxFileTypeFound = true; + std::vector boxData(box.length - boxSize); + io_->read(boxData.data(), static_cast(boxData.size())); + if (!Internal::isValidBoxFileType(boxData)) + throw Error(kerCorruptedMetadata); + break; + } + case kJp2BoxTypeHeader: { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::readMetadata: JP2Header box found" << std::endl; #endif long restore = io_->tell(); - while (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox) && subBox.length ) - { - boxes_check(boxes++, boxem) ; + while (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox) && subBox.length) { + boxes_check(boxes++, boxem); subBox.length = getLong((byte*)&subBox.length, bigEndian); - subBox.type = getLong((byte*)&subBox.type, bigEndian); - if (subBox.length > io_->size() ) { + subBox.type = getLong((byte*)&subBox.type, bigEndian); + if (subBox.length > io_->size()) { throw Error(kerCorruptedMetadata); } #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::readMetadata: " - << "subBox = " << toAscii(subBox.type) << " length = " << subBox.length << std::endl; + << "subBox = " << toAscii(subBox.type) << " length = " << subBox.length << std::endl; #endif - if(subBox.type == kJp2BoxTypeColorHeader && subBox.length != 15) - { + if (subBox.type == kJp2BoxTypeColorSpec && subBox.length != 15) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::readMetadata: " - << "Color data found" << std::endl; + << "Color data found" << std::endl; #endif - const long pad = 3 ; // 3 padding bytes 2 0 0 + const long pad = 3; // 3 padding bytes 2 0 0 const size_t data_length = Safe::add(subBox.length, static_cast(8)); // data_length makes no sense if it is larger than the rest of the file if (data_length > io_->size() - io_->tell()) { throw Error(kerCorruptedMetadata); } DataBuf data(static_cast(data_length)); - io_->read(data.pData_,data.size_); - const long iccLength = getULong(data.pData_+pad, bigEndian); + io_->read(data.pData_, data.size_); + const long iccLength = getULong(data.pData_ + pad, bigEndian); // subtracting pad from data.size_ is safe: // size_ is at least 8 and pad = 3 if (iccLength > data.size_ - pad) { throw Error(kerCorruptedMetadata); } DataBuf icc(iccLength); - ::memcpy(icc.pData_,data.pData_+pad,icc.size_); + ::memcpy(icc.pData_, data.pData_ + pad, icc.size_); #ifdef EXIV2_DEBUG_MESSAGES const char* iccPath = "/tmp/libexiv2_jp2.icc"; - FILE* f = fopen(iccPath,"wb"); - if ( f ) { - fwrite(icc.pData_,icc.size_,1,f); + FILE* f = fopen(iccPath, "wb"); + if (f) { + fwrite(icc.pData_, icc.size_, 1, f); fclose(f); } - std::cout << "Exiv2::Jp2Image::readMetadata: wrote iccProfile " << icc.size_<< " bytes to " << iccPath << std::endl ; + std::cout << "Exiv2::Jp2Image::readMetadata: wrote iccProfile " << icc.size_ << " bytes to " + << iccPath << std::endl; #endif setIccProfile(icc); } - if( subBox.type == kJp2BoxTypeImageHeader) - { + if (subBox.type == kJp2BoxTypeImageHeader) { io_->read((byte*)&ihdr, sizeof(ihdr)); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::readMetadata: Ihdr data found" << std::endl; #endif - ihdr.imageHeight = getLong((byte*)&ihdr.imageHeight, bigEndian); - ihdr.imageWidth = getLong((byte*)&ihdr.imageWidth, bigEndian); - ihdr.componentCount = getShort((byte*)&ihdr.componentCount, bigEndian); - ihdr.compressionTypeProfile = getShort((byte*)&ihdr.compressionTypeProfile, bigEndian); + ihdr.imageHeight = getLong((byte*)&ihdr.imageHeight, bigEndian); + ihdr.imageWidth = getLong((byte*)&ihdr.imageWidth, bigEndian); + ihdr.componentCount = getShort((byte*)&ihdr.componentCount, bigEndian); + if (ihdr.c != 7) { + throw Error(kerCorruptedMetadata); + } - pixelWidth_ = ihdr.imageWidth; + pixelWidth_ = ihdr.imageWidth; pixelHeight_ = ihdr.imageHeight; } - io_->seek(restore,BasicIo::beg); - if ( io_->seek(subBox.length, Exiv2::BasicIo::cur) != 0 ) { + io_->seek(restore, BasicIo::beg); + if (io_->seek(subBox.length, Exiv2::BasicIo::cur) != 0) { throw Error(kerCorruptedMetadata); } restore = io_->tell(); } break; } - - case kJp2BoxTypeUuid: - { + case kJp2BoxTypeUuid: { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::readMetadata: UUID box found" << std::endl; #endif - if (io_->read((byte*)&uuid, sizeof(uuid)) == sizeof(uuid)) - { + if (io_->read((byte*)&uuid, sizeof(uuid)) == sizeof(uuid)) { DataBuf rawData; - long bufRead; - bool bIsExif = memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid))==0; - bool bIsIPTC = memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid))==0; - bool bIsXMP = memcmp(uuid.uuid, kJp2UuidXmp , sizeof(uuid))==0; + long bufRead; + bool bIsExif = memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid)) == 0; + bool bIsIPTC = memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid)) == 0; + bool bIsXMP = memcmp(uuid.uuid, kJp2UuidXmp, sizeof(uuid)) == 0; - if(bIsExif) - { + if (bIsExif) { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found" << std::endl ; + std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found" << std::endl; #endif enforce(box.length >= sizeof(box) + sizeof(uuid), kerCorruptedMetadata); rawData.alloc(box.length - (sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != rawData.size_) throw Error(kerInputDataReadFailed); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != rawData.size_) + throw Error(kerInputDataReadFailed); - if (rawData.size_ > 8) // "II*\0long" + if (rawData.size_ > 8) // "II*\0long" { // Find the position of Exif header in bytes array. - long pos = ( (rawData.pData_[0] == rawData.pData_[1]) - && (rawData.pData_[0]=='I' || rawData.pData_[0]=='M') - ) ? 0 : -1; + long pos = ((rawData.pData_[0] == rawData.pData_[1]) && + (rawData.pData_[0] == 'I' || rawData.pData_[0] == 'M')) + ? 0 + : -1; // #1242 Forgive having Exif\0\0 in rawData.pData_ - const byte exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; - for (long i=0 ; pos < 0 && i < rawData.size_-(long)sizeof(exifHeader) ; i++) - { - if (memcmp(exifHeader, &rawData.pData_[i], sizeof(exifHeader)) == 0) - { - pos = i+sizeof(exifHeader); + const byte exifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + for (long i = 0; pos < 0 && i < rawData.size_ - (long)sizeof(exifHeader); i++) { + if (memcmp(exifHeader, &rawData.pData_[i], sizeof(exifHeader)) == 0) { + pos = i + sizeof(exifHeader); #ifndef SUPPRESS_WARNINGS - EXV_WARNING << "Reading non-standard UUID-EXIF_bad box in " << io_->path() << std::endl; + EXV_WARNING << "Reading non-standard UUID-EXIF_bad box in " << io_->path() + << std::endl; #endif - } } // If found it, store only these data at from this place. - if (pos >= 0 ) - { + if (pos >= 0) { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::readMetadata: Exif header found at position " << pos << std::endl; + std::cout << "Exiv2::Jp2Image::readMetadata: Exif header found at position " << pos + << std::endl; #endif - ByteOrder bo = TiffParser::decode(exifData(), - iptcData(), - xmpData(), - rawData.pData_ + pos, - rawData.size_ - pos); + ByteOrder bo = TiffParser::decode(exifData(), iptcData(), xmpData(), + rawData.pData_ + pos, rawData.size_ - pos); setByteOrder(bo); } - } - else - { + } else { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode Exif metadata." << std::endl; #endif @@ -400,19 +353,19 @@ } } - if(bIsIPTC) - { + if (bIsIPTC) { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found" << std::endl; + std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found" << std::endl; #endif enforce(box.length >= sizeof(box) + sizeof(uuid), kerCorruptedMetadata); rawData.alloc(box.length - (sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != rawData.size_) throw Error(kerInputDataReadFailed); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != rawData.size_) + throw Error(kerInputDataReadFailed); - if (IptcParser::decode(iptcData_, rawData.pData_, rawData.size_)) - { + if (IptcParser::decode(iptcData_, rawData.pData_, rawData.size_)) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode IPTC metadata." << std::endl; #endif @@ -420,21 +373,21 @@ } } - if(bIsXMP) - { + if (bIsXMP) { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found" << std::endl; + std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found" << std::endl; #endif enforce(box.length >= sizeof(box) + sizeof(uuid), kerCorruptedMetadata); rawData.alloc(box.length - (uint32_t)(sizeof(box) + sizeof(uuid))); bufRead = io_->read(rawData.pData_, rawData.size_); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != rawData.size_) throw Error(kerInputDataReadFailed); - xmpPacket_.assign(reinterpret_cast(rawData.pData_), rawData.size_); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != rawData.size_) + throw Error(kerInputDataReadFailed); + xmpPacket_.assign(reinterpret_cast(rawData.pData_), rawData.size_); std::string::size_type idx = xmpPacket_.find_first_of('<'); - if (idx != std::string::npos && idx > 0) - { + if (idx != std::string::npos && idx > 0) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Removing " << static_cast(idx) << " characters from the beginning of the XMP packet" << std::endl; @@ -442,8 +395,7 @@ xmpPacket_ = xmpPacket_.substr(idx); } - if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) - { + if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode XMP metadata." << std::endl; #endif @@ -453,18 +405,18 @@ break; } - default: - { + default: { break; } } + lastBoxTypeRead = box.type; // Move to the next box. io_->seek(static_cast(position - sizeof(box) + box.length), BasicIo::beg); - if (io_->error()) throw Error(kerFailedToReadImageData); + if (io_->error()) + throw Error(kerFailedToReadImageData); } - - } // Jp2Image::readMetadata + } void Jp2Image::printStructure(std::ostream& out, PrintStructureOption option, int depth) { @@ -483,26 +435,25 @@ bool bICC = option == kpsIccProfile; bool bXMP = option == kpsXMP; bool bIPTCErase = option == kpsIptcErase; + bool boxSignatureFound = false; if (bPrint) { out << "STRUCTURE OF JPEG2000 FILE: " << io_->path() << std::endl; out << " address | length | box | data" << std::endl; } - if ( bPrint || bXMP || bICC || bIPTCErase ) { + if (bPrint || bXMP || bICC || bIPTCErase) { + long position = 0; + Internal::Jp2BoxHeader box = {1, 1}; + Internal::Jp2BoxHeader subBox = {1, 1}; + Internal::Jp2UuidBox uuid = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + bool bLF = false; - long position = 0; - Jp2BoxHeader box = {1,1}; - Jp2BoxHeader subBox = {1,1}; - Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - bool bLF = false; - - while (box.length && box.type != kJp2BoxTypeClose && io_->read((byte*)&box, sizeof(box)) == sizeof(box)) - { - position = io_->tell(); + while (box.length && box.type != kJp2BoxTypeClose && io_->read((byte*)&box, sizeof(box)) == sizeof(box)) { + position = io_->tell(); box.length = getLong((byte*)&box.length, bigEndian); box.type = getLong((byte*)&box.type, bigEndian); - enforce(box.length <= sizeof(box)+io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata); + enforce(box.length <= sizeof(box) + io_->size() - io_->tell(), Exiv2::kerCorruptedMetadata); if (bPrint) { out << Internal::stringFormat("%8ld | %8ld | ", (size_t)(position - sizeof(box)), @@ -516,7 +467,22 @@ break; switch (box.type) { - case kJp2BoxTypeJp2Header: { + case kJp2BoxTypeSignature: { + if (boxSignatureFound) // Only one is allowed + throw Error(kerCorruptedMetadata); + boxSignatureFound = true; + break; + } + case kJp2BoxTypeFileTypeBox: { + // This box shall immediately follow the JPEG 2000 Signature box + /// \todo All files shall contain one and only one File Type box. + std::vector boxData(box.length - boxSize); + io_->read(boxData.data(), static_cast(boxData.size())); + if (!Internal::isValidBoxFileType(boxData)) + throw Error(kerCorruptedMetadata); + break; + } + case kJp2BoxTypeHeader: { lf(out, bLF); while (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox) && @@ -540,24 +506,42 @@ bLF = true; } - if (subBox.type == kJp2BoxTypeColorHeader) { + if (subBox.type == kJp2BoxTypeImageHeader) { + enforce(subBox.length == 22, kerCorruptedMetadata); + // height (4), width (4), componentsCount (2), bpc (1) + uint8_t compressionType = data.pData_[11]; + uint8_t unkC = data.pData_[12]; + uint8_t ipr = data.pData_[13]; + if (compressionType != 7 || unkC > 1 || ipr > 1) { + throw Error(kerCorruptedMetadata); + } + } + if (subBox.type == kJp2BoxTypeColorSpec) { long pad = 3; // don't know why there are 3 padding bytes // Bounds-check for the `getULong()` below, which reads 4 bytes, starting at `pad`. enforce(data.size_ >= pad + 4, kerCorruptedMetadata); - if (bPrint) { - out << " | pad:"; - for (int i = 0; i < 3; i++) - out << " " << (int)data.pData_[i]; - } - long iccLength = getULong(data.pData_ + pad, bigEndian); - if (bPrint) { - out << " | iccLength:" << iccLength; - } - enforce(iccLength <= data.size_ - pad, kerCorruptedMetadata); - if (bICC) { - out.write((const char*)data.pData_ + pad, iccLength); + /// \todo A conforming JP2 reader shall ignore all Colour Specification boxes after the + /// first. + uint8_t METH = data.pData_[0]; + // auto PREC = data.read_uint8(1); + // auto APPROX = data.read_uint8(2); + if (METH == 1) { // Enumerated Colourspace + const uint32_t enumCS = getULong(data.pData_ + 3, bigEndian); + if (enumCS != 16 && enumCS != 17) { + throw Error(kerCorruptedMetadata); + } + } else { // Restricted ICC Profile + // see the ICC Profile Format Specification, version ICC.1:1998-09 + const long iccLength = (long)getULong(data.pData_ + pad, bigEndian); + if (bPrint) { + out << " | iccLength:" << iccLength; + } + enforce(iccLength <= data.size_ - pad, kerCorruptedMetadata); + if (bICC) { + out.write((const char*)data.pData_ + pad, iccLength); + } } } lf(out, bLF); @@ -594,12 +578,12 @@ if (bPrint) { out << Internal::binaryToString( - makeSlice(rawData, 0, rawData.size_>40?40:rawData.size_)); + makeSlice(rawData, 0, rawData.size_ > 40 ? 40 : rawData.size_)); out.flush(); } lf(out, bLF); - if (bIsExif && bRecursive && rawData.size_ > 8) { // "II*\0long" + if (bIsExif && bRecursive && rawData.size_ > 8) { // "II*\0long" if ((rawData.pData_[0] == rawData.pData_[1]) && (rawData.pData_[0] == 'I' || rawData.pData_[0] == 'M')) { BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(rawData.pData_, rawData.size_)); @@ -633,19 +617,18 @@ void Jp2Image::writeMetadata() { - if (io_->open() != 0) - { + if (io_->open() != 0) { throw Error(kerDataSourceOpenFailed, io_->path(), strError()); } IoCloser closer(*io_); BasicIo::AutoPtr tempIo(new MemIo); - assert (tempIo.get() != 0); + assert(tempIo.get() != 0); - doWriteMetadata(*tempIo); // may throw + doWriteMetadata(*tempIo); // may throw io_->close(); - io_->transfer(*tempIo); // may throw + io_->transfer(*tempIo); // may throw - } // Jp2Image::writeMetadata + } // Jp2Image::writeMetadata #ifdef __clang__ // ignore cast align errors. dataBuf.pData_ is allocated by malloc() and 4 (or 8 byte aligned). @@ -653,84 +636,85 @@ #pragma clang diagnostic ignored "-Wcast-align" #endif - void Jp2Image::encodeJp2Header(const DataBuf& boxBuf,DataBuf& outBuf) + void Jp2Image::encodeJp2Header(const DataBuf& boxBuf, DataBuf& outBuf) { - DataBuf output(boxBuf.size_ + iccProfile_.size_ + 100); // allocate sufficient space - long outlen = sizeof(Jp2BoxHeader) ; // now many bytes have we written to output? - long inlen = sizeof(Jp2BoxHeader) ; // how many bytes have we read from boxBuf? - enforce(sizeof(Jp2BoxHeader) <= static_cast(output.size_), Exiv2::kerCorruptedMetadata); - Jp2BoxHeader* pBox = (Jp2BoxHeader*) boxBuf.pData_; - uint32_t length = getLong((byte*)&pBox->length, bigEndian); + DataBuf output(boxBuf.size_ + iccProfile_.size_ + 100); // allocate sufficient space + long outlen = sizeof(Internal::Jp2BoxHeader); // now many bytes have we written to output? + long inlen = sizeof(Internal::Jp2BoxHeader); // how many bytes have we read from boxBuf? + enforce(sizeof(Internal::Jp2BoxHeader) <= static_cast(output.size_), Exiv2::kerCorruptedMetadata); + Internal::Jp2BoxHeader* pBox = (Internal::Jp2BoxHeader*)boxBuf.pData_; + uint32_t length = getLong((byte*)&pBox->length, bigEndian); + enforce(length <= static_cast(output.size_), Exiv2::kerCorruptedMetadata); - uint32_t count = sizeof (Jp2BoxHeader); - char* p = (char*) boxBuf.pData_; - bool bWroteColor = false ; - - while ( count < length && !bWroteColor ) { - enforce(sizeof(Jp2BoxHeader) <= length - count, Exiv2::kerCorruptedMetadata); - Jp2BoxHeader* pSubBox = (Jp2BoxHeader*) (p+count) ; + uint32_t count = sizeof(Internal::Jp2BoxHeader); + char* p = (char*)boxBuf.pData_; + bool bWroteColor = false; + + while (count < length && !bWroteColor) { + enforce(sizeof(Internal::Jp2BoxHeader) <= length - count, Exiv2::kerCorruptedMetadata); + Internal::Jp2BoxHeader* pSubBox = (Internal::Jp2BoxHeader*)(p + count); // copy data. pointer could be into a memory mapped file which we will decode! // pSubBox isn't always an aligned pointer, so use memcpy to do the copy. - Jp2BoxHeader subBox; - memcpy(&subBox, pSubBox, sizeof(Jp2BoxHeader)); - Jp2BoxHeader newBox = subBox; + Internal::Jp2BoxHeader subBox; + memcpy(&subBox, pSubBox, sizeof(Internal::Jp2BoxHeader)); + Internal::Jp2BoxHeader newBox = subBox; - if ( count < length ) { + if (count < length) { subBox.length = getLong((byte*)&subBox.length, bigEndian); - subBox.type = getLong((byte*)&subBox.type , bigEndian); + subBox.type = getLong((byte*)&subBox.type, bigEndian); #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Jp2Image::encodeJp2Header subbox: "<< toAscii(subBox.type) << " length = " << subBox.length << std::endl; + std::cout << "Jp2Image::encodeJp2Header subbox: " << toAscii(subBox.type) + << " length = " << subBox.length << std::endl; #endif enforce(subBox.length > 0, Exiv2::kerCorruptedMetadata); enforce(subBox.length <= length - count, Exiv2::kerCorruptedMetadata); - count += subBox.length; - newBox.type = subBox.type; + count += subBox.length; + newBox.type = subBox.type; } else { - subBox.length=0; - newBox.type = kJp2BoxTypeColorHeader; + subBox.length = 0; + newBox.type = kJp2BoxTypeColorSpec; count = length; } uint32_t newlen = subBox.length; - if ( newBox.type == kJp2BoxTypeColorHeader ) { - bWroteColor = true ; - if ( ! iccProfileDefined() ) { - const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid"; - uint32_t psize = 15; - newlen = sizeof(newBox) + psize ; + if (newBox.type == kJp2BoxTypeColorSpec) { + bWroteColor = true; + if (!iccProfileDefined()) { + const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid"; + uint32_t psize = 15; enforce(newlen <= static_cast(output.size_ - outlen), Exiv2::kerCorruptedMetadata); - ul2Data((byte*)&newBox.length,psize ,bigEndian); - ul2Data((byte*)&newBox.type ,newBox.type,bigEndian); - ::memcpy(output.pData_+outlen ,&newBox ,sizeof(newBox)); - ::memcpy(output.pData_+outlen+sizeof(newBox) ,pad ,psize ); + ul2Data((byte*)&newBox.length, psize, bigEndian); + ul2Data((byte*)&newBox.type, newBox.type, bigEndian); + ::memcpy(output.pData_ + outlen, &newBox, sizeof(newBox)); + ::memcpy(output.pData_ + outlen + sizeof(newBox), pad, psize); } else { - const char* pad = "\x02\x00\x00"; - uint32_t psize = 3; - newlen = sizeof(newBox) + psize + iccProfile_.size_; + const char* pad = "\x02\x00\x00"; + uint32_t psize = 3; + newlen = sizeof(newBox) + psize + iccProfile_.size_; enforce(newlen <= static_cast(output.size_ - outlen), Exiv2::kerCorruptedMetadata); - ul2Data((byte*)&newBox.length,newlen,bigEndian); - ul2Data((byte*)&newBox.type,newBox.type,bigEndian); - ::memcpy(output.pData_+outlen ,&newBox ,sizeof(newBox) ); - ::memcpy(output.pData_+outlen+sizeof(newBox) , pad ,psize ); - ::memcpy(output.pData_+outlen+sizeof(newBox)+psize,iccProfile_.pData_,iccProfile_.size_); + ul2Data((byte*)&newBox.length, newlen, bigEndian); + ul2Data((byte*)&newBox.type, newBox.type, bigEndian); + ::memcpy(output.pData_ + outlen, &newBox, sizeof(newBox)); + ::memcpy(output.pData_ + outlen + sizeof(newBox), pad, psize); + ::memcpy(output.pData_ + outlen + sizeof(newBox) + psize, iccProfile_.pData_, iccProfile_.size_); } } else { enforce(newlen <= static_cast(output.size_ - outlen), Exiv2::kerCorruptedMetadata); - ::memcpy(output.pData_+outlen,boxBuf.pData_+inlen,subBox.length); + ::memcpy(output.pData_ + outlen, boxBuf.pData_ + inlen, subBox.length); } outlen += newlen; - inlen += subBox.length; + inlen += subBox.length; } // allocate the correct number of bytes, copy the data and update the box header outBuf.alloc(outlen); - ::memcpy(outBuf.pData_,output.pData_,outlen); - pBox = (Jp2BoxHeader*) outBuf.pData_; - ul2Data((byte*)&pBox->type,kJp2BoxTypeJp2Header,bigEndian); - ul2Data((byte*)&pBox->length,outlen,bigEndian); - } // Jp2Image::encodeJp2Header + ::memcpy(outBuf.pData_, output.pData_, outlen); + pBox = (Internal::Jp2BoxHeader*)outBuf.pData_; + ul2Data((byte*)&pBox->type, kJp2BoxTypeHeader, bigEndian); + ul2Data((byte*)&pBox->length, outlen, bigEndian); + } // Jp2Image::encodeJp2Header #ifdef __clang__ #pragma clang diagnostic pop @@ -738,8 +722,10 @@ void Jp2Image::doWriteMetadata(BasicIo& outIo) { - if (!io_->isopen()) throw Error(kerInputDataReadFailed); - if (!outIo.isopen()) throw Error(kerImageWriteFailed); + if (!io_->isopen()) + throw Error(kerInputDataReadFailed); + if (!outIo.isopen()) + throw Error(kerImageWriteFailed); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Writing JPEG-2000 file " << io_->path() << std::endl; @@ -747,57 +733,59 @@ #endif // Ensure that this is the correct image type - if (!isJp2Type(*io_, true)) - { - if (io_->error() || io_->eof()) throw Error(kerInputDataReadFailed); + if (!isJp2Type(*io_, true)) { + if (io_->error() || io_->eof()) + throw Error(kerInputDataReadFailed); throw Error(kerNoImageInInputData); } // Write JPEG2000 Signature. - if (outIo.write(Jp2Signature, 12) != 12) throw Error(kerImageWriteFailed); + if (outIo.write(Jp2Signature, 12) != 12) + throw Error(kerImageWriteFailed); - Jp2BoxHeader box = {0,0}; + Internal::Jp2BoxHeader box = {0, 0}; - byte boxDataSize[4]; - byte boxUUIDtype[4]; - DataBuf bheaderBuf(8); // Box header : 4 bytes (data size) + 4 bytes (box type). + byte boxDataSize[4]; + byte boxUUIDtype[4]; + DataBuf bheaderBuf(8); // Box header : 4 bytes (data size) + 4 bytes (box type). // FIXME: Andreas, why the loop do not stop when EOF is taken from _io. The loop go out by an exception // generated by a zero size data read. - while(io_->tell() < (long) io_->size()) - { + while (io_->tell() < (long)io_->size()) { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::doWriteMetadata: Position: " << io_->tell() << " / " << io_->size() << std::endl; + std::cout << "Exiv2::Jp2Image::doWriteMetadata: Position: " << io_->tell() << " / " << io_->size() + << std::endl; #endif // Read chunk header. std::memset(bheaderBuf.pData_, 0x00, bheaderBuf.size_); long bufRead = io_->read(bheaderBuf.pData_, bheaderBuf.size_); - if (io_->error()) throw Error(kerFailedToReadImageData); - if (bufRead != bheaderBuf.size_) throw Error(kerInputDataReadFailed); + if (io_->error()) + throw Error(kerFailedToReadImageData); + if (bufRead != bheaderBuf.size_) + throw Error(kerInputDataReadFailed); // Decode box header. - box.length = getLong(bheaderBuf.pData_, bigEndian); - box.type = getLong(bheaderBuf.pData_ + 4, bigEndian); + box.length = getLong(bheaderBuf.pData_, bigEndian); + box.type = getLong(bheaderBuf.pData_ + 4, bigEndian); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: box type: " << toAscii(box.type) << " length: " << box.length << std::endl; #endif - if (box.length == 0) - { + if (box.length == 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Null Box size has been found. " - "This is the last box of file." << std::endl; + "This is the last box of file." + << std::endl; #endif - box.length = (uint32_t) (io_->size() - io_->tell() + 8); + box.length = (uint32_t)(io_->size() - io_->tell() + 8); } - if (box.length < 8) - { + if (box.length < 8) { // box is broken, so there is nothing we can do here throw Error(kerCorruptedMetadata); } @@ -806,11 +794,10 @@ enforce(box.length - 8 <= static_cast(io_->size() - io_->tell()), kerCorruptedMetadata); // Read whole box : Box header + Box data (not fixed size - can be null). - DataBuf boxBuf(box.length); // Box header (8 bytes) + box data. - memcpy(boxBuf.pData_, bheaderBuf.pData_, 8); // Copy header. - bufRead = io_->read(boxBuf.pData_ + 8, box.length - 8); // Extract box data. - if (io_->error()) - { + DataBuf boxBuf(box.length); // Box header (8 bytes) + box data. + memcpy(boxBuf.pData_, bheaderBuf.pData_, 8); // Copy header. + bufRead = io_->read(boxBuf.pData_ + 8, box.length - 8); // Extract box data. + if (io_->error()) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Error reading source file" << std::endl; #endif @@ -818,146 +805,137 @@ throw Error(kerFailedToReadImageData); } - if (bufRead != (long)(box.length - 8)) - { + if (bufRead != (long)(box.length - 8)) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Cannot read source file data" << std::endl; #endif throw Error(kerInputDataReadFailed); } - switch(box.type) - { - case kJp2BoxTypeJp2Header: - { + switch (box.type) { + case kJp2BoxTypeHeader: { DataBuf newBuf; - encodeJp2Header(boxBuf,newBuf); + encodeJp2Header(boxBuf, newBuf); #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write JP2Header box (length: " << box.length << ")" << std::endl; + std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write JP2Header box (length: " << box.length << ")" + << std::endl; #endif - if (outIo.write(newBuf.pData_, newBuf.size_) != newBuf.size_) throw Error(kerImageWriteFailed); + if (outIo.write(newBuf.pData_, newBuf.size_) != newBuf.size_) + throw Error(kerImageWriteFailed); // Write all updated metadata here, just after JP2Header. - if (exifData_.count() > 0) - { + if (exifData_.count() > 0) { // Update Exif data to a new UUID box Blob blob; ExifParser::encode(blob, littleEndian, exifData_); - if (blob.size()) - { + if (blob.size()) { DataBuf rawExif(static_cast(blob.size())); memcpy(rawExif.pData_, &blob[0], blob.size()); DataBuf boxData(8 + 16 + rawExif.size_); ul2Data(boxDataSize, boxData.size_, Exiv2::bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian); - memcpy(boxData.pData_, boxDataSize, 4); - memcpy(boxData.pData_ + 4, boxUUIDtype, 4); - memcpy(boxData.pData_ + 8, kJp2UuidExif, 16); + memcpy(boxData.pData_, boxDataSize, 4); + memcpy(boxData.pData_ + 4, boxUUIDtype, 4); + memcpy(boxData.pData_ + 8, kJp2UuidExif, 16); memcpy(boxData.pData_ + 8 + 16, rawExif.pData_, rawExif.size_); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Exif metadata (length: " << boxData.size_ << std::endl; #endif - if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) throw Error(kerImageWriteFailed); + if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) + throw Error(kerImageWriteFailed); } } - if (iptcData_.count() > 0) - { + if (iptcData_.count() > 0) { // Update Iptc data to a new UUID box DataBuf rawIptc = IptcParser::encode(iptcData_); - if (rawIptc.size_ > 0) - { + if (rawIptc.size_ > 0) { DataBuf boxData(8 + 16 + rawIptc.size_); ul2Data(boxDataSize, boxData.size_, Exiv2::bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian); - memcpy(boxData.pData_, boxDataSize, 4); - memcpy(boxData.pData_ + 4, boxUUIDtype, 4); - memcpy(boxData.pData_ + 8, kJp2UuidIptc, 16); + memcpy(boxData.pData_, boxDataSize, 4); + memcpy(boxData.pData_ + 4, boxUUIDtype, 4); + memcpy(boxData.pData_ + 8, kJp2UuidIptc, 16); memcpy(boxData.pData_ + 8 + 16, rawIptc.pData_, rawIptc.size_); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with Iptc metadata (length: " << boxData.size_ << std::endl; #endif - if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) throw Error(kerImageWriteFailed); + if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) + throw Error(kerImageWriteFailed); } } - if (writeXmpFromPacket() == false) - { - if (XmpParser::encode(xmpPacket_, xmpData_) > 1) - { + if (writeXmpFromPacket() == false) { + if (XmpParser::encode(xmpPacket_, xmpData_) > 1) { #ifndef SUPPRESS_WARNINGS EXV_ERROR << "Failed to encode XMP metadata." << std::endl; #endif } } - if (xmpPacket_.size() > 0) - { + if (xmpPacket_.size() > 0) { // Update Xmp data to a new UUID box - DataBuf xmp(reinterpret_cast(xmpPacket_.data()), static_cast(xmpPacket_.size())); + DataBuf xmp(reinterpret_cast(xmpPacket_.data()), + static_cast(xmpPacket_.size())); DataBuf boxData(8 + 16 + xmp.size_); ul2Data(boxDataSize, boxData.size_, Exiv2::bigEndian); ul2Data(boxUUIDtype, kJp2BoxTypeUuid, Exiv2::bigEndian); - memcpy(boxData.pData_, boxDataSize, 4); - memcpy(boxData.pData_ + 4, boxUUIDtype, 4); - memcpy(boxData.pData_ + 8, kJp2UuidXmp, 16); - memcpy(boxData.pData_ + 8 + 16, xmp.pData_, xmp.size_); + memcpy(boxData.pData_, boxDataSize, 4); + memcpy(boxData.pData_ + 4, boxUUIDtype, 4); + memcpy(boxData.pData_ + 8, kJp2UuidXmp, 16); + memcpy(boxData.pData_ + 8 + 16, xmp.pData_, xmp.size_); #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write box with XMP metadata (length: " << boxData.size_ << ")" << std::endl; #endif - if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) throw Error(kerImageWriteFailed); + if (outIo.write(boxData.pData_, boxData.size_) != boxData.size_) + throw Error(kerImageWriteFailed); } break; } - case kJp2BoxTypeUuid: - { + case kJp2BoxTypeUuid: { enforce(boxBuf.size_ >= 24, Exiv2::kerCorruptedMetadata); - if(memcmp(boxBuf.pData_ + 8, kJp2UuidExif, 16) == 0) - { + if (memcmp(boxBuf.pData_ + 8, kJp2UuidExif, 16) == 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Exif Uuid box" << std::endl; #endif - } - else if(memcmp(boxBuf.pData_ + 8, kJp2UuidIptc, 16) == 0) - { + } else if (memcmp(boxBuf.pData_ + 8, kJp2UuidIptc, 16) == 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Iptc Uuid box" << std::endl; #endif - } - else if(memcmp(boxBuf.pData_ + 8, kJp2UuidXmp, 16) == 0) - { + } else if (memcmp(boxBuf.pData_ + 8, kJp2UuidXmp, 16) == 0) { #ifdef EXIV2_DEBUG_MESSAGES std::cout << "Exiv2::Jp2Image::doWriteMetadata: strip Xmp Uuid box" << std::endl; #endif - } - else - { + } else { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::doWriteMetadata: write Uuid box (length: " << box.length << ")" << std::endl; + std::cout << "Exiv2::Jp2Image::doWriteMetadata: write Uuid box (length: " << box.length << ")" + << std::endl; #endif - if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) throw Error(kerImageWriteFailed); + if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) + throw Error(kerImageWriteFailed); } break; } - default: - { + default: { #ifdef EXIV2_DEBUG_MESSAGES - std::cout << "Exiv2::Jp2Image::doWriteMetadata: write box (length: " << box.length << ")" << std::endl; + std::cout << "Exiv2::Jp2Image::doWriteMetadata: write box (length: " << box.length << ")" + << std::endl; #endif - if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) throw Error(kerImageWriteFailed); + if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) + throw Error(kerImageWriteFailed); break; } @@ -968,15 +946,14 @@ std::cout << "Exiv2::Jp2Image::doWriteMetadata: EOF" << std::endl; #endif - } // Jp2Image::doWriteMetadata + } // Jp2Image::doWriteMetadata // ************************************************************************* // free functions Image::AutoPtr newJp2Instance(BasicIo::AutoPtr io, bool create) { Image::AutoPtr image(new Jp2Image(io, create)); - if (!image->good()) - { + if (!image->good()) { image.reset(); } return image; @@ -987,15 +964,13 @@ const int32_t len = 12; byte buf[len]; iIo.read(buf, len); - if (iIo.error() || iIo.eof()) - { + if (iIo.error() || iIo.eof()) { return false; } bool matched = (memcmp(buf, Jp2Signature, len) == 0); - if (!advance || !matched) - { + if (!advance || !matched) { iIo.seek(-len, BasicIo::cur); } return matched; } -} // namespace Exiv2 +} // namespace Exiv2 diff -Nru exiv2-0.27.5/src/jp2image_int.cpp exiv2-0.27.6/src/jp2image_int.cpp --- exiv2-0.27.5/src/jp2image_int.cpp 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/src/jp2image_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -0,0 +1,33 @@ +#include "jp2image_int.hpp" + +#include + +#include "error.hpp" +#include "types.hpp" + +namespace Exiv2 { +namespace Internal { + bool isValidBoxFileType(const std::vector &boxData) + { + // BR & MinV are obligatory (4 + 4 bytes). Afterwards we have N compatibility + // lists (of size 4) + if (boxData.size() < 8 || ((boxData.size() - 8u) % 4u) != 0) { + return false; + } + + const size_t N = (boxData.size() - 8u) / 4u; + const uint32_t brand = getULong(boxData.data(), bigEndian); + const uint32_t minorVersion = getULong(boxData.data() + 4, bigEndian); + + bool clWithRightBrand = false; + for (size_t i = 0; i < N; i++) { + uint32_t compatibilityList = getULong(boxData.data() + 8 + i * 4, bigEndian); + if (compatibilityList == brandJp2) { + clWithRightBrand = true; + break; + } + } + return (brand == brandJp2 && minorVersion == 0 && clWithRightBrand); + } +} +} diff -Nru exiv2-0.27.5/src/jp2image_int.hpp exiv2-0.27.6/src/jp2image_int.hpp --- exiv2-0.27.5/src/jp2image_int.hpp 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/src/jp2image_int.hpp 2023-01-18 21:57:53.000000000 +0000 @@ -0,0 +1,40 @@ +#ifndef JP2IMAGE_INT_HPP +#define JP2IMAGE_INT_HPP + +#include +#include + +namespace Exiv2 +{ + namespace Internal + { + struct Jp2BoxHeader + { + uint32_t length; + uint32_t type; + }; + + struct Jp2ImageHeaderBox + { + uint32_t imageHeight; + uint32_t imageWidth; + uint16_t componentCount; + uint8_t bpc; //& boxData); + } // namespace Internal +} // namespace Exiv2 + +#endif // JP2IMAGE_INT_HPP diff -Nru exiv2-0.27.5/src/jpgimage.cpp exiv2-0.27.6/src/jpgimage.cpp --- exiv2-0.27.5/src/jpgimage.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/jpgimage.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -288,7 +288,9 @@ // Write existing stuff after record, // skip the current and all remaining IPTC blocks long pos = sizeFront; - while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos, + long nextSizeData = Safe::add(sizePsData, -pos); + enforce(nextSizeData >= 0, kerCorruptedMetadata); + while (0 == Photoshop::locateIptcIrb(pPsData + pos, nextSizeData, &record, &sizeHdr, &sizeIptc)) { const long newPos = static_cast(record - pPsData); // Copy data up to the IPTC IRB @@ -296,6 +298,8 @@ append(psBlob, pPsData + pos, newPos - pos); } // Skip the IPTC IRB + nextSizeData = Safe::add(sizePsData, -pos); + enforce(nextSizeData >= 0, kerCorruptedMetadata); pos = newPos + sizeHdr + sizeIptc + (sizeIptc & 1); } if (pos < sizePsData) { diff -Nru exiv2-0.27.5/src/makernote_int.cpp exiv2-0.27.6/src/makernote_int.cpp --- exiv2-0.27.5/src/makernote_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/makernote_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -130,6 +130,7 @@ { "Minolta", minoltaId, newIfdMn, newIfdMn2 }, { "NIKON", ifdIdNotSet, newNikonMn, 0 }, // mnGroup_ is not used { "OLYMPUS", ifdIdNotSet, newOlympusMn, 0 }, // mnGroup_ is not used + { "OM Digital", olympus2Id, newOMSystemMn, newOMSystemMn2 }, { "Panasonic", panasonicId, newPanasonicMn, newPanasonicMn2 }, { "PENTAX", ifdIdNotSet, newPentaxMn, 0 }, // mnGroup_ is not used { "RICOH", ifdIdNotSet, newPentaxMn, 0 }, // mnGroup_ is not used @@ -330,6 +331,60 @@ return sizeOfSignature(); } // Olympus2MnHeader::write + const byte OMSystemMnHeader::signature_[] = { + 'O', 'M', ' ', 'S', 'Y', 'S', 'T', 'E', 'M', 0x00, 0x00, 0x00, 'I', 'I', 0x04, 0x00 + }; + + uint32_t OMSystemMnHeader::sizeOfSignature() + { + return sizeof(signature_); + } + + OMSystemMnHeader::OMSystemMnHeader() + { + read(signature_, sizeOfSignature(), invalidByteOrder); + } + + OMSystemMnHeader::~OMSystemMnHeader() + { + } + + uint32_t OMSystemMnHeader::size() const + { + return header_.size_; + } + + uint32_t OMSystemMnHeader::ifdOffset() const + { + return sizeOfSignature(); + } + + uint32_t OMSystemMnHeader::baseOffset(uint32_t mnOffset) const + { + return mnOffset; + } + + bool OMSystemMnHeader::read(const byte* pData, + uint32_t size, + ByteOrder /*byteOrder*/) + { + if (!pData || size < sizeOfSignature()) return false; + header_.alloc(sizeOfSignature()); + std::memcpy(header_.pData_, pData, header_.size_); + if ( static_cast(header_.size_) < sizeOfSignature() + || 0 != memcmp(header_.pData_, signature_, sizeOfSignature() - 2)) { + return false; + } + return true; + } // OMSystemMnHeader::read + + uint32_t OMSystemMnHeader::write(IoWrapper& ioWrapper, + ByteOrder /*byteOrder*/) const + { + ioWrapper.write(signature_, sizeOfSignature()); + return sizeOfSignature(); + } // OMSystemMnHeader::write + const byte FujiMnHeader::signature_[] = { 'F', 'U', 'J', 'I', 'F', 'I', 'L', 'M', 0x0c, 0x00, 0x00, 0x00 }; @@ -900,6 +955,25 @@ return new TiffIfdMakernote(tag, group, mnGroup, new Olympus2MnHeader); } + TiffComponent* newOMSystemMn(uint16_t tag, + IfdId group, + IfdId mnGroup, + const byte* /*pData*/, + uint32_t size, + ByteOrder /*byteOrder*/) + { + // Require at least the header and an IFD with 1 entry + if (size < OMSystemMnHeader::sizeOfSignature() + 18) return 0; + return newOMSystemMn2(tag, group, mnGroup); + } + + TiffComponent* newOMSystemMn2(uint16_t tag, + IfdId group, + IfdId mnGroup) + { + return new TiffIfdMakernote(tag, group, mnGroup, new OMSystemMnHeader); + } + TiffComponent* newFujiMn(uint16_t tag, IfdId group, IfdId mnGroup, @@ -1173,6 +1247,7 @@ { 0x0098, "0204", 0, 2, 4 }, { 0x0098, "0800", 0, 3, 4 }, // for e.g. Z6/7 { 0x0098, "0801", 0, 3, 4 }, // for e.g. Z6/7 + { 0x0098, "0802", 0, 3, 4 }, // for e.g. Z9 // NikonFl { 0x00a8, "0100", 0, 0, NA }, { 0x00a8, "0101", 0, 0, NA }, diff -Nru exiv2-0.27.5/src/makernote_int.hpp exiv2-0.27.6/src/makernote_int.hpp --- exiv2-0.27.5/src/makernote_int.hpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/makernote_int.hpp 2023-01-18 21:57:53.000000000 +0000 @@ -232,6 +232,38 @@ }; // class Olympus2MnHeader + //! Header of an OM Digital Solutions (ex Olympus) Makernote + class OMSystemMnHeader : public MnHeader { + public: + //! @name Creators + //@{ + //! Default constructor + OMSystemMnHeader(); + //! Virtual destructor. + virtual ~OMSystemMnHeader(); + //@} + //! @name Manipulators + //@{ + virtual bool read(const byte* pData, + uint32_t size, + ByteOrder byteOrder); + //@} + //! @name Accessors + //@{ + virtual uint32_t size() const; + virtual uint32_t write(IoWrapper& ioWrapper, ByteOrder byteOrder) const; + virtual uint32_t ifdOffset() const; + virtual uint32_t baseOffset(uint32_t mnOffset) const; + //@} + //! Return the size of the makernote header signature + static uint32_t sizeOfSignature(); + + private: + DataBuf header_; //!< Data buffer for the makernote header + static const byte signature_[]; //!< OM Digital Solutions makernote header signature + + }; // class OMSystemMnHeader + //! Header of a Fujifilm Makernote class FujiMnHeader : public MnHeader { public: @@ -587,6 +619,19 @@ IfdId group, IfdId mnGroup); + //! Function to create an OM Digital Solutions makernote + TiffComponent* newOMSystemMn(uint16_t tag, + IfdId group, + IfdId mnGroup, + const byte* pData, + uint32_t size, + ByteOrder byteOrder); + + //! Function to create a OM Digital Solutions makernote + TiffComponent* newOMSystemMn2(uint16_t tag, + IfdId group, + IfdId mnGroup); + //! Function to create a Fujifilm makernote TiffComponent* newFujiMn(uint16_t tag, IfdId group, diff -Nru exiv2-0.27.5/src/nikonmn_int.cpp exiv2-0.27.6/src/nikonmn_int.cpp --- exiv2-0.27.5/src/nikonmn_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/nikonmn_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -593,6 +593,7 @@ TagInfo(0x002a, "VignetteControl", N_("Vignette Control"), N_("Vignette control"), nikon3Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(nikonOlnh)), TagInfo(0x0034, "ShutterMode", N_("Shutter Mode"), N_("Shutter mode"), nikon3Id, makerTags, unsignedShort, -1, EXV_PRINT_TAG(nikonShutterModes)), TagInfo(0x0037, "MechanicalShutterCount", N_("Mechanical Shutter Count"), N_("Mechanical shutter count"), nikon3Id, makerTags, unsignedLong, -1, printValue), + TagInfo(0x003f, "WhiteBalanceBias2", N_("White Balance Bias 2"), N_("White balance bias 2"), nikon3Id, makerTags, signedRational, -1, printValue), TagInfo(0x0080, "ImageAdjustment", N_("Image Adjustment"), N_("Image adjustment setting"), nikon3Id, makerTags, asciiString, -1, printValue), TagInfo(0x0081, "ToneComp", N_("Tone Compensation"), N_("Tone compensation"), nikon3Id, makerTags, asciiString, -1, printValue), TagInfo(0x0082, "AuxiliaryLens", N_("Auxiliary Lens"), N_("Auxiliary lens (adapter)"), nikon3Id, makerTags, asciiString, -1, printValue), @@ -2101,6 +2102,7 @@ {0x9F,0x58,0x44,0x44,0x14,0x14,0xA1,0x06,0x01,0x00,0x00, "Nikon", "JAA132DA", "AF-S DX Nikkor 35mm f/1.8G"}, {0xA0,0x54,0x50,0x50,0x0C,0x0C,0xA2,0x06,0x01,0x00,0x00, "Nikon", "JAA014DA", "AF-S Nikkor 50mm f/1.4G"}, {0xA1,0x40,0x18,0x37,0x2C,0x34,0xA3,0x06,0x01,0x00,0x00, "Nikon", "JAA804DA", "AF-S DX Nikkor 10-24mm f/3.5-4.5G ED"}, +{0xA2,0x38,0x5C,0x8E,0x34,0x40,0xCD,0x86,0x00,0x00,0x00, "Nikon", "JAA829DA", "AF-P DX Nikkor 70-300mm f/4.5-6.3G ED VR"}, {0xA2,0x48,0x5C,0x80,0x24,0x24,0xA4,0x0E,0x13,0x00,0x00, "Nikon", "JAA807DA", "AF-S Nikkor 70-200mm f/2.8G ED VR II"}, {0xA3,0x3C,0x29,0x44,0x30,0x30,0xA5,0x0E,0x01,0x00,0x00, "Nikon", "JAA806DA", "AF-S Nikkor 16-35mm f/4G ED VR"}, {0xA4,0x54,0x37,0x37,0x0C,0x0C,0xA6,0x06,0x01,0x00,0x00, "Nikon", "JAA131DA", "AF-S Nikkor 24mm f/1.4G ED"}, @@ -2113,6 +2115,7 @@ //AB AD -- no lens -- {0xAC,0x38,0x53,0x8E,0x34,0x3C,0xAE,0x0E,0x01,0x00,0x00, "Nikon", "JAA814DA", "AF-S DX Nikkor 55-300mm f/4.5-5.6G ED VR"}, {0xAD,0x3C,0x2D,0x8E,0x2C,0x3C,0xAF,0x0E,0x01,0x00,0x00, "Nikon", "JAA812DA", "AF-S DX Nikkor 18-300mm f/3.5-5.6G ED VR"}, +{0xAD,0x3C,0xA0,0xA0,0x3C,0x3C,0xD8,0x4E,0x00,0x00,0x00, "Nikon", "JAA535DA", "AF-S Nikkor 500mm f/5.6E PF ED VR"}, {0xAE,0x54,0x62,0x62,0x0C,0x0C,0xB0,0x06,0x01,0x00,0x00, "Nikon", "JAA338DA", "AF-S Nikkor 85mm f/1.4G"}, {0xAF,0x54,0x44,0x44,0x0C,0x0C,0xB1,0x06,0x01,0x00,0x00, "Nikon", "JAA134DA", "AF-S Nikkor 35mm f/1.4G"}, {0xB0,0x4C,0x50,0x50,0x14,0x14,0xB2,0x06,0x01,0x00,0x00, "Nikon", "JAA015DA", "AF-S Nikkor 50mm f/1.8G"}, @@ -2404,6 +2407,7 @@ //M "Tamron" "63D" "AF 35-90mm F/4-5.6"; //M "Tamron" "65D" "SP AF 35-105mm F/2.8 Aspherical"; //M "Tamron" "" "AF 35-135mm F/3.5-4.5"; +{0xC9,0x3C,0x44,0x76,0x25,0x31,0xDF,0x4E,0x00,0x00,0x00, "Tamron", "A043", "35-150mm F/2.8-4 Di VC OSD"}, {0x00,0x47,0x53,0x80,0x30,0x3C,0x00,0x06,0x00,0x00,0x00, "Tamron", "A15", "AF 55-200mm F/4-5.6 Di II LD"}, {0xF7,0x53,0x5C,0x80,0x24,0x24,0x84,0x06,0x01,0x00,0x00, "Tamron", "A001", "SP AF 70-200mm F/2.8 Di LD (IF) Macro"}, {0xFE,0x53,0x5C,0x80,0x24,0x24,0x84,0x06,0x01,0x00,0x00, "Tamron", "A001", "SP AF 70-200mm F/2.8 Di LD (IF) Macro"}, @@ -2926,7 +2930,7 @@ return os << "(" << value << ")"; } -// from https://github.com/exiftool/exiftool/blob/12.12/lib/Image/ExifTool/Nikon.pm#L4646 +// from https://github.com/exiftool/exiftool/blob/12.44/lib/Image/ExifTool/Nikon.pm#L4969 static const struct ZMntLens {uint16_t lid; const char *manuf, *lensname;} zmountlens[] = { {1 , "Nikon", "Nikkor Z 24-70mm f/4 S"}, @@ -2945,6 +2949,13 @@ {21 , "Nikon", "Nikkor Z 50mm f/1.2 S"}, //IB {22 , "Nikon", "Nikkor Z 24-50mm f/4-6.3"}, //IB {23 , "Nikon", "Nikkor Z 14-24mm f/2.8 S"}, //IB + {24 , "Nikon", "Nikkor Z MC 105mm f/2.8 VR S"}, //IB + {27 , "Nikon", "Nikkor Z MC 50mm f/2.8"}, //IB + {28 , "Nikon", "Nikkor Z 100-400mm f/4.5-5.6 VR S"}, //28 + {29 , "Nikon", "Nikkor Z 28mm f/2.8"}, //IB + {30 , "Nikon", "Nikkor Z 400mm f/2.8 TC VR S"}, //28 + {31 , "Nikon", "Nikkor Z 24-120 f/4"}, //28 + {32 , "Nikon", "Nikkor Z 800mm f/6.3 VR S"}, //28 {0 , "", ""} //end of array }; diff -Nru exiv2-0.27.5/src/pngimage.cpp exiv2-0.27.6/src/pngimage.cpp --- exiv2-0.27.5/src/pngimage.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/pngimage.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -230,7 +230,6 @@ const std::string exifKey = "Raw profile type exif"; const std::string app1Key = "Raw profile type APP1"; const std::string iptcKey = "Raw profile type iptc"; - const std::string iccKey = "icc"; const std::string softKey = "Software"; const std::string commKey = "Comment"; const std::string descKey = "Description"; @@ -309,13 +308,12 @@ // for XMP, ICC etc: read and format data bool bXMP = option == kpsXMP && findi(dataString,xmpKey)==0; - bool bICC = option == kpsIccProfile && findi(dataString,iccKey)==0; bool bExif = option == kpsRecursive &&(findi(dataString,exifKey)==0 || findi(dataString,app1Key)==0); bool bIptc = option == kpsRecursive && findi(dataString,iptcKey)==0; bool bSoft = option == kpsRecursive && findi(dataString,softKey)==0; bool bComm = option == kpsRecursive && findi(dataString,commKey)==0; bool bDesc = option == kpsRecursive && findi(dataString,descKey)==0; - bool bDump = bXMP || bICC || bExif || bIptc || bSoft || bComm || bDesc || eXIf ; + bool bDump = bXMP || bExif || bIptc || bSoft || bComm || bDesc || iCCP || eXIf ; if( bDump ) { DataBuf dataBuf; @@ -379,7 +377,7 @@ bLF=true; } - if ( bICC || bComm ) { + if ( ( iCCP && option == kpsIccProfile ) || bComm ) { out.write((const char*) dataBuf.pData_,dataBuf.size_); bLF = bComm ; } @@ -389,6 +387,7 @@ out.write((const char*)decoded.pData_,decoded.size_); bLF = true; } + if ( eXIf && option == kpsRecursive ) { // create memio object with the data, then print the structure BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(data.pData_, dataOffset)); @@ -591,9 +590,14 @@ throw Error(kerImageWriteFailed); return; } - else if ( !strcmp(szChunk, "eXIf") ) { - ; // do nothing Exif metdata is written following IHDR - ; // as zTXt chunk with signature Raw profile type exif__ + else if ( !strcmp(szChunk, "eXIf") || !strcmp(szChunk, "iCCP") ) { + // do nothing (strip): Exif metadata is written following IHDR + // as zTXt chunk with signature "Raw profile type exif", + // together with the ICC profile as a fresh iCCP chunk +#ifdef EXIV2_DEBUG_MESSAGES + std::cout << "Exiv2::PngImage::doWriteMetadata: strip " << szChunk + << " chunk (length: " << dataOffset << ")" << std::endl; +#endif } else if ( !strcmp(szChunk, "IHDR") ) { @@ -699,8 +703,7 @@ } else if (!strcmp(szChunk, "tEXt") || !strcmp(szChunk, "zTXt") || - !strcmp(szChunk, "iTXt") || - !strcmp(szChunk, "iCCP")) + !strcmp(szChunk, "iTXt")) { DataBuf key = PngChunk::keyTXTChunk(chunkBuf, true); if (compare("Raw profile type exif", key, 21) || @@ -708,8 +711,6 @@ compare("Raw profile type iptc", key, 21) || compare("Raw profile type xmp", key, 20) || compare("XML:com.adobe.xmp", key, 17) || - compare("icc", key, 3) || // see test/data/imagemagick.png - compare("ICC", key, 3) || compare("Description", key, 11)) { #ifdef EXIV2_DEBUG_MESSAGES diff -Nru exiv2-0.27.5/src/preview.cpp exiv2-0.27.6/src/preview.cpp --- exiv2-0.27.5/src/preview.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/preview.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -23,6 +23,7 @@ #include #include +#include #include "preview.hpp" #include "futils.hpp" @@ -936,9 +937,8 @@ // create decoding table unsigned long invalid = 64; - unsigned long decodeBase64Table[256] = {}; - for (unsigned long i = 0; i < 256; i++) - decodeBase64Table[i] = invalid; + std::vector decodeBase64Table(256, invalid); + for (unsigned long i = 0; i < 64; i++) decodeBase64Table[(unsigned char)encodeBase64Table[i]] = i; diff -Nru exiv2-0.27.5/src/tags_int.cpp exiv2-0.27.6/src/tags_int.cpp --- exiv2-0.27.5/src/tags_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/tags_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -252,6 +252,7 @@ { 9, N_("JBIG B&W") }, { 10, N_("JBIG Color") }, { 32766, N_("Next 2-bits RLE") }, + { 32767, N_("Sony ARW Compressed") }, { 32769, N_("Epson ERF Compressed") }, { 32770, N_("Samsung SRW Compressed") }, { 32771, N_("CCITT RLE 1-word") }, @@ -536,7 +537,7 @@ N_("The logical order of bits within a byte"), ifd0Id, imgStruct, unsignedShort, 1, printValue), // TIFF tag TagInfo(0x010d, "DocumentName", N_("Document Name"), - N_("The name of the document from which this image was scanned"), + N_("The name of the document from which this image was scanned."), ifd0Id, imgStruct, asciiString, 0, printValue), // TIFF tag TagInfo(0x010e, "ImageDescription", N_("Image Description"), N_("A character string giving the title of the image. It may be " @@ -596,6 +597,19 @@ "is used instead of this tag. If this field does not exist, " "the TIFF default of 1 (chunky) is assumed."), ifd0Id, imgStruct, unsignedShort, 1, EXV_PRINT_TAG(exifPlanarConfiguration)), + TagInfo(0x011d, "PageName", N_("Page Name"), + N_("The name of the page from which this image was scanned."), + ifd0Id, imgStruct, asciiString, 0, printValue), // TIFF tag + TagInfo(0x011e, "XPosition", N_("X Position"), + N_("X position of the image. The X offset in ResolutionUnits of the " + "left side of the image, with respect to the left side of the page."), + ifd0Id, imgStruct, unsignedRational, 1, printValue), // TIFF tag + TagInfo(0x011f, "YPosition", N_("Y Position"), + N_("Y position of the image. The Y offset in ResolutionUnits of the " + "top of the image, with respect to the top of the page. In the TIFF " + "coordinate scheme, the positive Y direction is down, so that " + "YPosition is always positive."), + ifd0Id, imgStruct, unsignedRational, 1, printValue), // TIFF tag TagInfo(0x0122, "GrayResponseUnit", N_("Gray Response Unit"), N_("The precision of the information contained in the GrayResponseCurve."), ifd0Id, imgStruct, unsignedShort, 1, printValue), // TIFF tag @@ -960,6 +974,8 @@ TagInfo(0xc4a5, "PrintImageMatching", N_("Print Image Matching"), N_("Print Image Matching, description needed."), ifd0Id, otherTags, undefined, -1, printValue), + //////////////////////////////////////// + // https://wwwimages.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.5.0.0.pdf TagInfo(0xc612, "DNGVersion", N_("DNG version"), N_("This tag encodes the DNG four-tier version number. For files " "compliant with version 1.1.0.0 of the DNG specification, this " @@ -1495,9 +1511,8 @@ "independent, ignoring fixed pattern effects and other sources of noise (e.g., " "pixel response non-uniformity, spatially-dependent thermal effects, etc.)."), ifd0Id, dngTags, tiffDouble, -1, printValue), // DNG tag - //////////////////////////////////////// - // http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/cinemadng/pdfs/CinemaDNG_Format_Specification_v1_1.pdf + // https://www.adobe.com/content/dam/acom/en/devnet/CinemaDNG/pdf/CinemaDNG_Format_Specification_v1_1.pdf TagInfo(0xc763, "TimeCodes", N_("TimeCodes"), N_("The optional TimeCodes tag shall contain an ordered array of time codes. " "All time codes shall be 8 bytes long and in binary format. The tag may " @@ -1623,6 +1638,8 @@ TagInfo(0xc7ee, "EnhanceParams", N_("Enhance Params"), N_("A string that documents how the enhanced image data was processed."), ifd0Id, dngTags, asciiString, 0, printValue), // DNG 1.5 tag + //////////////////////////////////////// + // https://helpx.adobe.com/photoshop/kb/dng-specification-tags.html TagInfo(0xcd2d, "ProfileGainTableMap", N_("Profile Gain Table Map"), N_("Contains spatially varying gain tables that can be applied while processing the " "image as a starting point for user adjustments."), @@ -1681,6 +1698,10 @@ "for the third illuminant. Otherwise, this tag is ignored. The " "format of the data is the same as IlluminantData1."), ifd0Id, dngTags, undefined, -1, printValue), // DNG 1.6 tag + TagInfo(0xcd38, "MaskSubArea", N_("Mask Subarea"), + N_("This tag identifies the crop rectangle of this IFD's mask, " + "relative to the main image."), + ifd0Id, dngTags, unsignedLong, 4, printValue), // DNG 1.6 tag TagInfo(0xcd39, "ProfileHueSatMapData3", N_("Profile Hue Sat Map Data 3"), N_("This tag contains the data for the third hue/saturation/value mapping " "table. Each entry of the table contains three 32-bit IEEE floating-point " @@ -1698,6 +1719,14 @@ "used if ColorPlanes is greater than 3. The matrix is stored in row " "scan order."), ifd0Id, dngTags, signedRational, -1, printValue), // DNG 1.6 tag + TagInfo(0xcd3b, "RGBTables", N_("RGB Tables"), + N_("This tag specifies color transforms that can be applied to masked image " + "regions. Color transforms are specified using RGB-to-RGB color lookup tables. " + "These tables are associated with Semantic Masks to limit the color transform " + "to a sub-region of the image. The overall color transform is a linear " + "combination of the color tables, weighted by their corresponding Semantic " + "Masks."), + ifd0Id, dngTags, undefined, -1, printValue), // DNG 1.6 tag //////////////////////////////////////// // End of list marker diff -Nru exiv2-0.27.5/src/tiffimage.cpp exiv2-0.27.6/src/tiffimage.cpp --- exiv2-0.27.5/src/tiffimage.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/tiffimage.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -83,8 +83,11 @@ //! List of TIFF compression to MIME type mappings MimeTypeList mimeTypeList[] = { + { 32767, "image/x-sony-arw" }, + { 32769, "image/x-epson-erf" }, { 32770, "image/x-samsung-srw" }, { 34713, "image/x-nikon-nef" }, + { 65000, "image/x-kodak-dcr" }, { 65535, "image/x-pentax-pef" } }; diff -Nru exiv2-0.27.5/src/tiffvisitor_int.cpp exiv2-0.27.6/src/tiffvisitor_int.cpp --- exiv2-0.27.5/src/tiffvisitor_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/tiffvisitor_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -775,7 +775,7 @@ << " to offset area.\n"; #endif memset(buf + 8, 0x0, 4); - memcpy(buf + 8, pTiffEntry->pData(), pTiffEntry->size()); + memmove(buf + 8, pTiffEntry->pData(), pTiffEntry->size()); memset(const_cast(pTiffEntry->pData()), 0x0, pTiffEntry->size()); } return 12; @@ -1568,7 +1568,6 @@ return; } p += 4; - uint32_t isize= 0; // size of Exif.Sony1.PreviewImage if (count > std::numeric_limits::max() / typeSize) { throw Error(kerArithmeticOverflow); @@ -1581,7 +1580,19 @@ || static_cast(baseOffset()) + offset <= 0)) { // #1143 if ( object->tag() == 0x2001 && std::string(groupName(object->group())) == "Sony1" ) { - isize=size; + // This tag is Exif.Sony1.PreviewImage, which refers to a preview image which is + // not stored in the metadata. Instead it is stored at the end of the file, after + // the main image. The value of `size` refers to the size of the preview image, not + // the size of the tag's payload, so we set it to zero here so that we don't attempt + // to read those bytes from the metadata. We currently leave this tag as "undefined", + // although we may attempt to handle it better in the future. More discussion of + // this issue can be found here: + // + // https://github.com/Exiv2/exiv2/issues/2001 + // https://github.com/Exiv2/exiv2/pull/2008 + // https://github.com/Exiv2/exiv2/pull/2013 + typeId = undefined; + size = 0; } else { #ifndef SUPPRESS_WARNINGS EXV_ERROR << "Offset of directory " << groupName(object->group()) @@ -1629,20 +1640,7 @@ } Value::AutoPtr v = Value::create(typeId); enforce(v.get() != NULL, kerCorruptedMetadata); - if ( !isize ) { - v->read(pData, size, byteOrder()); - } else { - // Prevent large memory allocations: https://github.com/Exiv2/exiv2/issues/1881 - enforce(isize <= 1024 * 1024, kerCorruptedMetadata); - - // #1143 Write a "hollow" buffer for the preview image - // Sadly: we don't know the exact location of the image in the source (it's near offset) - // And neither TiffReader nor TiffEntryBase have access to the BasicIo object being processed - byte* buffer = (byte*) ::malloc(isize); - ::memset(buffer,0,isize); - v->read(buffer,isize, byteOrder()); - ::free(buffer); - } + v->read(pData, size, byteOrder()); object->setValue(v); object->setData(pData, size); diff -Nru exiv2-0.27.5/src/xmp.cpp exiv2-0.27.6/src/xmp.cpp --- exiv2-0.27.5/src/xmp.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/src/xmp.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -765,8 +765,12 @@ return 2; } - XMLValidator::check(xmpPacket.data(), xmpPacket.size()); - SXMPMeta meta(xmpPacket.data(), static_cast(xmpPacket.size())); + // Make sure the unterminated substring is used + size_t len = xmpPacket.size(); + while (len > 0 && 0 == xmpPacket[len - 1]) --len; + + XMLValidator::check(xmpPacket.data(), len); + SXMPMeta meta(xmpPacket.data(), static_cast(len)); SXMPIterator iter(meta); std::string schemaNs, propPath, propValue; XMP_OptionBits opt = 0; diff -Nru exiv2-0.27.5/test/data/icc-test.out exiv2-0.27.6/test/data/icc-test.out --- exiv2-0.27.5/test/data/icc-test.out 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/test/data/icc-test.out 2023-01-18 21:57:53.000000000 +0000 @@ -735,7 +735,7 @@ 12 | 20 | ftyp | 32 | 3185 | jp2h | 40 | 22 | sub:ihdr | ............. - 62 | 3155 | sub:colr | ......HLino....mntrRGB XYZ .. | pad: 2 0 0 | iccLength:3144 + 62 | 3155 | sub:colr | ......HLino....mntrRGB XYZ .. | iccLength:3144 3217 | 0 | jp2c | STRUCTURE OF JPEG2000 FILE: Reagan2.jp2 address | length | box | data @@ -743,7 +743,7 @@ 12 | 20 | ftyp | 32 | 1613641 | jp2h | 40 | 22 | sub:ihdr | ............. - 62 | 1613611 | sub:colr | ...... APPL....prtrRGB Lab .. | pad: 2 0 0 | iccLength:1613600 + 62 | 1613611 | sub:colr | ...... APPL....prtrRGB Lab .. | iccLength:1613600 1613673 | 0 | jp2c | STRUCTURE OF JPEG2000 FILE: Reagan2.jp2 address | length | box | data @@ -751,7 +751,7 @@ 12 | 20 | ftyp | 32 | 601 | jp2h | 40 | 22 | sub:ihdr | ............. - 62 | 571 | sub:colr | ......0ADBE....mntrRGB XYZ .. | pad: 2 0 0 | iccLength:560 + 62 | 571 | sub:colr | ......0ADBE....mntrRGB XYZ .. | iccLength:560 633 | 0 | jp2c | 1d3fda2edb4a89ab60a23c5f7c7d81dd 1d3fda2edb4a89ab60a23c5f7c7d81dd Binary files /tmp/tmpg285omu9/eNyDQIYGVr/exiv2-0.27.5/test/data/issue_2027_poc.jpg and /tmp/tmpg285omu9/U3uFH_uqQc/exiv2-0.27.6/test/data/issue_2027_poc.jpg differ Binary files /tmp/tmpg285omu9/eNyDQIYGVr/exiv2-0.27.5/test/data/issue_2178_poc.jp2 and /tmp/tmpg285omu9/U3uFH_uqQc/exiv2-0.27.6/test/data/issue_2178_poc.jp2 differ Binary files /tmp/tmpg285omu9/eNyDQIYGVr/exiv2-0.27.5/test/data/issue_2190_poc.jp2 and /tmp/tmpg285omu9/U3uFH_uqQc/exiv2-0.27.6/test/data/issue_2190_poc.jp2 differ Binary files /tmp/tmpg285omu9/eNyDQIYGVr/exiv2-0.27.5/test/data/issue_2268_poc.jp2 and /tmp/tmpg285omu9/U3uFH_uqQc/exiv2-0.27.6/test/data/issue_2268_poc.jp2 differ Binary files /tmp/tmpg285omu9/eNyDQIYGVr/exiv2-0.27.5/test/data/test_issue_2126.exv and /tmp/tmpg285omu9/U3uFH_uqQc/exiv2-0.27.6/test/data/test_issue_2126.exv differ diff -Nru exiv2-0.27.5/tests/bugfixes/github/test_issue_1845.py exiv2-0.27.6/tests/bugfixes/github/test_issue_1845.py --- exiv2-0.27.5/tests/bugfixes/github/test_issue_1845.py 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/tests/bugfixes/github/test_issue_1845.py 2023-01-18 21:57:53.000000000 +0000 @@ -12,6 +12,9 @@ filename = path("$tmp_path/issue_1845_poc.jp2") commands = ["$exiv2 -q -D +1 ad $filename"] - stderr = [""] + stderr = [ + """$exception_in_adjust """ + filename + """: +$kerCorruptedMetadata +"""] stdout = [""] - retval = [0] + retval = [1] diff -Nru exiv2-0.27.5/tests/bugfixes/github/test_issue_1881.py exiv2-0.27.6/tests/bugfixes/github/test_issue_1881.py --- exiv2-0.27.5/tests/bugfixes/github/test_issue_1881.py 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/tests/bugfixes/github/test_issue_1881.py 2023-01-18 21:57:53.000000000 +0000 @@ -14,9 +14,5 @@ filename2 = path("$tmp_path/issue_1881_coverage.jpg") commands = ["$exiv2 -q -d I rm $filename1", "$exiv2 -q -d I rm $filename2"] stdout = ["",""] - stderr = [ -"""Exiv2 exception in erase action for file $filename1: -$kerCorruptedMetadata -""", -""] - retval = [1,0] + stderr = ["",""] + retval = [0,0] diff -Nru exiv2-0.27.5/tests/bugfixes/github/test_issue_2126.py exiv2-0.27.6/tests/bugfixes/github/test_issue_2126.py --- exiv2-0.27.5/tests/bugfixes/github/test_issue_2126.py 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/tests/bugfixes/github/test_issue_2126.py 2023-01-18 21:57:53.000000000 +0000 @@ -0,0 +1,15 @@ +from system_tests import CaseMeta, path + +class OMSystemMakerNote(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/issues/2126 + """ + url = "https://github.com/Exiv2/exiv2/issues/2126" + + filename = path("$data_path/test_issue_2126.exv") + commands = ["$exiv2 -q -K Exif.Olympus2.CameraID $filename"] + stdout = ["""Exif.Olympus2.CameraID Undefined 32 OM SYSTEM CAMERA +"""] + stderr = [""] + retval = [0] diff -Nru exiv2-0.27.5/tests/bugfixes/github/test_issue_2268.py exiv2-0.27.6/tests/bugfixes/github/test_issue_2268.py --- exiv2-0.27.5/tests/bugfixes/github/test_issue_2268.py 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/tests/bugfixes/github/test_issue_2268.py 2023-01-18 21:57:53.000000000 +0000 @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, check_no_ASAN_UBSAN_errors + +class issue_2268_jp2_assert(metaclass=CaseMeta): + url = "https://github.com/Exiv2/exiv2/issues/2268" + filename = "$data_path/issue_2268_poc.jp2" + commands = ["$exiv2 -pS $filename"] + retval = [1] + stderr = ["""$exiv2_exception_message $filename: +$kerCorruptedMetadata +"""] + compare_stdout = check_no_ASAN_UBSAN_errors diff -Nru exiv2-0.27.5/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py exiv2-0.27.6/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py --- exiv2-0.27.5/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/tests/bugfixes/github/test_issue_ghsa_mxw9_qx4c_6m8v.py 2023-01-18 21:57:53.000000000 +0000 @@ -13,6 +13,8 @@ filename = path("$tmp_path/issue_ghsa_mxw9_qx4c_6m8v_poc.jp2") commands = ["$exiv2 rm $filename"] stdout = [""] - retval = [0] - - compare_stderr = check_no_ASAN_UBSAN_errors + stderr = [ + """$exception_in_erase """ + filename + """: +$kerCorruptedMetadata +"""] + retval = [1] diff -Nru exiv2-0.27.5/tests/suite.conf exiv2-0.27.6/tests/suite.conf --- exiv2-0.27.5/tests/suite.conf 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/tests/suite.conf 2023-01-18 21:57:53.000000000 +0000 @@ -48,5 +48,7 @@ exiv2_exception_message: Exiv2 exception in print action for file exiv2_overflow_exception_message: std::overflow_error exception in print action for file exception_in_extract: Exiv2 exception in extract action for file +exception_in_adjust: Exiv2 exception in adjust action for file +exception_in_erase: Exiv2 exception in erase action for file uncaught_exception: Uncaught exception: no_exif_data_found_retval: 253 diff -Nru exiv2-0.27.5/.travis.yml exiv2-0.27.6/.travis.yml --- exiv2-0.27.5/.travis.yml 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -language: cpp - -git: - quiet: true - depth: 1 - -env: - global: - - COMMON_CMAKE_OPTIONS="-DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install" - -matrix: - include: - - name: "Ubuntu 18.04 - gcc-7.5 (Release)" - os: linux - dist: bionic - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Release" - - - name: "Ubuntu 18.04 - gcc-7.5 (Debug)" - os: linux - dist: bionic - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Debug" - - - name: "Ubuntu 20.04 - gcc-9.3 (Release)" - os: linux - dist: focal - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Release" - - - name: "Ubuntu 20.04 - gcc-9.3 (Debug)" - os: linux - dist: focal - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Debug" - - - name: "Ubuntu 20.04 - clang-7 (Release)" - os: linux - dist: focal - sudo: required - compiler: clang - env: - - BUILD_TYPE="Release" - - - name: "Ubuntu 20.04 - clang-7 (Debug)" - os: linux - dist: focal - sudo: required - compiler: clang - env: - - BUILD_TYPE="Debug" - - - name: "Ubuntu 20.04 - gcc-9.3 (Debug+Coverage)" - os: linux - dist: focal - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Debug" - - WITH_COVERAGE=1 - - - name: "Ubuntu 20.04 - gcc-9.3 (Release+Valgrind)" - os: linux - dist: focal - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Release" - - WITH_VALGRIND=1 - - - name: "Ubuntu 20.04 - gcc-9.3 (Release+Sanitizers)" - os: linux - dist: focal - sudo: required - compiler: gcc - env: - - BUILD_TYPE="Release" - - WITH_SANITIZERS=1 - - - name: "macOS 10.14 - XCode 11.3 (Release)" - os: osx - osx_image: xcode11.3 - compiler: clang - env: - - BUILD_TYPE="Release" - - - name: "macOS 10.14 - XCode 11.3 (Debug)" - os: osx - osx_image: xcode11.3 - compiler: clang - env: - - BUILD_TYPE="Debug" - -install: ./ci/install.sh -script: ./ci/run.sh - -cache: - ccache: true - directories: - - conan # Conan installation folder - - $HOME/conanData # Conan storage location diff -Nru exiv2-0.27.5/unitTests/CMakeLists.txt exiv2-0.27.6/unitTests/CMakeLists.txt --- exiv2-0.27.5/unitTests/CMakeLists.txt 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/CMakeLists.txt 2023-01-18 21:57:53.000000000 +0000 @@ -1,22 +1,5 @@ find_package(GTest REQUIRED) -get_target_property(exiv2lib_SOURCES exiv2lib SOURCES) -get_target_property(exiv2lib_int_SOURCES exiv2lib_int SOURCES) -get_target_property(exiv2lib_COMPILE_DEFINITIONS exiv2lib COMPILE_DEFINITIONS) -get_target_property(exiv2lib_INCLUDE_DIRECTORIES exiv2lib INCLUDE_DIRECTORIES) -get_target_property(exiv2lib_LINK_LIBRARIES exiv2lib LINK_LIBRARIES) - -set(unit_tests_exiv2lib_SOURCES) -foreach(source IN LISTS exiv2lib_SOURCES exiv2lib_int_SOURCES) - if(source MATCHES "\.(c|cpp|h|hpp)$") - if(source MATCHES ".*/.*") - list(APPEND unit_tests_exiv2lib_SOURCES "${source}") - else() - list(APPEND unit_tests_exiv2lib_SOURCES "../src/${source}") - endif() - endif() -endforeach() - add_executable(unit_tests mainTestRunner.cpp test_DateValue.cpp @@ -29,13 +12,14 @@ test_futils.cpp test_helper_functions.cpp test_image_int.cpp + test_jp2image.cpp + test_jp2image_int.cpp test_safe_op.cpp test_slice.cpp test_tiffheader.cpp test_types.cpp test_LangAltValueRead.cpp - gtestwrapper.h - ${unit_tests_exiv2lib_SOURCES} + $ ) target_compile_definitions(unit_tests @@ -44,46 +28,37 @@ TESTDATA_PATH="${PROJECT_SOURCE_DIR}/test/data" ) -if (exiv2lib_COMPILE_DEFINITIONS) - target_compile_definitions(unit_tests PRIVATE ${exiv2lib_COMPILE_DEFINITIONS}) -endif () - target_include_directories(unit_tests PRIVATE ${exiv2lib_INCLUDE_DIRECTORIES} ) -#TODO Use GTest::GTest once we upgrade the minimum CMake version required target_link_libraries(unit_tests PRIVATE - ${exiv2lib_LINK_LIBRARIES} - ${GTEST_BOTH_LIBRARIES} + exiv2lib + GTest::GTest ) +# NOTE: We are using the GTest::GTest which is coming from the file FindGTest.cmake +# auto-generated by conan. Normally we would use here: GTest::gtest GTest::gtest_main # ZLIB is used in exiv2lib_int. if( EXIV2_ENABLE_PNG ) target_link_libraries(unit_tests PRIVATE ${ZLIB_LIBRARIES} ) endif() +# TODO: Propagate this from src/CMakeLists.txt target_include_directories(unit_tests PRIVATE - ${GTEST_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/src ) -target_compile_definitions(unit_tests - PRIVATE - GTEST_LINKED_AS_SHARED_LIBRARY=1 -) - set_target_properties(unit_tests PROPERTIES COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS} ) -if (USING_CONAN) - target_compile_definitions(unit_tests PRIVATE ${CONAN_COMPILE_DEFINITIONS_GTEST}) -endif() - +# Ignore warnings about missing PDB files from 3rd party libs if (MSVC) set_target_properties(unit_tests PROPERTIES LINK_FLAGS "/ignore:4099") endif() + +add_test(NAME unitTests COMMAND unit_tests) diff -Nru exiv2-0.27.5/unitTests/mainTestRunner.cpp exiv2-0.27.6/unitTests/mainTestRunner.cpp --- exiv2-0.27.5/unitTests/mainTestRunner.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/mainTestRunner.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. */ -#include "gtestwrapper.h" +#include #include int main(int argc, char** argv) diff -Nru exiv2-0.27.5/unitTests/test_basicio.cpp exiv2-0.27.6/unitTests/test_basicio.cpp --- exiv2-0.27.5/unitTests/test_basicio.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_basicio.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,9 +19,58 @@ */ #include -#include "gtestwrapper.h" +#include using namespace Exiv2; +TEST(MemIo_Default, readEReturns0) +{ + std::vector buf(10); + MemIo io; + ASSERT_EQ(0, io.read(buf.data(), (long)buf.size())); +} + +TEST(MemIo_Default, isNotAtEof) +{ + MemIo io; + ASSERT_FALSE(io.eof()); +} + +TEST(MemIo_Default, seekBeyondBufferSizeReturns1AndSetsEofToTrue) +{ + MemIo io; + ASSERT_EQ(1, io.seek(1, BasicIo::beg)); + ASSERT_TRUE(io.eof()); +} + +TEST(MemIo_Default, seekBefore0Returns1ButItDoesNotSetEofToTrue) +{ + MemIo io; + ASSERT_EQ(1, io.seek(-1, BasicIo::beg)); + ASSERT_FALSE(io.eof()); +} + +TEST(MemIo_Default, seekToEndPosition_doesNotTriggerEof) +{ + MemIo io; + ASSERT_EQ(0, io.tell()); + ASSERT_EQ(0, io.seek(0, BasicIo::end)); + ASSERT_EQ(0, io.tell()); + ASSERT_FALSE(io.eof()); +} + +TEST(MemIo_Default, seekToEndPositionAndReadTriggersEof) +{ + MemIo io; + ASSERT_EQ(0, io.seek(0, BasicIo::end)); + ASSERT_EQ(0, io.tell()); + + std::vector buf2(64, 0); + ASSERT_EQ(0, io.read(buf2.data(), 1)); // Note that we cannot even read 1 byte being at the end + ASSERT_TRUE(io.eof()); +} + +// ------------------------- + TEST(MemIo, seek_out_of_bounds_00) { byte buf[1024]; diff -Nru exiv2-0.27.5/unitTests/test_cr2header_int.cpp exiv2-0.27.6/unitTests/test_cr2header_int.cpp --- exiv2-0.27.5/unitTests/test_cr2header_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_cr2header_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include "cr2header_int.hpp" -#include "gtestwrapper.h" +#include using namespace Exiv2; static const byte cr2LittleEndian[] = {0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, @@ -75,4 +75,4 @@ 0x43, 0x52, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; Internal::Cr2Header header; ASSERT_FALSE(header.read(bufferInvalidTag, 16)); -} \ No newline at end of file +} diff -Nru exiv2-0.27.5/unitTests/test_DateValue.cpp exiv2-0.27.6/unitTests/test_DateValue.cpp --- exiv2-0.27.5/unitTests/test_DateValue.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_DateValue.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include "value.hpp" -#include "gtestwrapper.h" +#include using namespace Exiv2; TEST(ADateValue, isDefaultConstructed) diff -Nru exiv2-0.27.5/unitTests/test_enforce.cpp exiv2-0.27.6/unitTests/test_enforce.cpp --- exiv2-0.27.5/unitTests/test_enforce.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_enforce.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -21,7 +21,7 @@ #include #include -#include "gtestwrapper.h" +#include #include diff -Nru exiv2-0.27.5/unitTests/test_futils.cpp exiv2-0.27.6/unitTests/test_futils.cpp --- exiv2-0.27.5/unitTests/test_futils.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_futils.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -28,7 +28,7 @@ #include #include -#include "gtestwrapper.h" +#include using namespace Exiv2; @@ -42,21 +42,8 @@ std::string tmpFile("tmp.dat"); std::ofstream auxFile(tmpFile.c_str()); auxFile.close(); -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__) || defined(__MSYS__) - const char * expectedString = "No error (errno = 0)"; -#elif defined(__APPLE__) - const char * expectedString = "Undefined error: 0 (errno = 0)"; -#elif defined(__sun__) - const char * expectedString = "Error 0 (errno = 0)"; -#elif defined(__FreeBSD__) - const char * expectedString = "No error: 0 (errno = 0)"; -#elif defined(__NetBSD__) - const char * expectedString = "Undefined error: 0 (errno = 0)"; -#else - const char * expectedString = "Success (errno = 0)"; -#endif std::remove(tmpFile.c_str()); - ASSERT_STREQ(expectedString, strError().c_str()); + ASSERT_TRUE(strError().find("errno = 0") != std::string::npos); } TEST(strError, returnNoSuchFileOrDirectoryWhenTryingToOpenNonExistingFile) @@ -68,22 +55,7 @@ TEST(strError, doNotRecognizeUnknownError) { errno = 9999; -#if defined(__MINGW__) || defined(__MSYS__) || defined(__CYGWIN__) - const char * expectedString = "Unknown error 9999 (errno = 9999)"; -#elif defined(_WIN32) - const char * expectedString = "Unknown error (errno = 9999)"; -#elif defined(__APPLE__) - const char * expectedString = "Unknown error: 9999 (errno = 9999)"; -#elif defined(__sun__) - const char * expectedString = "Unknown error (errno = 9999)"; -#elif defined(__FreeBSD__) - const char * expectedString = "Unknown error: 9999 (errno = 9999)"; -#elif defined(__NetBSD__) - const char * expectedString = "Unknown error: 9999 (errno = 9999)"; -#else - const char * expectedString = "Unknown error 9999 (errno = 9999)"; -#endif - ASSERT_STREQ(expectedString, strError().c_str()); + ASSERT_TRUE(strError().find("errno = 9999") != std::string::npos) << "strError = " << strError(); } TEST(getEnv, getsDefaultValueWhenExpectedEnvVariableDoesNotExist) diff -Nru exiv2-0.27.5/unitTests/test_helper_functions.cpp exiv2-0.27.6/unitTests/test_helper_functions.cpp --- exiv2-0.27.5/unitTests/test_helper_functions.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_helper_functions.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include "helper_functions.hpp" -#include "gtestwrapper.h" +#include TEST(string_from_unterminated, terminatedArray) { diff -Nru exiv2-0.27.5/unitTests/test_image_int.cpp exiv2-0.27.6/unitTests/test_image_int.cpp --- exiv2-0.27.5/unitTests/test_image_int.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_image_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include -#include "gtestwrapper.h" +#include #include using namespace Exiv2::Internal; diff -Nru exiv2-0.27.5/unitTests/test_jp2image.cpp exiv2-0.27.6/unitTests/test_jp2image.cpp --- exiv2-0.27.5/unitTests/test_jp2image.cpp 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_jp2image.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include + +using namespace Exiv2; + +TEST(Jp2Image, canBeCreatedFromScratch) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = true; + ASSERT_NO_THROW(newJp2Instance(memIo, create)); +} + +TEST(Jp2Image, canBeOpenedEvenWithAnEmptyMemIo) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = false; + ASSERT_NO_THROW(newJp2Instance(memIo, create)); +} + +TEST(Jp2Image, mimeTypeIsPng) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = true; + Image::AutoPtr image = newJp2Instance(memIo, create); + ASSERT_EQ("image/jp2", image->mimeType()); +} + +TEST(Jp2Image, printStructurePrintsNothingWithKpsNone) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = true; + Image::AutoPtr image = newJp2Instance(memIo, create); + + std::ostringstream stream; + image->printStructure(stream, Exiv2::kpsNone, 1); + + ASSERT_TRUE(stream.str().empty()); +} + +TEST(Jp2Image, printStructurePrintsDataWithKpsBasic) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = true; + Image::AutoPtr image = newJp2Instance(memIo, create); + + std::ostringstream stream; + image->printStructure(stream, Exiv2::kpsBasic, 1); + + ASSERT_FALSE(stream.str().empty()); +} + +TEST(Jp2Image, cannotReadMetadataFromEmptyIo) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = false; + Image::AutoPtr image = newJp2Instance(memIo, create); + ASSERT_TRUE(image.get() == NULL); +} + +TEST(Jp2Image, cannotReadMetadataFromIoWhichCannotBeOpened) +{ + Exiv2::BasicIo::AutoPtr io (new Exiv2::FileIo("NonExistingPath.jp2")); + const bool create = false; + Image::AutoPtr image = newJp2Instance(io, create); + ASSERT_TRUE(image.get() == NULL); +} + +TEST(Jp2Image, cannotWriteMetadataToEmptyIo) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = false; + Image::AutoPtr image = newJp2Instance(memIo, create); + ASSERT_TRUE(image.get() == NULL); +} + +TEST(Jp2Image, canWriteMetadataFromCreatedJp2Image) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = true; + Image::AutoPtr image = newJp2Instance(memIo, create); + ASSERT_NO_THROW(image->writeMetadata()); +} + +TEST(Jp2Image, canWriteMetadataAndReadAfterwards) +{ + Exiv2::BasicIo::AutoPtr memIo (new Exiv2::MemIo); + const bool create = true; + Image::AutoPtr image = newJp2Instance(memIo, create); + + ASSERT_NO_THROW(image->writeMetadata()); + ASSERT_NO_THROW(image->readMetadata()); +} diff -Nru exiv2-0.27.5/unitTests/test_jp2image_int.cpp exiv2-0.27.6/unitTests/test_jp2image_int.cpp --- exiv2-0.27.5/unitTests/test_jp2image_int.cpp 1970-01-01 00:00:00.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_jp2image_int.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "jp2image_int.hpp" // Internals of JPEG-2000 standard + +#include + +using namespace Exiv2::Internal; + +namespace { +void setValidValues(std::vector& boxData) { + // The first 4 bytes correspond to the BR (Brand). It must have the value 'jp2\040' + boxData[0] = 'j'; + boxData[1] = 'p'; + boxData[2] = '2'; + boxData[3] = '\040'; + + // The next 4 bytes correspond to the MinV (Minor version). It is a 4-byte unsigned int with value 0 + + // The only available Compatibility list also has the value 'jp2\040' + boxData[8] = 'j'; + boxData[9] = 'p'; + boxData[10] = '2'; + boxData[11] = '\040'; +} +} // namespace + +TEST(Jp2_FileTypeBox, isNotValidWithoutProperValuesSet) { + const std::vector boxData(12); + ASSERT_FALSE(isValidBoxFileType(boxData)); +} + +TEST(Jp2_FileTypeBox, isValidWithMinimumPossibleSizeAndValidValues) { + std::vector boxData(12); + setValidValues(boxData); + ASSERT_TRUE(isValidBoxFileType(boxData)); +} + +TEST(Jp2_FileTypeBox, isNotValidWithMinimumPossibleSizeButInvalidBrand) { + std::vector boxData(12); + setValidValues(boxData); + boxData[2] = '3'; // Change byte in the brand field + + ASSERT_FALSE(isValidBoxFileType(boxData)); +} + +TEST(Jp2_FileTypeBox, isNotValidWithMinimumPossibleSizeButInvalidCL1) { + std::vector boxData(12); + setValidValues(boxData); + boxData[10] = '3'; // Change byte in the CL1 + + ASSERT_FALSE(isValidBoxFileType(boxData)); +} + +// ---------------------------------------------------------- + +TEST(Jp2_FileTypeBox, withInvalidBoxDataSizeIsInvalid) { + std::vector boxData(13); // 12 + 1 (the extra byte causes problems) + ASSERT_FALSE(isValidBoxFileType(boxData)); +} + +TEST(Jp2_FileTypeBox, withSmallBoxDataSizeIsInvalid) { + std::vector boxData(7); // Minimum size is 8 + ASSERT_FALSE(isValidBoxFileType(boxData)); +} + +TEST(Jp2_FileTypeBox, with2CLs_lastOneWithBrandValue_isValid) { + std::vector boxData(16); + // The first 4 bytes correspond to the BR (Brand). It must have the value 'jp2\040' + boxData[0] = 'j'; + boxData[1] = 'p'; + boxData[2] = '2'; + boxData[3] = '\040'; + + // The next 4 bytes correspond to the MinV (Minor version). It is a 4-byte unsigned int with value 0 + + // The 2nd Compatibility list has the value 'jp2\040' + boxData[12] = 'j'; + boxData[13] = 'p'; + boxData[14] = '2'; + boxData[15] = '\040'; + + ASSERT_TRUE(isValidBoxFileType(boxData)); +} diff -Nru exiv2-0.27.5/unitTests/test_LangAltValueRead.cpp exiv2-0.27.6/unitTests/test_LangAltValueRead.cpp --- exiv2-0.27.5/unitTests/test_LangAltValueRead.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_LangAltValueRead.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -20,7 +20,7 @@ #include -#include "gtestwrapper.h" +#include using namespace Exiv2; diff -Nru exiv2-0.27.5/unitTests/test_safe_op.cpp exiv2-0.27.6/unitTests/test_safe_op.cpp --- exiv2-0.27.5/unitTests/test_safe_op.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_safe_op.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include -#include "gtestwrapper.h" +#include namespace si = Safe::Internal; /*! diff -Nru exiv2-0.27.5/unitTests/test_slice.cpp exiv2-0.27.6/unitTests/test_slice.cpp --- exiv2-0.27.5/unitTests/test_slice.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_slice.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -22,7 +22,7 @@ #include #include "slice.hpp" #include "types.hpp" -#include "gtestwrapper.h" +#include using namespace Exiv2; template diff -Nru exiv2-0.27.5/unitTests/test_tiffheader.cpp exiv2-0.27.6/unitTests/test_tiffheader.cpp --- exiv2-0.27.5/unitTests/test_tiffheader.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_tiffheader.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include -#include "gtestwrapper.h" +#include #include using namespace Exiv2; @@ -80,4 +80,4 @@ std::ostringstream str; header.print(str, ""); ASSERT_STREQ("TIFF header, offset = 0x00000008, little endian encoded\n", str.str().c_str()); -} \ No newline at end of file +} diff -Nru exiv2-0.27.5/unitTests/test_TimeValue.cpp exiv2-0.27.6/unitTests/test_TimeValue.cpp --- exiv2-0.27.5/unitTests/test_TimeValue.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_TimeValue.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -19,7 +19,7 @@ */ #include "value.hpp" -#include "gtestwrapper.h" +#include using namespace Exiv2; TEST(ATimeValue, isDefaultConstructed) diff -Nru exiv2-0.27.5/unitTests/test_types.cpp exiv2-0.27.6/unitTests/test_types.cpp --- exiv2-0.27.5/unitTests/test_types.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_types.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -21,7 +21,7 @@ #include #include #include -#include "gtestwrapper.h" +#include using namespace Exiv2; // More info about tm : http://www.cplusplus.com/reference/ctime/tm/ diff -Nru exiv2-0.27.5/unitTests/test_XmpKey.cpp exiv2-0.27.6/unitTests/test_XmpKey.cpp --- exiv2-0.27.5/unitTests/test_XmpKey.cpp 2021-10-21 15:21:12.000000000 +0000 +++ exiv2-0.27.6/unitTests/test_XmpKey.cpp 2023-01-18 21:57:53.000000000 +0000 @@ -20,7 +20,7 @@ #include #include -#include "gtestwrapper.h" +#include using namespace Exiv2; namespace