Merge remote-tracking branch 'origin'

main
Viktor Schneider 3 years ago
commit 73a1a0ec21

@ -53,7 +53,7 @@ predicate indexK_with_fixedarray(ClassTemplateInstantiation t, ArrayIndexCall ca
t.getSimpleName() = "array" and
idx = call.getArgument(0) and
lowerBound(idx) >= 0 and
upperBound(idx) < t.getTemplateArgument(1).(Literal).getValue().toInt()
upperBound(idx) < lowerBound(t.getTemplateArgument(1))
)
}

@ -2,6 +2,9 @@
# https://google.github.io/oss-fuzz/getting-started/continuous-integration/
name: CIFuzz
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths-ignore:

@ -5,6 +5,10 @@
# or to provide custom queries or build logic.
name: "CodeQL"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: [0.27-maintenance, main]

@ -6,6 +6,10 @@ on:
schedule:
- cron: 0 4 * * *
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
name: Nightly - Linux distributions
jobs:

@ -4,6 +4,10 @@
name: On PRs - Linux-Ubuntu Quick Fuzz
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths-ignore:
@ -24,18 +28,8 @@ jobs:
- name: build and compile
run: |
mkdir build && cd build && \
cmake -GNinja -DEXIV2_ENABLE_PNG=ON \
-DEXIV2_BUILD_SAMPLES=ON \
-DEXIV2_ENABLE_WEBREADY=ON \
-DEXIV2_ENABLE_CURL=ON \
-DEXIV2_ENABLE_BMFF=ON \
-DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON \
-DCMAKE_CXX_COMPILER=$(which clang++) \
-DEXIV2_BUILD_FUZZ_TESTS=ON \
-DEXIV2_TEAM_USE_SANITIZERS=ON \
.. && \
cmake --build . --parallel
cmake --preset linux-sanitizers -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=$(which clang++) -DEXIV2_BUILD_FUZZ_TESTS=ON -DEXIV2_BUILD_UNIT_TESTS=OFF
cmake --build build --parallel
- name: Fuzz
run: |

@ -1,5 +1,9 @@
name: On PRs - Linux-Ubuntu Matrix
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths-ignore:
@ -22,7 +26,7 @@ jobs:
- name: install dependencies
run: |
sudo apt-get install ninja-build
pip3 install conan==1.45.0
pip3 install conan==1.48.1
- name: Conan common config
run: |
@ -39,20 +43,8 @@ jobs:
- name: Build
run: |
cd build && \
cmake -GNinja \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} \
-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 \
.. && \
cmake --build . --parallel
cmake --preset base_linux -S . -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}}
cmake --build build --parallel
- name: Install
run: |

@ -1,5 +1,9 @@
name: On PRs - Linux Special Builds
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
pull_request:
@ -20,7 +24,7 @@ jobs:
- name: install dependencies
run: |
sudo apt-get install ninja-build
pip3 install conan==1.45.0
pip3 install conan==1.48.1
pip3 install gcovr
- name: Conan common config
@ -37,21 +41,8 @@ jobs:
- name: Build
run: |
cd build && \
cmake -GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_SHARED_LIBS=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 \
-DEXIV2_BUILD_SAMPLES=ON \
-DBUILD_WITH_COVERAGE=ON \
-DCMAKE_INSTALL_PREFIX=install \
.. && \
cmake --build . --parallel
cmake --preset linux-coverage -S . -B build
cmake --build build --parallel
- name: Tests + Upload coverage
run: |
@ -78,9 +69,8 @@ jobs:
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get install valgrind ninja-build
pip3 install conan==1.45.0
pip3 install conan==1.48.1
- name: Conan common config
run: |
@ -96,9 +86,8 @@ jobs:
- name: Build
run: |
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=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 -DBUILD_WITH_COVERAGE=OFF -DCMAKE_INSTALL_PREFIX=install ..
cmake --build . --parallel
cmake --preset linux-release -S . -B build
cmake --build build --parallel
- name: Tests with valgrind
run: |
@ -116,7 +105,7 @@ jobs:
- name: install dependencies
run: |
sudo apt-get install ninja-build
pip3 install conan==1.45.0
pip3 install conan==1.48.1
- name: Conan common config
run: |
@ -132,22 +121,8 @@ jobs:
- name: Build
run: |
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 \
-DBUILD_WITH_COVERAGE=OFF \
-DEXIV2_TEAM_USE_SANITIZERS=ON \
-DCMAKE_INSTALL_PREFIX=install \
.. && \
cmake --build . --parallel
cmake --preset linux-sanitizers -S . -B build
cmake --build build --parallel
- name: Tests
run: |
@ -163,9 +138,8 @@ jobs:
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get install valgrind doxygen graphviz gettext
pip3 install conan==1.45.0
sudo apt-get install valgrind doxygen graphviz gettext ninja-build
pip3 install conan==1.48.1
- name: Conan common config
run: |
@ -181,22 +155,8 @@ jobs:
- name: Build
run: |
cd build && \
cmake -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 \
-DBUILD_WITH_COVERAGE=ON \
-DEXIV2_BUILD_DOC=ON \
-DEXIV2_ENABLE_NLS=ON \
-DCMAKE_CXX_FLAGS="-DEXIV2_DEBUG_MESSAGES" \
.. && \
cmake --build . --parallel
cmake --preset linux-release -S . -B build -DEXIV2_BUILD_DOC=ON -DCMAKE_CXX_FLAGS="-DEXIV2_DEBUG_MESSAGES"
cmake --build build --parallel
- name: Generate documentation
run: |

@ -1,5 +1,9 @@
name: On PRs - Linux - Static Analysis
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
pull_request:
@ -19,7 +23,7 @@ jobs:
- name: install dependencies
run: |
pip3 install conan==1.45.0
pip3 install conan==1.48.1
sudo add-apt-repository ppa:ubuntu-lxc/daily -y
wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt |sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.pvs-studio.com/etc/viva64.list
@ -40,19 +44,7 @@ jobs:
- name: Configure
run: |
cd build && \
cmake -DCMAKE_BUILD_TYPE=Debug \
-DBUILD_SHARED_LIBS=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 \
-DBUILD_WITH_COVERAGE=ON \
-DCMAKE_INSTALL_PREFIX=install \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
.. \
cmake --preset linux-debug-NoConan -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- name: Static Analysis
env:

@ -1,5 +1,9 @@
name: On PRs - Mac Matrix
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths-ignore:
@ -33,21 +37,8 @@ jobs:
- name: Build
run: |
mkdir build && cd build && \
cmake -GNinja \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} \
-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
cmake --preset base_mac -S . -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations"
cmake --build build --parallel
- name: Install
run: |

@ -1,5 +1,9 @@
name: On PRs - Mac Special Builds
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
pull_request:
@ -28,22 +32,8 @@ jobs:
- name: Build
run: |
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 \
-DBUILD_WITH_COVERAGE=OFF \
-DEXIV2_TEAM_USE_SANITIZERS=ON \
-DCMAKE_INSTALL_PREFIX=install \
.. && \
cmake --build . --parallel
cmake --preset base_mac -S . -B build -DEXIV2_TEAM_USE_SANITIZERS=ON
cmake --build build --parallel
- name: Tests
run: |

@ -1,5 +1,9 @@
name: On PRs - Windows Matrix
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths-ignore:
@ -50,7 +54,7 @@ jobs:
- name: Install Conan & Common config
run: |
pip.exe install "conan==1.45.0"
pip.exe install "conan==1.48.1"
conan config install https://github.com/conan-io/conanclientcert.git
conan profile new --detect default
conan profile update settings.build_type=${{matrix.build_type}} default
@ -73,23 +77,12 @@ jobs:
- name: Build
run: |
cmake -GNinja `
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} `
-DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} `
-DEXIV2_ENABLE_NLS=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 --preset base_windows -S . -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.shared_libraries}}
cmake --build build --parallel
- name: Install
run: |
cd build
cmake --install .
tree /f install
cmake --install build
- name: Test
if: ${{matrix.platform == 'x64'}}
@ -122,26 +115,26 @@ jobs:
install: >-
base-devel
pacboy: >-
toolchain:p
cc:p
gcc-libs:p
libwinpthread:p
cmake:p
ninja:p
expat:p
gettext:p
gtest:p
libiconv:p
zlib:p
curl:p
- name: Build
run: |
cmake -G"MSYS Makefiles" \
-DCMAKE_CXX_FLAGS=-Wno-deprecated \
cmake --preset base_windows -S . -B build \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} \
-DEXIV2_BUILD_SAMPLES=ON \
-DEXIV2_ENABLE_NLS=OFF \
-DEXIV2_ENABLE_WEBREADY=ON \
-DEXIV2_ENABLE_BMFF=ON \
-DEXIV2_BUILD_UNIT_TESTS=ON \
-S . -B build && \
-DCONAN_AUTO_INSTALL=OFF \
-DCMAKE_CXX_FLAGS=-Wno-deprecated \
-DEXIV2_TEAM_WARNINGS_AS_ERRORS=OFF
cmake --build build --parallel
- name: Test
@ -176,6 +169,7 @@ jobs:
gcc-g++
cmake
ninja
libcurl-devel
libexpat-devel
libxml2-devel
libxslt-devel
@ -190,6 +184,7 @@ jobs:
-DEXIV2_ENABLE_NLS=OFF \
-DEXIV2_ENABLE_WIN_UNICODE=OFF \
-DEXIV2_ENABLE_WEBREADY=ON \
-DEXIV2_ENABLE_CURL=ON \
-DEXIV2_ENABLE_BMFF=ON \
-DEXIV2_BUILD_UNIT_TESTS=OFF \
-S . -B build && \

@ -8,6 +8,10 @@ on:
paths-ignore:
- "*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
name: On PUSH - Basic CI for main platforms
jobs:
@ -41,35 +45,16 @@ jobs:
- name: Install Conan & Common config
run: |
pip.exe install "conan==1.45.0"
pip.exe install "conan==1.48.1"
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: |
md build
cd build
conan profile list
conan install .. --build missing
- name: Build
run: |
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 --preset win-release -S . -B build
cmake --build build --parallel
@ -88,7 +73,7 @@ jobs:
- name: install dependencies
run: |
sudo apt-get install ninja-build
pip3 install conan==1.45.0
pip3 install conan==1.48.1
- name: Conan
run: |
@ -100,20 +85,8 @@ jobs:
- name: build and compile
run: |
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 \
.. && \
cmake --build . --parallel
cmake --preset linux-release-NoConan -S . -B build
cmake --build build --parallel
- name: Test
run: |
@ -141,21 +114,8 @@ jobs:
- name: build and compile
run: |
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
cmake --preset base_mac -S . -B build -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations"
cmake --build build --parallel
- name: Test
run: |

@ -1,5 +1,9 @@
name: On PUSH - Linux Special Builds for main branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
@ -8,6 +12,7 @@ on:
- '!*'
paths-ignore:
- "*.md"
workflow_dispatch:
jobs:
special_debugRelease:
@ -19,8 +24,9 @@ jobs:
- name: install dependencies
run: |
pip3 install conan==1.45.0
pip install gcovr
sudo apt-get install ninja-build
pip3 install conan==1.48.1
pip3 install gcovr
- name: Conan common config
run: |
@ -36,20 +42,8 @@ jobs:
- name: Build
run: |
cd build && \
cmake -DCMAKE_BUILD_TYPE=Debug \
-DBUILD_SHARED_LIBS=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 \
-DEXIV2_BUILD_SAMPLES=ON \
-DBUILD_WITH_COVERAGE=ON \
-DCMAKE_INSTALL_PREFIX=install \
.. && \
cmake --build .
cmake --preset linux-coverage -S . -B build
cmake --build build
- name: Tests + Upload coverage
run: |

@ -1,4 +1,7 @@
name: Clang Format Checker
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on: [push, pull_request]
jobs:
clang-format-checking:

@ -1,4 +1,7 @@
name: Release
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
tags:
@ -22,7 +25,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get install ninja-build gettext doxygen graphviz
pip3 install conan==1.45.0
pip3 install conan==1.48.1
- name: Conan common config
run: |
@ -39,16 +42,7 @@ jobs:
- name: Build packaged release
run: |
cmake -GNinja -S . -B build \
-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 \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DEXIV2_BUILD_DOC=ON
cmake --preset linux-all -S . -B build -DEXIV2_TEAM_PACKAGING=ON -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DEXIV2_ENABLE_WEBREADY=OFF -DEXIV2_ENABLE_CURL=OFF
cmake --build build -t doc
cmake --build build -t package
@ -114,20 +108,28 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: 3.9
python-version: 3.7
- name: Install doxygen
run: |
choco install doxygen.install
choco install graphviz
- name: Restore conan cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/conanCache
key: ${{runner.os}}-release-win-${{ hashFiles('conanfile.py') }}
- name: Install Conan & Common config
run: |
pip.exe install "conan==1.45.0"
pip.exe install "conan==1.48.1"
conan profile new --detect default
conan profile show default
conan profile update settings.build_type=Release 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: |
@ -137,18 +139,9 @@ jobs:
- name: Build packaged release
run: |
cmake -GNinja -S . -B build `
-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 `
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON `
-DEXIV2_BUILD_DOC=ON
cmake --build build -t doc
cmake --build build -t package
cmake --preset win-release -S . -B build -DEXIV2_TEAM_PACKAGING=ON -DEXIV2_BUILD_DOC=ON -DEXIV2_ENABLE_WEBREADY=OFF -DEXIV2_ENABLE_CURL=OFF
cmake --build build --parallel -t doc
cmake --build build --parallel -t package
- uses: actions/upload-artifact@v3
with:
@ -196,14 +189,14 @@ jobs:
with:
script: |
try{
const rel_id = await github.repos.getReleaseByTag({
const rel_id = await github.rest.repos.getReleaseByTag({
...context.repo,
tag: "nightly"
}).then(result => result.data.id);
console.log( "Found existing nightly release with id: ", rel_id);
await github.repos.deleteRelease({
await github.rest.repos.deleteRelease({
...context.repo,
release_id: rel_id
});
@ -215,7 +208,7 @@ jobs:
}
try{
await github.git.deleteRef({
await github.rest.git.deleteRef({
...context.repo,
ref: "tags/nightly"
});

1
.gitignore vendored

@ -25,5 +25,6 @@ doc/html
contrib/vms/.vagrant
/.vscode
.vs/
CMakeUserPresets.json
*cppcheck*

@ -0,0 +1,149 @@
{
"version": 3,
"configurePresets": [
{
"name": "base_ninja",
"description": "Base preset to use ninja as generator",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build-${presetName}",
"installDir": "${sourceDir}/build-${presetName}/install",
"cacheVariables": {
"BUILD_SHARED_LIBS": true,
"CONAN_AUTO_INSTALL": true,
"EXIV2_BUILD_SAMPLES": true,
"EXIV2_ENABLE_WEBREADY": true,
"EXIV2_ENABLE_CURL": true,
"EXIV2_ENABLE_PNG": true,
"EXIV2_ENABLE_BMFF": true,
"EXIV2_BUILD_UNIT_TESTS": true,
"EXIV2_TEAM_WARNINGS_AS_ERRORS": true,
"EXIV2_ENABLE_NLS": false
}
},
{
"name": "base_windows",
"description": "Base preset for Windows (specially useful for CI jobs)",
"displayName": "Base preset for Windows (specially useful for CI jobs)",
"inherits": "base_ninja",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "base_linux",
"description": "Base preset for Linux",
"displayName": "Base preset for Linux with default compiler: GCC (specially useful for CI jobs)",
"inherits": "base_ninja",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"cacheVariables": {
"BUILD_WITH_CCACHE": true
}
},
{
"name": "base_mac",
"description": "Base preset for macOS (no conan usage)",
"displayName": "Base preset for macOS with default compiler: AppleClang (specially useful for CI jobs)",
"inherits": "base_ninja",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CONAN_AUTO_INSTALL": false
}
},
{
"name": "msvc",
"displayName": "Visual Studio cl toolchain (also usable from VS Code)",
"inherits": "base_windows",
"architecture": {
"value": "x64",
"strategy": "external"
},
"toolset": {
"value": "host=x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe",
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "win-debug",
"displayName": "Windows Debug with configured architecture",
"description": "Sets Debug build type with the preloaded Visual Studio Environment",
"inherits": "base_windows",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "win-release",
"displayName": "Windows Release with configured architecture",
"description": "Sets Release build type with the preloaded Visual Studio Environment",
"inherits": "base_windows",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug (Ninja Generator) with default architecture",
"inherits": "base_linux",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
},
{
"name": "linux-release",
"displayName": "Linux Release (Ninja Generator) with default architecture",
"inherits": "base_linux",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
},
{
"name": "linux-debug-NoConan",
"displayName": "Same as linux-debug but without automatic conan execution",
"inherits": "linux-debug",
"cacheVariables": { "CONAN_AUTO_INSTALL": false }
},
{
"name": "linux-release-NoConan",
"displayName": "Same as linux-release but without automatic conan execution",
"inherits": "linux-release",
"cacheVariables": { "CONAN_AUTO_INSTALL": false }
},
{
"name": "linux-coverage",
"displayName": "Same as linux-debug-NoConan with coverage enabled",
"inherits": "linux-debug-NoConan",
"cacheVariables": { "BUILD_WITH_COVERAGE": true }
},
{
"name": "linux-sanitizers",
"displayName": "Same as linux-debug-NoConan with sanitizers enabled",
"inherits": "linux-debug-NoConan",
"cacheVariables": { "EXIV2_TEAM_USE_SANITIZERS": true }
},
{
"name": "linux-all",
"displayName": "Same as linux-release-NoConan and with rest of things enabled (doc + NLS)",
"description": "requires installation of packages: doxygen graphviz gettext",
"inherits": "linux-release-NoConan",
"cacheVariables": {
"EXIV2_ENABLE_NLS": true,
"EXIV2_BUILD_DOC": true
}
}
]
}

@ -32,6 +32,7 @@ The file ReadMe.txt in a build bundle describes how to install the library on th
- [Building, Installing, Using and Uninstalling Exiv2](#B_I_U)
- [Build, Install, Use and Uninstall Exiv2 on a UNIX-like system](#B_I_U_Unix)
- [Build and Install Exiv2 with Visual Studio](#B_I_U_VisualStudio)
- [Configure the project with CMake presets](#CMakePresets)
- [Build Options](#BuildOptions)
- [Dependencies](#Dependencies)
- [Building and linking your code with Exiv2](#BuildAndLinkYourCode)
@ -126,7 +127,7 @@ path.
## Build and Install Exiv2 with Visual Studio
We recommend that you use conan to download the Exiv2 external dependencies on Windows. On other platforms (macOS, Linux and others), traditionally the platform package managers have been used. These are discussed at [Platform Notes](#PlatformNotes). The options to configure and compile the project using Visual Studio are similar to UNIX like systems.
We recommend to use conan to download the Exiv2 external dependencies on Windows. On other platforms (macOS, Linux and others), traditionally the platform package managers have been used. However, conan can be used in any platform/architecture to bring the project dependencies. These are discussed at [Platform Notes](#PlatformNotes). The options to configure and compile the project using Visual Studio are similar to UNIX like systems.
See [README-CONAN](README-CONAN.md) for more information about Conan.
When you build, you may install with the following command.
@ -136,6 +137,99 @@ When you build, you may install with the following command.
```
This will create and copy the exiv2 build artefacts to `%ProgramFiles%/exiv2`. To be able to run the `exiv2` command line application from any terminal you should modify your path to include `%ProgramFiles%/exiv2/bin`.
[TOC](#TOC)
<div id="CMakePresets">
## Configure the project with the CMake presets
CMake presets (see documentation [here](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html)) were added recently to the project to ease the CMake configuration process for typical configurations. The presets are defined in the file `CMakePresets.json` and they can be used from the terminal or interpreted by different IDEs. Please note that one needs to use a recent version of CMake (>= 3.21) supporting the presets feature.
One can list the available presets using the `--list-presets` option:
```bash
# Running the command from a Windows terminal
$ cmake --list-presets
Available configure presets:
"msvc" - Visual Studio cl toolchain (also usable from VS Code)
"win-debug" - Windows Debug with configured architecture
"win-release" - Windows Release with configured architecture
# Running the command from a Linux terminal
$ cmake --list-presets
Available configure presets:
"linux-debug" - Linux Debug with default architecture
"linux-release" - Linux Release with default architecture
```
The project configuration with a specific preset can be choosen with the CMake `--preset` option. In the following terminal output we comment out some interesting things happening during the project configuration:
```bash
# Configuring the project using a preset
$ cmake --preset win-release
Preset CMake variables:
# Note that with the usage of a preset, we pass many different options to CMake.
BUILD_SHARED_LIBS:BOOL="TRUE"
CMAKE_BUILD_TYPE="Release"
CMAKE_INSTALL_PREFIX:PATH="C:/dev/personal/exiv2/build-win-release/install"
# A build & install directory are configured with the preset
CONAN_AUTO_INSTALL:BOOL="TRUE"
EXIV2_BUILD_SAMPLES:BOOL="TRUE"
EXIV2_BUILD_UNIT_TESTS:BOOL="TRUE"
EXIV2_ENABLE_BMFF:BOOL="TRUE"
EXIV2_ENABLE_CURL:BOOL="TRUE"
EXIV2_ENABLE_NLS:BOOL="FALSE"
EXIV2_ENABLE_PNG:BOOL="TRUE"
EXIV2_ENABLE_WEBREADY:BOOL="TRUE"
EXIV2_TEAM_WARNINGS_AS_ERRORS:BOOL="TRUE"
# Conan can be automatically detected in your system and it is run automatically to bring the
# project dependencies
-- Conan: Detected VS runtime: MD
-- Conan: checking conan executable
-- Conan: Found program C:/dev/envs/conan/Scripts/conan.exe
-- Conan: Version found Conan version 1.47.0
-- Conan executing: C:/dev/envs/conan/Scripts/conan.exe install .. --remote conancenter --build missing --options webready=True --settings arch=x86_64 --settings build_type=Release --settings compiler=Visual Studio --settings compiler.version=17 --settings compiler.runtime=MD
...
# CMake finds the project dependencies which were automatically handled by conan
-- Conan: Using autogenerated FindZLIB.cmake
-- Library zlib found C:/Users/luis/.conan/data/zlib/1.2.11/_/_/package/-- Conan: Using autogenerated FindCURL.cmake
-- Library libcurl_imp found C:/Users/luis/.conan/data/libcurl/7.79.0/_/_/package/
...
# CMake finish the project configuration and prints a report
-- Install prefix: C:/dev/personal/exiv2/build-win-release/install
-- ------------------------------------------------------------------
-- CMake Generator: Ninja
-- CMAKE_BUILD_TYPE: Release
-- Compiler info: MSVC (C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.30.30705/bin/Hostx64/x64/cl.exe) ; version: 19.30.30705.0
-- CMAKE_CXX_STANDARD:17
-- --- Compiler flags ---
-- General: /DWIN32 /D_WINDOWS /W3 /GR /EHsc
/MP
/utf-8
/WX
-- Extra:
-- Debug: /MDd /Zi /Ob0 /Ox /Zo
-- Release: /MD /O2 /DNDEBUG
-- RelWithDebInfo: /MD /Zi /O2 /DNDEBUG
-- MinSizeRel: /MD /O1 /DNDEBUG
-- --- Linker flags ---
-- General: /machine:x64 /WX
-- Debug: /debug /INCREMENTAL
-- Release: /INCREMENTAL:NO
-- RelWithDebInfo: /debug /INCREMENTAL
-- MinSizeRel: /INCREMENTAL:NO
--
...
-- Build files have been written to: C:/dev/personal/exiv2/build-win-release
```
Note that the usage of CMake presets allow the project contributors to use the same set of options easily in different environments (using terminal, IDEs or CI).
[TOC](#TOC)
<div id="BuildOptions">
@ -145,7 +239,7 @@ There are two groups of CMake options which are relevant to the project: global
| Options | Purpose (_default_) |
|:------------- |:------------- |
| CMAKE\_INSTALL\_PREFIX<br/>CMAKE\_BUILD\_TYPE<br/>BUILD\_SHARED\_LIBS | Where to install on your computer _**(/usr/local)**_<br/>Type of build _**(Release)**_ See: [Debugging Exiv2](#Debugging) <br/>Build exiv2lib as shared or static _**(On)**_ |
| CMAKE\_INSTALL\_PREFIX<br/>CMAKE\_BUILD\_TYPE<br/>BUILD\_SHARED\_LIBS | Where to install on your computer _**(/usr/local)**_<br/>Type of build _**(Release)**_ See: [Debugging Exiv2](#Debugging) <br/>Build exiv2lib as SHARED or STATIC |
Options defined at `exiv2/CMakeLists.txt` include:
@ -160,10 +254,10 @@ option( EXIV2_ENABLE_BMFF "Build with BMFF support" ON
577 rmills@rmillsmm:~/gnu/github/exiv2/exiv2 $
```
Options are defined on the CMake command-line:
Using the command-line, these variables can be set/updated using the option `-D`:
```bash
$ cmake -DBUILD_SHARED_LIBS=On -DEXIV2_ENABLE_NLS=Off
$ cmake -DBUILD_SHARED_LIBS=ON -DEXIV2_ENABLE_NLS=OFF
```
[TOC](#TOC)
@ -175,9 +269,9 @@ The following Exiv2 features require external libraries:
| Feature | Package | Default | To change default | Availability |
|:-------------------------- |:-------- |:--------:| :---------------------------- |:----------- |
| PNG image support | zlib | ON | -DEXIV2\_ENABLE\_PNG=Off | [http://zlib.net/](http://zlib.net/) |
| XMP support | expat | ON | -DEXIV2\_ENABLE\_XMP=Off | [http://expat.sourceforge.net](http://expat.sourceforge.net)/<br/>Use _**Expat 2.2.6**_ and later |
| Natural language system | gettext | OFF | -DEXIV2\_ENABLE\_NLS=On | [http://www.gnu.org/software/gettext/](http://www.gnu.org/software/gettext/) |
| PNG image support | zlib | ON | -DEXIV2\_ENABLE\_PNG=OFF | [http://zlib.net/](http://zlib.net/) |
| XMP support | expat | ON | -DEXIV2\_ENABLE\_XMP=OFF | [http://expat.sourceforge.net](http://expat.sourceforge.net)/<br/>Use _**Expat 2.2.6**_ and later |
| Natural language system | gettext | OFF | -DEXIV2\_ENABLE\_NLS=ON | [http://www.gnu.org/software/gettext/](http://www.gnu.org/software/gettext/) |
| Character set conversion | libiconv | | Disabled for Visual Studio.<br>Linked when installed on UNIX like platforms. | [https://www.gnu.org/software/libiconv/](https://www.gnu.org/software/libiconv/) |
On UNIX systems, you may install the dependencies using the distribution's package management system. Install the
@ -297,7 +391,7 @@ Localisation is supported on a UNIX-like platform: Linux, macOS, Cygwin and Min
Crowdin have provided Exiv2 with a free open-source license to use their services. The Exiv2 localisation project is located at [https://crowdin.com/project/exiv2](https://crowdin.com/project/exiv2). You will also need to register to have a free user account on Crowdin. The Crowdin setup is discussed here: [https://github.com/Exiv2/exiv2/issues/1510](https://github.com/Exiv2/exiv2/issues/1510). It is recommended that you coordinate with Leonardo before contributing localisation changes on Crowdin. You can contact Leonardo by via GitHub.
To build localisation support, use the CMake option `-DEXIV2_ENABLE_NLS=On`. You must install the `gettext` package with your package manager or from source. The `gettext` package is available from [http://www.gnu.org/software/gettext/](http://www.gnu.org/software/gettext/) and includes the library `libintl` and utilities to build localisation files. If CMake produces error messages which mention libintl or gettext, you should verify that the package `gettext` has been correctly built and installed.
To build localisation support, use the CMake option `-DEXIV2_ENABLE_NLS=ON`. You must install the `gettext` package with your package manager or from source. The `gettext` package is available from [http://www.gnu.org/software/gettext/](http://www.gnu.org/software/gettext/) and includes the library `libintl` and utilities to build localisation files. If CMake produces error messages which mention libintl or gettext, you should verify that the package `gettext` has been correctly built and installed.
You must install the build to test localisation. This ensures that the localisation message files can be found at run-time. You cannot test localisation in the directory `build\bin`.
@ -386,11 +480,11 @@ $
Building documentation requires installing special tools. You will probably prefer to
read the documentation on-line from the project website: https://exiv2.org
To build documentation, use the CMake option **`-DEXIV2_BUILD_DOC=On`**.
To build documentation, use the CMake option **`-DEXIV2_BUILD_DOC=ON`**.
Additionally, you will require an additional build step to actually build the documentation.
```bash
$ cmake ..options.. -DEXIV2_BUILD_DOC=On
$ cmake ..options.. -DEXIV2_BUILD_DOC=ON
$ cmake --build . --target doc
```
@ -437,7 +531,7 @@ When the Exiv2 websites are updated, the generated tag webpages are reformatted
## Building Exiv2 Packages
To enable the building of Exiv2 packages, use the CMake option `-DEXIV2_TEAM_PACKAGING=On`.
To enable the building of Exiv2 packages, use the CMake option `-DEXIV2_TEAM_PACKAGING=ON`.
You should not build Exiv2 Packages. This feature is intended for use by Team Exiv2 to create Platform and Source Packages on the buildserver.
@ -451,7 +545,7 @@ Create and build exiv2 for your platform.
$ git clone https://github.com/exiv2/exiv2
$ mkdir -p exiv2/build
$ cd exiv2/build
$ cmake .. -G "Unix Makefiles" -DEXIV2_TEAM_PACKAGING=On
$ cmake .. -G "Unix Makefiles" -DEXIV2_TEAM_PACKAGING=ON
...
-- Build files have been written to: .../build
$ cmake --build . --config Release
@ -603,19 +697,19 @@ Installing and using ccache (and other similar utilities), is platform dependent
$ sudo apt install --yes ccache
```
To build with ccache, use the CMake option **-DBUILD\_WITH\_CCACHE=On**
To build with ccache, use the CMake option **-DBUILD\_WITH\_CCACHE=ON**
```bash
$ cd <exiv2dir>
$ mkdir build ; cd build ; cd build
$ cmake .. -G "Unix Makefiles" -DBUILD_WITH_CCACHE=On
$ cmake .. -G "Unix Makefiles" -DBUILD_WITH_CCACHE=ON
$ cmake --build .
# Build again to appreciate the performance gain
$ 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)
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)
<div id="ThreadSafety">
@ -707,10 +801,9 @@ $ make
Note, you may wish to choose to build with optional features and/or build static libraries. To do this, request appropriately on the mingw64-cmake command:
```bash
$ mingw64-cmake .. -DEXIV2_TEAM_EXTRA_WARNINGS=On \
-DEXIV2_ENABLE_WEBREADY=On \
-DEXIV2_ENABLE_WIN_UNICODE=On \
-DBUILD_SHARED_LIBS=Off
$ mingw64-cmake .. -DEXIV2_TEAM_EXTRA_WARNINGS=ON \
-DEXIV2_ENABLE_WEBREADY=ON \
-DBUILD_SHARED_LIBS=OFF
```
The options available for cross-compiling are the same as provided for all builds. See: [Build Options](#BuildOptions)
@ -773,7 +866,7 @@ You will find that 3 tests fail at the end of the test suite. It is safe to ign
## 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.
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.
CMake creates your build artefacts in the directories `bin` and `lib`. The `bin` directory contains your executables and .DLLs. The `lib` directory contains your static libraries. When you install exiv2, the build artefacts are copied to your system's prefix directory which by default is `/usr/local/`. If you wish to test and use your build without installing, you will have to set you PATH appropriately. Linux/Unix users should also set `LD_LIBRARY_PATH` and macOS users should set `DYLD_LIBRARY_PATH`.
@ -806,13 +899,13 @@ This is discussed: [https://github.com/Exiv2/exiv2/issues/1230](https://github.c
**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_ENABLE_BMFF=On).
The return value from `enableBMFF()` is true if the library has been build with bmff support (CMake option -DEXIV2_ENABLE_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.
@ -928,7 +1021,7 @@ The Variable EXIV2\_PORT or EXIV2\_HTTP can be set to None to skip http tests.
You can run tests directly from the build:
```bash
$ cmake .. -G "Unix Makefiles" -DEXIV2_BUILD_UNIT_TESTS=On
$ cmake .. -G "Unix Makefiles" -DEXIV2_BUILD_UNIT_TESTS=ON
... lots of output and build summary ...
$ cmake --build .
... lots of output ...
@ -993,7 +1086,7 @@ As a summary, the procedure is:
c:\...\exiv2>mkdir build
c:\...\exiv2>cd build
c:\...\exiv2\build>conan install .. --build missing --profile msvc2019Release
c:\...\exiv2\build>cmake .. -DEXIV2_BUILD_UNIT_TESTS=On -G "Visual Studio 16 2019"
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>ctest -C Release
@ -1012,7 +1105,7 @@ set EXIV2_PORT=
## Unit Tests
The code for the unit tests is in `<exiv2dir>/unitTests`. To include unit tests in the build, use the *CMake* option `-DEXIV2_BUILD_UNIT_TESTS=On`.
The code for the unit tests is in `<exiv2dir>/unitTests`. To include unit tests in the build, use the *CMake* option `-DEXIV2_BUILD_UNIT_TESTS=ON`.
There is a discussion on the web about installing GTest: [https://github.com/Exiv2/exiv2/issues/575](https://github.com/Exiv2/exiv2/issues/575)

@ -6,12 +6,14 @@
#include "app_utils.hpp"
#include "config.h"
#include "easyaccess.hpp"
#include "enforce.hpp"
#include "exif.hpp"
#include "futils.hpp"
#include "i18n.h" // NLS support.
#include "image.hpp"
#include "iptc.hpp"
#include "preview.hpp"
#include "safe_op.hpp"
#include "types.hpp"
#include "xmp_exiv2.hpp"
@ -38,9 +40,10 @@
#include <utime.h>
#endif
#if !defined(__MINGW__) && !defined(_MSC_VER)
#define _fileno(a) a
#define _setmode(a, b)
#ifndef _WIN32
#define _setmode(a, b) \
do { \
} while (false)
#endif
namespace fs = std::filesystem;
@ -177,7 +180,7 @@ int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::stri
ascii.write_uint8(str.size() * 3, 0);
std::copy(str.begin(), str.end(), iccProfile.begin());
if (Exiv2::base64encode(iccProfile.c_data(), str.size(), reinterpret_cast<char*>(ascii.data()), str.size() * 3)) {
long chunk = 60;
const size_t chunk = 60;
std::string code = std::string("data:") + ascii.c_str();
size_t length = code.size();
for (size_t start = 0; start < length; start += chunk) {
@ -197,34 +200,25 @@ int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::stri
int Print::run(const std::string& path) {
try {
path_ = path;
int rc = 0;
switch (Params::instance().printMode_) {
case Params::pmSummary:
rc = Params::instance().greps_.empty() ? printSummary() : printList();
break;
return Params::instance().greps_.empty() ? printSummary() : printList();
case Params::pmList:
rc = printList();
break;
return printList();
case Params::pmComment:
rc = printComment();
break;
return printComment();
case Params::pmPreview:
rc = printPreviewList();
break;
return printPreviewList();
case Params::pmStructure:
rc = printStructure(std::cout, Exiv2::kpsBasic, path_);
break;
return printStructure(std::cout, Exiv2::kpsBasic, path_);
case Params::pmRecursive:
rc = printStructure(std::cout, Exiv2::kpsRecursive, path_);
break;
return printStructure(std::cout, Exiv2::kpsRecursive, path_);
case Params::pmXMP:
rc = setModeAndPrintStructure(Exiv2::kpsXMP, path_, binary());
break;
return setModeAndPrintStructure(Exiv2::kpsXMP, path_, binary());
case Params::pmIccProfile:
rc = setModeAndPrintStructure(Exiv2::kpsIccProfile, path_, binary());
break;
return setModeAndPrintStructure(Exiv2::kpsIccProfile, path_, binary());
}
return rc;
return 0;
} catch (const Exiv2::Error& e) {
std::cerr << "Exiv2 exception in print action for file " << path << ":\n" << e << "\n";
return 1;
@ -242,7 +236,7 @@ int Print::printSummary() {
auto image = Exiv2::ImageFactory::open(path_);
image->readMetadata();
Exiv2::ExifData& exifData = image->exifData();
const Exiv2::ExifData& exifData = image->exifData();
align_ = 16;
// Filename
@ -362,8 +356,8 @@ int Print::printList() {
auto image = Exiv2::ImageFactory::open(path_);
image->readMetadata();
// Set defaults for metadata types and data columns
if (Params::instance().printTags_ == Exiv2::mdNone) {
Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp;
if (Params::instance().printTags_ == MetadataId::invalid) {
Params::instance().printTags_ = MetadataId::exif | MetadataId::iptc | MetadataId::xmp;
}
if (Params::instance().printItems_ == 0) {
Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans;
@ -374,7 +368,7 @@ int Print::printList() {
int Print::printMetadata(const Exiv2::Image* image) {
bool ret = false;
bool noExif = false;
if (Params::instance().printTags_ & Exiv2::mdExif) {
if ((Params::instance().printTags_ & MetadataId::exif) == MetadataId::exif) {
const Exiv2::ExifData& exifData = image->exifData();
for (auto&& md : exifData) {
ret |= printMetadatum(md, image);
@ -384,7 +378,7 @@ int Print::printMetadata(const Exiv2::Image* image) {
}
bool noIptc = false;
if (Params::instance().printTags_ & Exiv2::mdIptc) {
if ((Params::instance().printTags_ & MetadataId::iptc) == MetadataId::iptc) {
const Exiv2::IptcData& iptcData = image->iptcData();
for (auto&& md : iptcData) {
ret |= printMetadatum(md, image);
@ -394,7 +388,7 @@ int Print::printMetadata(const Exiv2::Image* image) {
}
bool noXmp = false;
if (Params::instance().printTags_ & Exiv2::mdXmp) {
if ((Params::instance().printTags_ & MetadataId::xmp) == MetadataId::xmp) {
const Exiv2::XmpData& xmpData = image->xmpData();
for (auto&& md : xmpData) {
ret |= printMetadatum(md, image);
@ -434,7 +428,7 @@ bool Print::grepTag(const std::string& key) {
bool Print::keyTag(const std::string& key) {
bool result = Params::instance().keys_.empty();
for (auto&& k : Params::instance().keys_) {
for (const auto& k : Params::instance().keys_) {
if (result)
break;
result = key == k;
@ -496,6 +490,12 @@ bool Print::printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* pImag
first = false;
std::cout << std::setw(30) << std::setfill(' ') << std::left << md.tagLabel();
}
if (Params::instance().printItems_ & Params::prDesc) {
if (!first)
std::cout << " ";
first = false;
std::cout << std::setw(30) << std::setfill(' ') << std::left << md.tagDesc();
}
if (Params::instance().printItems_ & Params::prType) {
if (!first)
std::cout << " ";
@ -586,7 +586,7 @@ int Print::printPreviewList() {
int cnt = 0;
Exiv2::PreviewManager pm(*image);
Exiv2::PreviewPropertiesList list = pm.getPreviewProperties();
for (auto&& pos : list) {
for (const auto& pos : list) {
if (manyFiles) {
std::cout << std::setfill(' ') << std::left << std::setw(20) << path_ << " ";
}
@ -735,7 +735,7 @@ int Erase::eraseThumbnail(Exiv2::Image* image) {
}
int Erase::eraseExifData(Exiv2::Image* image) {
if (Params::instance().verbose_ && image->exifData().count() > 0) {
if (Params::instance().verbose_ && !image->exifData().empty()) {
std::cout << _("Erasing Exif data from the file") << std::endl;
}
image->clearExifData();
@ -743,7 +743,7 @@ int Erase::eraseExifData(Exiv2::Image* image) {
}
int Erase::eraseIptcData(Exiv2::Image* image) {
if (Params::instance().verbose_ && image->iptcData().count() > 0) {
if (Params::instance().verbose_ && !image->iptcData().empty()) {
std::cout << _("Erasing IPTC data from the file") << std::endl;
}
image->clearIptcData();
@ -759,7 +759,7 @@ int Erase::eraseComment(Exiv2::Image* image) {
}
int Erase::eraseXmpData(Exiv2::Image* image) {
if (Params::instance().verbose_ && image->xmpData().count() > 0) {
if (Params::instance().verbose_ && !image->xmpData().empty()) {
std::cout << _("Erasing XMP data from the file") << std::endl;
}
image->clearXmpData(); // Quick fix for bug #612
@ -1141,28 +1141,28 @@ int Modify::applyCommands(Exiv2::Image* pImage) {
}
// loop through command table and apply each command
ModifyCmds& modifyCmds = Params::instance().modifyCmds_;
const ModifyCmds& modifyCmds = Params::instance().modifyCmds_;
int rc = 0;
int ret = 0;
for (auto&& cmd : modifyCmds) {
for (const auto& cmd : modifyCmds) {
switch (cmd.cmdId_) {
case add:
case CmdId::add:
ret = addMetadatum(pImage, cmd);
if (rc == 0)
rc = ret;
break;
case set:
case CmdId::set:
ret = setMetadatum(pImage, cmd);
if (rc == 0)
rc = ret;
break;
case del:
case CmdId::del:
delMetadatum(pImage, cmd);
break;
case reg:
case CmdId::reg:
regNamespace(cmd);
break;
case invalidCmdId:
case CmdId::invalid:
break;
}
}
@ -1182,13 +1182,13 @@ int Modify::addMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
auto value = Exiv2::Value::create(modifyCmd.typeId_);
int rc = value->read(modifyCmd.value_);
if (0 == rc) {
if (modifyCmd.metadataId_ == exif) {
if (modifyCmd.metadataId_ == MetadataId::exif) {
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
}
if (modifyCmd.metadataId_ == iptc) {
if (modifyCmd.metadataId_ == MetadataId::iptc) {
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
}
if (modifyCmd.metadataId_ == xmp) {
if (modifyCmd.metadataId_ == MetadataId::xmp) {
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
}
} else {
@ -1211,19 +1211,19 @@ int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
Exiv2::IptcData& iptcData = pImage->iptcData();
Exiv2::XmpData& xmpData = pImage->xmpData();
Exiv2::Metadatum* metadatum = nullptr;
if (modifyCmd.metadataId_ == exif) {
if (modifyCmd.metadataId_ == MetadataId::exif) {
auto pos = exifData.findKey(Exiv2::ExifKey(modifyCmd.key_));
if (pos != exifData.end()) {
metadatum = &(*pos);
}
}
if (modifyCmd.metadataId_ == iptc) {
if (modifyCmd.metadataId_ == MetadataId::iptc) {
auto pos = iptcData.findKey(Exiv2::IptcKey(modifyCmd.key_));
if (pos != iptcData.end()) {
metadatum = &(*pos);
}
}
if (modifyCmd.metadataId_ == xmp) {
if (modifyCmd.metadataId_ == MetadataId::xmp) {
auto pos = xmpData.findKey(Exiv2::XmpKey(modifyCmd.key_));
if (pos != xmpData.end()) {
metadatum = &(*pos);
@ -1244,13 +1244,13 @@ int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
if (metadatum) {
metadatum->setValue(value.get());
} else {
if (modifyCmd.metadataId_ == exif) {
if (modifyCmd.metadataId_ == MetadataId::exif) {
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
}
if (modifyCmd.metadataId_ == iptc) {
if (modifyCmd.metadataId_ == MetadataId::iptc) {
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
}
if (modifyCmd.metadataId_ == xmp) {
if (modifyCmd.metadataId_ == MetadataId::xmp) {
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
}
}
@ -1271,21 +1271,21 @@ void Modify::delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
Exiv2::ExifData& exifData = pImage->exifData();
Exiv2::IptcData& iptcData = pImage->iptcData();
Exiv2::XmpData& xmpData = pImage->xmpData();
if (modifyCmd.metadataId_ == exif) {
if (modifyCmd.metadataId_ == MetadataId::exif) {
Exiv2::ExifData::iterator pos;
const Exiv2::ExifKey exifKey(modifyCmd.key_);
while ((pos = exifData.findKey(exifKey)) != exifData.end()) {
exifData.erase(pos);
}
}
if (modifyCmd.metadataId_ == iptc) {
if (modifyCmd.metadataId_ == MetadataId::iptc) {
Exiv2::IptcData::iterator pos;
const Exiv2::IptcKey iptcKey(modifyCmd.key_);
while ((pos = iptcData.findKey(iptcKey)) != iptcData.end()) {
iptcData.erase(pos);
}
}
if (modifyCmd.metadataId_ == xmp) {
if (modifyCmd.metadataId_ == MetadataId::xmp) {
Exiv2::XmpData::iterator pos;
const Exiv2::XmpKey xmpKey(modifyCmd.key_);
if ((pos = xmpData.findKey(xmpKey)) != xmpData.end()) {
@ -1407,19 +1407,47 @@ int Adjust::adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, co
std::cerr << path << ": " << _("Failed to parse timestamp") << " `" << timeStr << "'\n";
return 1;
}
const long monOverflow = (tm.tm_mon + monthAdjustment_) / 12;
tm.tm_mon = (tm.tm_mon + monthAdjustment_) % 12;
tm.tm_year += yearAdjustment_ + monOverflow;
// bounds checking for yearAdjustment_
enforce<std::overflow_error>(yearAdjustment_ >= std::numeric_limits<decltype(tm.tm_year)>::min(),
"year adjustment too low");
enforce<std::overflow_error>(yearAdjustment_ <= std::numeric_limits<decltype(tm.tm_year)>::max(),
"year adjustment too high");
const auto yearAdjustment = static_cast<decltype(tm.tm_year)>(yearAdjustment_);
// bounds checking for monthAdjustment_
enforce<std::overflow_error>(monthAdjustment_ >= std::numeric_limits<decltype(tm.tm_mon)>::min(),
"month adjustment too low");
enforce<std::overflow_error>(monthAdjustment_ <= std::numeric_limits<decltype(tm.tm_mon)>::max(),
"month adjustment too high");
const auto monthAdjustment = static_cast<decltype(tm.tm_mon)>(monthAdjustment_);
// bounds checking for dayAdjustment_
static constexpr time_t secondsInDay = 24 * 60 * 60;
enforce<std::overflow_error>(dayAdjustment_ >= std::numeric_limits<time_t>::min() / secondsInDay,
"day adjustment too low");
enforce<std::overflow_error>(dayAdjustment_ <= std::numeric_limits<time_t>::max() / secondsInDay,
"day adjustment too high");
const auto dayAdjustment = static_cast<time_t>(dayAdjustment_);
// bounds checking for adjustment_
enforce<std::overflow_error>(adjustment_ >= std::numeric_limits<time_t>::min(), "seconds adjustment too low");
enforce<std::overflow_error>(adjustment_ <= std::numeric_limits<time_t>::max(), "seconds adjustment too high");
const auto adjustment = static_cast<time_t>(adjustment_);
const auto monOverflow = Safe::add(tm.tm_mon, monthAdjustment) / 12;
tm.tm_mon = Safe::add(tm.tm_mon, monthAdjustment) % 12;
tm.tm_year = Safe::add(tm.tm_year, Safe::add(yearAdjustment, monOverflow));
// Let's not create files with non-4-digit years, we can't read them.
if (tm.tm_year > 9999 - 1900 || tm.tm_year < 1000 - 1900) {
if (Params::instance().verbose_)
std::cout << std::endl;
std::cerr << path << ": " << _("Can't adjust timestamp by") << " " << yearAdjustment_ + monOverflow << " "
std::cerr << path << ": " << _("Can't adjust timestamp by") << " " << yearAdjustment + monOverflow << " "
<< _("years") << "\n";
return 1;
}
time_t time = mktime(&tm);
time += adjustment_ + dayAdjustment_ * 86400;
time = Safe::add(time, Safe::add(adjustment, dayAdjustment * secondsInDay));
timeStr = time2Str(time);
if (Params::instance().verbose_) {
std::cout << " " << _("to") << " " << timeStr << std::endl;
@ -1587,25 +1615,31 @@ int str2Tm(const std::string& timeStr, struct tm* tm) {
std::memset(tm, 0x0, sizeof(struct tm));
tm->tm_isdst = -1;
long tmp = 0;
int64_t tmp = 0;
if (!Util::strtol(timeStr.substr(0, 4).c_str(), tmp))
return 5;
tm->tm_year = tmp - 1900;
// tmp is a 4-digit number so this cast cannot overflow
tm->tm_year = static_cast<decltype(tm->tm_year)>(tmp - 1900);
if (!Util::strtol(timeStr.substr(5, 2).c_str(), tmp))
return 6;
tm->tm_mon = tmp - 1;
// tmp is a 2-digit number so this cast cannot overflow
tm->tm_mon = static_cast<decltype(tm->tm_mon)>(tmp - 1);
if (!Util::strtol(timeStr.substr(8, 2).c_str(), tmp))
return 7;
tm->tm_mday = tmp;
// tmp is a 2-digit number so this cast cannot overflow
tm->tm_mday = static_cast<decltype(tm->tm_mday)>(tmp);
if (!Util::strtol(timeStr.substr(11, 2).c_str(), tmp))
return 8;
tm->tm_hour = tmp;
// tmp is a 2-digit number so this cast cannot overflow
tm->tm_hour = static_cast<decltype(tm->tm_hour)>(tmp);
if (!Util::strtol(timeStr.substr(14, 2).c_str(), tmp))
return 9;
tm->tm_min = tmp;
// tmp is a 2-digit number so this cast cannot overflow
tm->tm_min = static_cast<decltype(tm->tm_min)>(tmp);
if (!Util::strtol(timeStr.substr(17, 2).c_str(), tmp))
return 10;
tm->tm_sec = tmp;
// tmp is a 2-digit number so this cast cannot overflow
tm->tm_sec = static_cast<decltype(tm->tm_sec)>(tmp);
// Conversions to set remaining fields of the tm structure
if (mktime(tm) == static_cast<time_t>(-1))
@ -1615,7 +1649,7 @@ int str2Tm(const std::string& timeStr, struct tm* tm) {
} // str2Tm
std::string time2Str(time_t time) {
struct tm* tm = localtime(&time);
auto tm = localtime(&time);
return tm2Str(tm);
} // time2Str
@ -1633,7 +1667,7 @@ std::string tm2Str(const struct tm* tm) {
std::string temporaryPath() {
static int count = 0;
std::lock_guard<std::mutex> guard(cs);
auto guard = std::scoped_lock(cs);
#if defined(_MSC_VER) || defined(__MINGW__)
HANDLE process = 0;
@ -1698,7 +1732,7 @@ int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType
std::cout << _("Writing Exif data from") << " " << source << " " << _("to") << " " << target << std::endl;
}
if (preserve) {
for (auto&& exif : sourceImage->exifData()) {
for (const auto& exif : sourceImage->exifData()) {
targetImage->exifData()[exif.key()] = exif.value();
}
} else {
@ -1710,7 +1744,7 @@ int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType
std::cout << _("Writing IPTC data from") << " " << source << " " << _("to") << " " << target << std::endl;
}
if (preserve) {
for (auto&& iptc : sourceImage->iptcData()) {
for (const auto& iptc : sourceImage->iptcData()) {
targetImage->iptcData()[iptc.key()] = iptc.value();
}
} else {
@ -1723,7 +1757,7 @@ int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType
}
// #1148 use Raw XMP packet if there are no XMP modification commands
int tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX
Params::CommonTarget tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX
if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) {
// std::cout << "short cut" << std::endl;
// http://www.cplusplus.com/doc/tutorial/files/
@ -1733,7 +1767,7 @@ int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType
os.close();
rc = 0;
} else if (preserve) {
for (auto&& xmp : sourceImage->xmpData()) {
for (const auto& xmp : sourceImage->xmpData()) {
targetImage->xmpData()[xmp.key()] = xmp.value();
}
} else {

@ -97,8 +97,10 @@ class TaskFactory {
*/
static TaskFactory& instance();
~TaskFactory() = default;
//! Prevent copy construction: not implemented.
TaskFactory(const TaskFactory&) = delete;
TaskFactory& operator=(const TaskFactory&) = delete;
//! Destructor
void cleanup();
@ -187,10 +189,10 @@ class Adjust : public Task {
private:
int adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, const std::string& path) const;
long adjustment_{0};
long yearAdjustment_{0};
long monthAdjustment_{0};
long dayAdjustment_{0};
int64_t adjustment_{0};
int64_t yearAdjustment_{0};
int64_t monthAdjustment_{0};
int64_t dayAdjustment_{0};
}; // class Adjust

@ -1,19 +1,26 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "app_utils.hpp"
#include <climits>
#include <cstdlib>
#include <limits>
namespace Util {
bool strtol(const char* nptr, long& n) {
bool strtol(const char* nptr, int64_t& n) {
if (!nptr || *nptr == '\0')
return false;
char* endptr = nullptr;
long tmp = std::strtol(nptr, &endptr, 10);
long long tmp = std::strtoll(nptr, &endptr, 10);
if (*endptr != '\0')
return false;
if (tmp == LONG_MAX || tmp == LONG_MIN)
// strtoll returns LLONG_MAX or LLONG_MIN if an overflow occurs.
if (tmp == LLONG_MAX || tmp == LLONG_MIN)
return false;
n = tmp;
if (tmp < std::numeric_limits<int64_t>::min())
return false;
if (tmp > std::numeric_limits<int64_t>::max())
return false;
n = static_cast<int64_t>(tmp);
return true;
}

@ -3,13 +3,15 @@
#ifndef APP_UTILS_HPP_
#define APP_UTILS_HPP_
#include <cstdint>
namespace Util {
/*!
@brief Convert a C string to a long value, which is returned in n.
@brief Convert a C string to an int64_t value, which is returned in n.
Returns true if the conversion is successful, else false.
n is not modified if the conversion is unsuccessful. See strtol(2).
*/
bool strtol(const char* nptr, long& n);
bool strtol(const char* nptr, int64_t& n);
} // namespace Util
#endif // #ifndef UTILS_HPP_

@ -34,15 +34,19 @@
// *****************************************************************************
// local declarations
namespace {
const Params::YodAdjust emptyYodAdjust_[] = {
{false, "-Y", 0},
{false, "-O", 0},
{false, "-D", 0},
constexpr auto emptyYodAdjust_ = std::array{
Params::YodAdjust{false, "-Y", 0},
Params::YodAdjust{false, "-O", 0},
Params::YodAdjust{false, "-D", 0},
};
//! List of all command identifiers and corresponding strings
const CmdIdAndString cmdIdAndString[] = {
{add, "add"}, {set, "set"}, {del, "del"}, {reg, "reg"}, {invalidCmdId, "invalidCmd"}, // End of list marker
constexpr auto cmdIdAndString = std::array{
CmdIdAndString{CmdId::add, "add"},
CmdIdAndString{CmdId::set, "set"},
CmdIdAndString{CmdId::del, "del"},
CmdIdAndString{CmdId::reg, "reg"},
CmdIdAndString{CmdId::invalid, "invalidCmd"}, // End of list marker
};
// Return a command Id for a command string
@ -50,7 +54,7 @@ CmdId commandId(const std::string& cmdString);
// Evaluate [-]HH[:MM[:SS]], returns true and sets time to the value
// in seconds if successful, else returns false.
bool parseTime(const std::string& ts, long& time);
bool parseTime(const std::string& ts, int64_t& time);
/*!
@brief Parse the oparg string into a bitmap of common targets.
@ -58,7 +62,7 @@ bool parseTime(const std::string& ts, long& time);
@param action Action being processed
@return A bitmap of common targets or -1 in case of a parse error
*/
int parseCommonTargets(const std::string& optArg, const std::string& action);
int64_t parseCommonTargets(const std::string& optArg, const std::string& action);
/*!
@brief Parse numbers separated by commas into container
@ -137,7 +141,7 @@ int main(int argc, char* const argv[]) {
try {
// Create the required action class
auto task = Action::TaskFactory::instance().create(Action::TaskType(params.action_));
auto task = Action::TaskFactory::instance().create(static_cast<Action::TaskType>(params.action_));
// Process all files
auto filesCount = params.files_.size();
@ -147,7 +151,7 @@ int main(int argc, char* const argv[]) {
} else {
int w = filesCount > 9 ? filesCount > 99 ? 3 : 2 : 1;
int n = 1;
for (auto&& file : params.files_) {
for (const auto& file : params.files_) {
// If extracting to stdout then ignore verbose
if (params.verbose_ && !(params.action_ & Action::extract && params.target_ & Params::ctStdInOut)) {
std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << filesCount << ": " << file
@ -279,14 +283,16 @@ void Params::help(std::ostream& os) const {
<< _(" X : Extract \"raw\" XMP\n")
<< _(" -P flgs Print flags for fine control of tag lists ('print' action):\n")
<< _(" E : Exif tags\n") << _(" I : IPTC tags\n") << _(" X : XMP tags\n")
<< _(" x : Tag number (Exif and IPTC only)\n")
<< _(" x : Tag number for Exif or IPTC tags (in hexadecimal)\n")
<< _(" g : Group name (e.g. Exif.Photo.UserComment, Photo)\n")
<< _(" k : Key (e.g. Exif.Photo.UserComment)\n")
<< _(" l : Tag label (e.g. Exif.Photo.UserComment, 'User comment')\n")
<< _(" d : Tag description\n")
<< _(" n : Tag name (e.g. Exif.Photo.UserComment, UserComment)\n") << _(" y : Type\n")
<< _(" c : Number of components (count)\n")
<< _(" s : Size in bytes (Ascii and Comment types include NULL)\n")
<< _(" v : Plain data value, untranslated (vanilla)\n")
<< _(" y : Type\n") << _(" c : Number of components (count)\n")
<< _(" s : Size in bytes of vanilla value (may include NULL)\n")
<< _(" v : Plain data value of untranslated (vanilla)\n")
<< _(" V : Plain data value, data type and the word 'set'\n")
<< _(" t : Interpreted (translated) human readable values\n")
<< _(" h : Hex dump of the data\n")
<< _(" -d tgt1 Delete target(s) for the 'delete' action. Possible targets are:\n")
@ -672,13 +678,13 @@ int Params::evalPrintFlags(const std::string& optArg) {
for (auto&& i : optArg) {
switch (i) {
case 'E':
printTags_ |= Exiv2::mdExif;
printTags_ |= MetadataId::exif;
break;
case 'I':
printTags_ |= Exiv2::mdIptc;
printTags_ |= MetadataId::iptc;
break;
case 'X':
printTags_ |= Exiv2::mdXmp;
printTags_ |= MetadataId::xmp;
break;
case 'x':
printItems_ |= prTag;
@ -716,6 +722,9 @@ int Params::evalPrintFlags(const std::string& optArg) {
case 'V':
printItems_ |= prSet | prKey | prType | prValue;
break;
case 'd':
printItems_ |= prDesc;
break;
default:
std::cerr << progname() << ": " << _("Unrecognized print item") << " `" << i << "'\n";
rc = 1;
@ -735,81 +744,68 @@ int Params::evalPrintFlags(const std::string& optArg) {
} // Params::evalPrintFlags
int Params::evalDelete(const std::string& optArg) {
int rc = 0;
switch (action_) {
case Action::none:
action_ = Action::erase;
target_ = 0;
target_ = static_cast<CommonTarget>(0);
// fallthrough
case Action::erase:
rc = parseCommonTargets(optArg, "erase");
case Action::erase: {
const auto rc = parseCommonTargets(optArg, "erase");
if (rc > 0) {
target_ |= rc;
rc = 0;
} else {
rc = 1;
target_ |= static_cast<CommonTarget>(rc);
return 0;
}
break;
return 1;
}
default:
std::cerr << progname() << ": " << _("Option -d is not compatible with a previous option\n");
rc = 1;
break;
return 1;
}
return rc;
} // Params::evalDelete
int Params::evalExtract(const std::string& optArg) {
int rc = 0;
switch (action_) {
case Action::none:
case Action::modify:
action_ = Action::extract;
target_ = 0;
target_ = static_cast<CommonTarget>(0);
// fallthrough
case Action::extract:
rc = parseCommonTargets(optArg, "extract");
case Action::extract: {
const auto rc = parseCommonTargets(optArg, "extract");
if (rc > 0) {
target_ |= rc;
rc = 0;
} else {
rc = 1;
target_ |= static_cast<CommonTarget>(rc);
return 0;
}
break;
return 1;
}
default:
std::cerr << progname() << ": " << _("Option -e is not compatible with a previous option\n");
rc = 1;
break;
return 1;
}
return rc;
} // Params::evalExtract
int Params::evalInsert(const std::string& optArg) {
int rc = 0;
switch (action_) {
case Action::none:
case Action::modify:
action_ = Action::insert;
target_ = 0;
target_ = static_cast<CommonTarget>(0);
// fallthrough
case Action::insert:
rc = parseCommonTargets(optArg, "insert");
case Action::insert: {
const auto rc = parseCommonTargets(optArg, "insert");
if (rc > 0) {
target_ |= rc;
rc = 0;
} else {
rc = 1;
target_ |= static_cast<CommonTarget>(rc);
return 0;
}
break;
return 1;
}
default:
std::cerr << progname() << ": " << _("Option -i is not compatible with a previous option\n");
rc = 1;
break;
return 1;
}
return rc;
} // Params::evalInsert
int Params::evalModify(int opt, const std::string& optArg) {
int rc = 0;
switch (action_) {
case Action::none:
action_ = Action::modify;
@ -823,14 +819,12 @@ int Params::evalModify(int opt, const std::string& optArg) {
cmdFiles_.push_back(optArg); // parse the files later
if (opt == 'M')
cmdLines_.push_back(optArg); // parse the commands later
break;
return 0;
default:
std::cerr << progname() << ": " << _("Option") << " -" << static_cast<char>(opt) << " "
<< _("is not compatible with a previous option\n");
rc = 1;
break;
return 1;
}
return rc;
} // Params::evalModify
int Params::nonoption(const std::string& argv) {
@ -1090,11 +1084,11 @@ cleanup:
// *****************************************************************************
// local implementations
namespace {
bool parseTime(const std::string& ts, long& time) {
bool parseTime(const std::string& ts, int64_t& time) {
std::string hstr, mstr, sstr;
auto cts = new char[ts.length() + 1];
strcpy(cts, ts.c_str());
char* tmp = ::strtok(cts, ":");
auto tmp = ::strtok(cts, ":");
if (tmp)
hstr = tmp;
tmp = ::strtok(nullptr, ":");
@ -1106,7 +1100,7 @@ bool parseTime(const std::string& ts, long& time) {
delete[] cts;
int sign = 1;
long hh(0), mm(0), ss(0);
int64_t hh(0), mm(0), ss(0);
// [-]HH part
if (!Util::strtol(hstr.c_str(), hh))
return false;
@ -1145,11 +1139,11 @@ void printUnrecognizedArgument(const char argc, const std::string& action) {
<< argc << "'\n";
}
int parseCommonTargets(const std::string& optArg, const std::string& action) {
int rc = 0;
int target = 0;
int all = Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp;
int extra = Params::ctXmpSidecar | Params::ctExif | Params::ctIptc | Params::ctXmp;
int64_t parseCommonTargets(const std::string& optArg, const std::string& action) {
int64_t rc = 0;
auto target = static_cast<Params::CommonTarget>(0);
Params::CommonTarget all = Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp;
Params::CommonTarget extra = Params::ctXmpSidecar | Params::ctExif | Params::ctIptc | Params::ctXmp;
for (size_t i = 0; rc == 0 && i < optArg.size(); ++i) {
switch (optArg[i]) {
case 'e':
@ -1183,7 +1177,7 @@ int parseCommonTargets(const std::string& optArg, const std::string& action) {
target |= extra; // -eX
if (i > 0) { // -eXX or -iXX
target |= Params::ctXmpRaw;
target &= ~extra; // turn off those bits
target = static_cast<Params::CommonTarget>(target & ~extra); // turn off those bits
}
break;
@ -1204,7 +1198,7 @@ int parseCommonTargets(const std::string& optArg, const std::string& action) {
break;
}
}
return rc ? rc : target;
return rc ? rc : static_cast<int64_t>(target);
}
int parsePreviewNumbers(Params::PreviewNumbers& previewNumbers, const std::string& optArg, int j) {
@ -1334,38 +1328,38 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
std::string cmd(line.substr(cmdStart, cmdEnd - cmdStart));
CmdId cmdId = commandId(cmd);
if (cmdId == invalidCmdId) {
if (cmdId == CmdId::invalid) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Invalid command") + " `" + cmd + "'");
}
Exiv2::TypeId defaultType = Exiv2::invalidTypeId;
std::string key(line.substr(keyStart, keyEnd - keyStart));
MetadataId metadataId = invalidMetadataId;
if (cmdId != reg) {
MetadataId metadataId = MetadataId::invalid;
if (cmdId != CmdId::reg) {
try {
Exiv2::IptcKey iptcKey(key);
metadataId = iptc;
metadataId = MetadataId::iptc;
defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
} catch (const Exiv2::Error&) {
}
if (metadataId == invalidMetadataId) {
if (metadataId == MetadataId::invalid) {
try {
Exiv2::ExifKey exifKey(key);
metadataId = exif;
metadataId = MetadataId::exif;
defaultType = exifKey.defaultTypeId();
} catch (const Exiv2::Error&) {
}
}
if (metadataId == invalidMetadataId) {
if (metadataId == MetadataId::invalid) {
try {
Exiv2::XmpKey xmpKey(key);
metadataId = xmp;
metadataId = MetadataId::xmp;
defaultType = Exiv2::XmpProperties::propertyType(xmpKey);
} catch (const Exiv2::Error&) {
}
}
if (metadataId == invalidMetadataId) {
if (metadataId == MetadataId::invalid) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Invalid key") + " `" + key + "'");
}
@ -1373,7 +1367,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
std::string value;
Exiv2::TypeId type = defaultType;
bool explicitType = false;
if (cmdId != del) {
if (cmdId != CmdId::del) {
// Get type and value
std::string::size_type typeStart = std::string::npos;
if (keyEnd != std::string::npos)
@ -1386,12 +1380,12 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
if (valStart != std::string::npos)
valEnd = line.find_last_not_of(delim);
if (cmdId == reg && (keyEnd == std::string::npos || valStart == std::string::npos)) {
if (cmdId == CmdId::reg && (keyEnd == std::string::npos || valStart == std::string::npos)) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Invalid command line") + " ");
}
if (cmdId != reg && typeStart != std::string::npos && typeEnd != std::string::npos) {
if (cmdId != CmdId::reg && typeStart != std::string::npos && typeEnd != std::string::npos) {
std::string typeStr(line.substr(typeStart, typeEnd - typeStart));
Exiv2::TypeId tmpType = Exiv2::TypeInfo::typeId(typeStr);
if (tmpType != Exiv2::invalidTypeId) {
@ -1421,7 +1415,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
modifyCmd.explicitType_ = explicitType;
modifyCmd.value_ = value;
if (cmdId == reg) {
if (cmdId == CmdId::reg) {
if (value.empty()) {
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
Exiv2::toString(num) + ": " + _("Empty value for key") + +" `" + key + "'");
@ -1436,11 +1430,8 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
} // parseLine
CmdId commandId(const std::string& cmdString) {
int i = 0;
while (cmdIdAndString[i].first != invalidCmdId && cmdIdAndString[i].second != cmdString) {
++i;
}
return cmdIdAndString[i].first;
auto it = std::find_if(cmdIdAndString.begin(), cmdIdAndString.end(), [&](auto cs) { return cs.second == cmdString; });
return it != cmdIdAndString.end() ? it->first : CmdId::invalid;
}
std::string parseEscapes(const std::string& input) {
@ -1452,7 +1443,7 @@ std::string parseEscapes(const std::string& input) {
continue;
}
size_t escapeStart = i;
if (!(input.length() - 1 > i)) {
if (input.length() - 1 <= i) {
result.push_back(ch);
continue;
}
@ -1473,7 +1464,7 @@ std::string parseEscapes(const std::string& input) {
break;
case 'u': // Escaping of unicode
if (input.length() >= 4 && input.length() - 4 > i) {
int acc = 0;
uint32_t acc = 0;
for (int j = 0; j < 4; ++j) {
++i;
acc <<= 4;
@ -1484,19 +1475,19 @@ std::string parseEscapes(const std::string& input) {
} else if (input[i] >= 'A' && input[i] <= 'F') {
acc |= input[i] - 'A' + 10;
} else {
acc = -1;
acc = 0xFFFFFFFF;
break;
}
}
if (acc == -1) {
if (acc == 0xFFFFFFFF) {
result.push_back('\\');
i = escapeStart;
break;
}
std::string ucs2toUtf8;
ucs2toUtf8.push_back(static_cast<char>((acc & 0xff00) >> 8));
ucs2toUtf8.push_back(static_cast<char>(acc & 0x00ff));
ucs2toUtf8.push_back(static_cast<char>((acc & 0xff00U) >> 8));
ucs2toUtf8.push_back(static_cast<char>(acc & 0x00ffU));
if (Exiv2::convertStringCharset(ucs2toUtf8, "UCS-2BE", "UTF-8")) {
result.append(ucs2toUtf8);

@ -21,28 +21,40 @@
#include <set>
//! Command identifiers
enum CmdId {
invalidCmdId,
enum class CmdId {
invalid,
add,
set,
del,
reg,
};
//! Metadata identifiers
enum MetadataId {
invalidMetadataId = Exiv2::mdNone, // 0
exif = Exiv2::mdExif, // 1
iptc = Exiv2::mdIptc, // 2
xmp = Exiv2::mdXmp, // 8
enum class MetadataId : uint32_t {
invalid = Exiv2::mdNone, // 0
exif = Exiv2::mdExif, // 1
iptc = Exiv2::mdIptc, // 2
xmp = Exiv2::mdXmp, // 8
};
inline MetadataId operator&(MetadataId x, MetadataId y) {
return static_cast<MetadataId>(static_cast<uint32_t>(x) & static_cast<uint32_t>(y));
}
inline MetadataId operator|(MetadataId x, MetadataId y) {
return static_cast<MetadataId>(static_cast<uint32_t>(x) | static_cast<uint32_t>(y));
}
inline MetadataId& operator|=(MetadataId& x, MetadataId y) {
return x = x | y;
}
//! Structure for one parsed modification command
struct ModifyCmd {
//! C'tor
ModifyCmd() = default;
CmdId cmdId_{invalidCmdId}; //!< Command identifier
CmdId cmdId_{CmdId::invalid}; //!< Command identifier
std::string key_; //!< Exiv2 key string
MetadataId metadataId_{invalidMetadataId}; //!< Metadata identifier
MetadataId metadataId_{MetadataId::invalid}; //!< Metadata identifier
Exiv2::TypeId typeId_{Exiv2::invalidTypeId}; //!< Exiv2 type identifier
//! Flag to indicate if the type was explicitly specified (true)
bool explicitType_{false};
@ -51,7 +63,7 @@ struct ModifyCmd {
//! Container for modification commands
using ModifyCmds = std::vector<ModifyCmd>;
//! Structure to link command identifiers to strings
using CmdIdAndString = std::pair<CmdId, std::string>;
using CmdIdAndString = std::pair<CmdId, std::string_view>;
/*!
@brief Implements the command line handling for the program.
@ -110,7 +122,9 @@ class Params : public Util::Getopt {
static Params& instance();
//! Prevent copy-construction: not implemented.
~Params() override = default;
Params(const Params&) = delete;
Params& operator=(const Params&) = delete;
//! Enumerates print modes
enum PrintMode {
@ -125,7 +139,7 @@ class Params : public Util::Getopt {
};
//! Individual items to print, bitmap
enum PrintItem {
enum PrintItem : uint32_t {
prTag = 1,
prGroup = 2,
prKey = 4,
@ -137,11 +151,12 @@ class Params : public Util::Getopt {
prValue = 256,
prTrans = 512,
prHex = 1024,
prSet = 2048
prSet = 2048,
prDesc = 4096
};
//! Enumerates common targets, bitmap
enum CommonTarget {
enum CommonTarget : uint32_t {
ctExif = 1,
ctIptc = 2,
ctComment = 4,
@ -173,7 +188,7 @@ class Params : public Util::Getopt {
struct YodAdjust {
bool flag_; //!< Adjustment flag.
const char* option_; //!< Adjustment option string.
long adjustment_; //!< Adjustment value.
int64_t adjustment_; //!< Adjustment value.
};
bool help_{false}; //!< Help option flag.
@ -188,27 +203,27 @@ class Params : public Util::Getopt {
FileExistsPolicy fileExistsPolicy_{askPolicy}; //!< What to do if file to rename exists.
bool adjust_{false}; //!< Adjustment flag.
PrintMode printMode_{pmSummary}; //!< Print mode.
unsigned long printItems_{0}; //!< Print items.
unsigned long printTags_{Exiv2::mdNone}; //!< Print tags (bitmap of MetadataId flags).
PrintItem printItems_{0}; //!< Print items.
MetadataId printTags_{Exiv2::mdNone}; //!< Print tags (bitmap of MetadataId flags).
//! %Action (integer rather than TaskType to avoid dependency).
int action_{0};
int target_; //!< What common target to process.
long adjustment_{0}; //!< Adjustment in seconds.
YodAdjust yodAdjust_[3]; //!< Year, month and day adjustment info.
std::string format_; //!< Filename format (-r option arg).
bool formatSet_{false}; //!< Whether the format is set with -r
CmdFiles cmdFiles_; //!< Names of the modification command files
CmdLines cmdLines_; //!< Commands from the command line
ModifyCmds modifyCmds_; //!< Parsed modification commands
std::string jpegComment_; //!< Jpeg comment to set in the image
std::string directory_; //!< Location for files to extract/insert
std::string suffix_; //!< File extension of the file to insert
Files files_; //!< List of non-option arguments.
PreviewNumbers previewNumbers_; //!< List of preview numbers
std::vector<std::regex> greps_; //!< List of keys to 'grep' from the metadata
Keys keys_; //!< List of keys to match from the metadata
std::string charset_; //!< Charset to use for UNICODE Exif user comment
CommonTarget target_; //!< What common target to process.
int64_t adjustment_{0}; //!< Adjustment in seconds.
std::array<YodAdjust, 3> yodAdjust_; //!< Year, month and day adjustment info.
std::string format_; //!< Filename format (-r option arg).
bool formatSet_{false}; //!< Whether the format is set with -r
CmdFiles cmdFiles_; //!< Names of the modification command files
CmdLines cmdLines_; //!< Commands from the command line
ModifyCmds modifyCmds_; //!< Parsed modification commands
std::string jpegComment_; //!< Jpeg comment to set in the image
std::string directory_; //!< Location for files to extract/insert
std::string suffix_; //!< File extension of the file to insert
Files files_; //!< List of non-option arguments.
PreviewNumbers previewNumbers_; //!< List of preview numbers
std::vector<std::regex> greps_; //!< List of keys to 'grep' from the metadata
Keys keys_; //!< List of keys to match from the metadata
std::string charset_; //!< Charset to use for UNICODE Exif user comment
Exiv2::DataBuf stdinBuf; //!< DataBuf with the binary bytes from stdin
@ -270,4 +285,20 @@ class Params : public Util::Getopt {
}; // class Params
inline Params::CommonTarget operator|(Params::CommonTarget x, Params::CommonTarget y) {
return static_cast<Params::CommonTarget>(static_cast<uint32_t>(x) | static_cast<uint32_t>(y));
}
inline Params::CommonTarget& operator|=(Params::CommonTarget& x, Params::CommonTarget y) {
return x = x | y;
}
inline Params::PrintItem operator|(Params::PrintItem x, Params::PrintItem y) {
return static_cast<Params::PrintItem>(static_cast<uint32_t>(x) | static_cast<uint32_t>(y));
}
inline Params::PrintItem& operator|=(Params::PrintItem& x, Params::PrintItem y) {
return x = x | y;
}
#endif // #ifndef EXIV2APP_HPP_

@ -62,10 +62,10 @@
/* Define to the version of this package. */
#cmakedefine EXV_PACKAGE_VERSION "@PROJECT_VERSION@"
#define EXIV2_MAJOR_VERSION (@PROJECT_VERSION_MAJOR@)
#define EXIV2_MINOR_VERSION (@PROJECT_VERSION_MINOR@)
#define EXIV2_PATCH_VERSION (@PROJECT_VERSION_PATCH@)
#define EXIV2_TWEAK_VERSION (@PROJECT_VERSION_TWEAK@)
#define EXIV2_MAJOR_VERSION (@PROJECT_VERSION_MAJOR@U)
#define EXIV2_MINOR_VERSION (@PROJECT_VERSION_MINOR@U)
#define EXIV2_PATCH_VERSION (@PROJECT_VERSION_PATCH@U)
#define EXIV2_TWEAK_VERSION (@PROJECT_VERSION_TWEAK@U)
// Definition to enable translation of Nikon lens names.
#cmakedefine EXV_HAVE_LENSDATA

@ -1,5 +1,24 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
if (CONAN_AUTO_INSTALL)
# Download automatically the cmake-conan integration file
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/master/conan.cmake"
"${CMAKE_BINARY_DIR}/conan.cmake"
TLS_VERIFY ON)
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_cmake_autodetect(settings)
conan_cmake_install(PATH_OR_REFERENCE ..
BUILD missing
REMOTE conancenter
OPTIONS webready=True
SETTINGS ${settings})
endif()
if (APPLE)
# On Apple, we use the conan cmake_paths generator
if (EXISTS ${CMAKE_BINARY_DIR}/conan_paths.cmake)

@ -21,10 +21,10 @@ class Exiv2Conan(ConanFile):
self.options['gtest'].shared = False
def requirements(self):
self.requires('zlib/1.2.11')
self.requires('zlib/1.2.12')
if self.options.webready:
self.requires('libcurl/7.79.0')
self.requires('libcurl/7.80.0')
if os_info.is_windows and self.options.iconv:
self.requires('libiconv/1.16')
@ -37,7 +37,7 @@ class Exiv2Conan(ConanFile):
if self.options.xmp:
self.requires('XmpSdk/2016.7@piponazo/stable') # from conan-piponazo
else:
self.requires('expat/2.4.1')
self.requires('expat/2.4.8')
def imports(self):
self.copy('*.dll', dst='bin', src='bin')

@ -566,34 +566,33 @@ as well as data columns included in the print output. Valid flags are:
| g | Group name (e.g., for Exif.Photo.UserComment, outputs Photo) |
| k | Key (e.g., Exif.Photo.UserComment) |
| l | Tag label (human-readable tagname, e.g., for Exif.Photo.UserComment, outputs 'User comment') |
| n | Tagname (e.g., for Exif.Photo.UserComment, outputs UserComment) |
| d | Tag description |
| n | Tag name (e.g., for Exif.Photo.UserComment, outputs UserComment) |
| y | Type (for available types, see [Exif/IPTC/XMP types](#exiv2_types)) |
| c | Number of components (for single entry types, the number of **sizeof('type')** in 'size'. For multi-entry types, the number of entries. See [Exif/IPTC/XMP types](#exiv2_types)) |
| s | Size in bytes of vanilla output (see note in [Exif 'Comment' values](#exif_comment_values)). Some types include a *NULL* character in the size (see [Exif/IPTC/XMP types](#exiv2_types)) |
| v | Plain data value (vanilla values, i.e., untranslated) |
| V | Plain data value, data type and the word 'set ' (see ['MODIFY' COMMANDS](#modify_cmds))|
| V | Plain data value, data type and the word 'set' (see ['MODIFY' COMMANDS](#modify_cmds))|
| t | Interpreted (translated) human-readable data values (includes plain vanilla values) |
| h | Hex dump of the data |
**--Print** *flgs* can be combined with [--grep str](#grep_str) or
[--key key](#key_key) to further filter the output.
<div id="Print_flgs_order">
The order of the values in *flgs* is not respected. For example, the order
of the columns, using some tags from *Stonehenge.jpg*, is as follows:
The order of the values in *flgs* is not respected and is output as follows:
```
$ curl --silent -O https://www.exiv2.org/Stonehenge.jpg
$ exiv2 --Print xgknlycst Stonehenge.jpg
```
| Tag number<br>(x) | Plain 'set'<br>(V) | Group<br>(g) | Key<br>(k) | Tagname<br>(n) | Tagname label<br>(l) |Description<br>(d) | Type<br>(y) | Comp<br>(c) | Size<br>(s) | Value<br>(v) | Translated<br>(t) |
|:------ |:---- |:------ |:------ |:------ |:------ |:------ |:------ |:------ |:------ |:--- |:------ |
| Tag number<br>(x) | Plain 'set'<br>(V) | Group<br>(g) | Key<br>(k) | Tagname<br>(n) | Tagname label<br>(l) | Type<br>(y) | Comp<br>(c) | Size<br>(s) | Value<br>(E, I, X, v, t) | Translated<br>(t) |
|:------ |:---- |:------ |:------ |:------ |:------ |:------ |:------ |:------ |:------ |:------ |
| 0x0110 | set | Image | Exif.Image.Model | Model | Model | Ascii | 12 | 12 | NIKON D5300 | NIKON D5300 |
| 0x0006 | set | NikonIi | Exif.NikonIi.ISO2 | ISO2 | ISO 2 | Byte | 1 | 1 | 72 | 200 |
| 0x0000 | set | xmp | Xmp.xmp.Rating | Rating | Rating | XmpText | 1 | 1 | 0 | 0 |
| 0x0000 | set | dc | Xmp.dc.Family | Family | Family | XmpBag | 1 | 5 | Robin | Robin |
For example,
**--Print** *flgs* can be combined with [--grep str](#grep_str) or
[--key key](#key_key) to further filter the output.
```bash
$ curl --silent -O https://www.exiv2.org/Stonehenge.jpg
$ exiv2 --Print xVgknldycsvt -K Exif.Nikon3.Quality Stonehenge.jpg
0x0004 set Nikon3 Exif.Nikon3.Quality Quality Quality Image quality setting Ascii 8 8 NORMAL NORMAL
```
<div id="delete_tgt1">

@ -198,10 +198,9 @@ class EXIV2API BasicIo {
//@{
/*!
@brief Get the current IO position.
@return Offset from the start of IO if successful;<BR>
-1 if failure;
@return Offset from the start of IO
*/
[[nodiscard]] virtual long tell() const = 0;
[[nodiscard]] virtual size_t tell() const = 0;
/*!
@brief Get the current size of the IO source in bytes.
@return Size of the IO source in bytes;<BR>
@ -439,10 +438,9 @@ class EXIV2API FileIo : public BasicIo {
//@{
/*!
@brief Get the current file position.
@return Offset from the start of the file if successful;<BR>
-1 if failure;
@return Offset from the start of the file
*/
[[nodiscard]] long tell() const override;
[[nodiscard]] size_t tell() const override;
/*!
@brief Flush any buffered writes and get the current file size
in bytes.
@ -624,7 +622,7 @@ class EXIV2API MemIo : public BasicIo {
@brief Get the current IO position.
@return Offset from the start of the memory block
*/
[[nodiscard]] long tell() const override;
[[nodiscard]] size_t tell() const override;
/*!
@brief Get the current memory buffer size in bytes.
@return Size of the in memory data in bytes;<BR>
@ -695,12 +693,12 @@ class EXIV2API XPathIo : public FileIo {
@brief The extension of the temporary file which is created when getting input data
to read metadata. This file will be deleted in destructor.
*/
static constexpr std::string_view TEMP_FILE_EXT = ".exiv2_temp";
static constexpr auto TEMP_FILE_EXT = ".exiv2_temp";
/*!
@brief The extension of the generated file which is created when getting input data
to add or modify the metadata.
*/
static constexpr std::string_view GEN_FILE_EXT = ".exiv2";
static constexpr auto GEN_FILE_EXT = ".exiv2";
//! @name Creators
//@{
@ -737,7 +735,7 @@ class EXIV2API XPathIo : public FileIo {
private:
// True if the file is a temporary file and it should be deleted in destructor.
bool isTemp_;
bool isTemp_{true};
std::string tempFilePath_;
}; // class XPathIo
#endif
@ -874,7 +872,7 @@ class EXIV2API RemoteIo : public BasicIo {
@brief Get the current IO position.
@return Offset from the start of the memory block
*/
[[nodiscard]] long tell() const override;
[[nodiscard]] size_t tell() const override;
/*!
@brief Get the current memory buffer size in bytes.
@return Size of the in memory data in bytes;<BR>

@ -14,7 +14,7 @@
// namespace extensions
namespace Exiv2 {
EXIV2API bool enableBMFF(bool enable = true);
}
} // namespace Exiv2
#ifdef EXV_ENABLE_BMFF
namespace Exiv2 {
@ -97,15 +97,15 @@ class EXIV2API BmffImage : public Image {
//! @name Manipulators
//@{
void readMetadata() override /* override */;
void writeMetadata() override /* override */;
void setComment(std::string_view comment) override /* override */;
void readMetadata() override;
void writeMetadata() override;
void setComment(const std::string& comment) override;
void printStructure(std::ostream& out, Exiv2::PrintStructureOption option, int depth) override;
//@}
//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override /* override */;
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] uint32_t pixelWidth() const override;
[[nodiscard]] uint32_t pixelHeight() const override;
//@}
@ -122,13 +122,13 @@ class EXIV2API BmffImage : public Image {
@return address of next box
@warning This function should only be called by readMetadata()
*/
long boxHandler(std::ostream& out, Exiv2::PrintStructureOption option, long pbox_end, int depth);
uint64_t boxHandler(std::ostream& out, Exiv2::PrintStructureOption option, uint64_t pbox_end, int depth);
[[nodiscard]] static std::string indent(int i) {
return std::string(2 * i, ' ');
}
uint32_t fileType_{0};
std::set<uint64_t> visits_;
std::set<size_t> visits_;
uint64_t visits_max_{0};
uint16_t unknownID_{0xffff};
uint16_t exifID_{0xffff};
@ -140,7 +140,7 @@ class EXIV2API BmffImage : public Image {
/*!
@brief box utilities
*/
static std::string toAscii(long n);
static std::string toAscii(uint32_t n);
std::string boxName(uint32_t box);
static bool superBox(uint32_t box);
static bool fullBox(uint32_t box);

@ -66,7 +66,7 @@ class EXIV2API BmpImage : public Image {
void setIptcData(const IptcData& iptcData) override;
/// @throws Error(ErrorCode::kerInvalidSettingForImage)
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -61,7 +61,7 @@ class EXIV2API Cr2Image : public Image {
@brief Not supported. CR2 format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -280,6 +280,7 @@ class EXIV2API IptcKey : public Key {
[[nodiscard]] std::string groupName() const override;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] UniquePtr clone() const;
//! Return the name of the record

@ -65,7 +65,7 @@ class EXIV2API EpsImage : public Image {
@brief Not supported.
Calling this function will throw an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -140,9 +140,10 @@ class EXIV2API Exifdatum : public Metadatum {
[[nodiscard]] std::string groupName() const override;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
[[nodiscard]] uint16_t tag() const override;
//! Return the IFD id as an integer. (Do not use, this is meant for library internal use.)
[[nodiscard]] int ifdId() const;
[[nodiscard]] IfdId ifdId() const;
//! Return the name of the IFD
[[nodiscard]] const char* ifdName() const;
//! Return the index (unique id of this key within the original IFD)

@ -31,7 +31,7 @@ EXIV2API std::string getEnv(int env_var);
@note Source: http://www.geekhideout.com/urlcode.shtml
@todo This function can probably be hidden into the implementation details
*/
EXIV2API std::string urlencode(std::string_view str);
EXIV2API std::string urlencode(const std::string& str);
/*!
@brief Like urlencode(char* str) but accept the input url in the std::string and modify it.

@ -69,7 +69,7 @@ class EXIV2API GifImage : public Image {
@brief Not supported. Calling this function will throw an instance
of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -177,7 +177,7 @@ class EXIV2API Image {
virtual void clearXmpData();
/// @brief Set the image comment. The comment is written to the image when writeMetadata() is called.
virtual void setComment(std::string_view comment);
virtual void setComment(const std::string& comment);
/*!
@brief Erase any buffered comment. Comment is not removed
@ -467,8 +467,8 @@ class EXIV2API Image {
DataBuf iccProfile_; //!< ICC buffer (binary data)
std::string comment_; //!< User comment
std::string xmpPacket_; //!< XMP packet
uint32_t pixelWidth_; //!< image pixel width
uint32_t pixelHeight_; //!< image pixel height
uint32_t pixelWidth_{0}; //!< image pixel width
uint32_t pixelHeight_{0}; //!< image pixel height
NativePreviewList nativePreviews_; //!< list of native previews
//! Return tag name for given tag id.
@ -479,13 +479,13 @@ class EXIV2API Image {
private:
// DATA
ImageType imageType_; //!< Image type
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
bool writeXmpFromPacket_; //!< Determines the source when writing XMP
ByteOrder byteOrder_; //!< Byte order
ImageType imageType_; //!< Image type
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
bool writeXmpFromPacket_; //!< Determines the source when writing XMP
ByteOrder byteOrder_{invalidByteOrder}; //!< Byte order
std::map<int, std::string> tags_; //!< Map of tags
bool init_; //!< Flag marking if map of tags needs to be initialized
bool init_{true}; //!< Flag marking if map of tags needs to be initialized
}; // class Image

@ -113,6 +113,7 @@ class EXIV2API Iptcdatum : public Metadatum {
*/
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Return the tag (aka dataset) number
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] TypeId typeId() const override;

@ -56,7 +56,7 @@ class EXIV2API Jp2Image : public Image {
@brief Todo: Not supported yet(?). Calling this function will throw
an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -52,6 +52,8 @@ class EXIV2API Key {
[[nodiscard]] virtual std::string tagName() const = 0;
//! Return a label for the tag
[[nodiscard]] virtual std::string tagLabel() const = 0;
//! Return a description for the tag
[[nodiscard]] virtual std::string tagDesc() const = 0;
//! Return the tag number
[[nodiscard]] virtual uint16_t tag() const = 0;
/*!
@ -181,6 +183,8 @@ class EXIV2API Metadatum {
[[nodiscard]] virtual std::string tagName() const = 0;
//! Return a label for the tag
[[nodiscard]] virtual std::string tagLabel() const = 0;
//! Return a description for the tag
[[nodiscard]] virtual std::string tagDesc() const = 0;
//! Return the tag
[[nodiscard]] virtual uint16_t tag() const = 0;
//! Return the type id of the value

@ -72,7 +72,7 @@ class EXIV2API MrwImage : public Image {
@brief Not supported. MRW format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -59,7 +59,7 @@ class EXIV2API OrfImage : public TiffImage {
@brief Not supported. ORF format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -16,10 +16,10 @@ class IptcData;
/// @brief Helper class, has methods to deal with %Photoshop "Information Resource Blocks" (IRBs).
struct EXIV2API Photoshop {
// Todo: Public for now
static constexpr std::array irbId_{"8BIM", "AgHg", "DCSR", "PHUT"}; //!< %Photoshop IRB markers
static constexpr auto ps3Id_ = "Photoshop 3.0\0"; //!< %Photoshop marker
static constexpr uint16_t iptc_ = 0x0404; //!< %Photoshop IPTC marker
static constexpr uint16_t preview_ = 0x040c; //!< %Photoshop preview marker
static constexpr std::array<const char*, 4> irbId_{"8BIM", "AgHg", "DCSR", "PHUT"}; //!< %Photoshop IRB markers
static constexpr auto ps3Id_ = "Photoshop 3.0\0"; //!< %Photoshop marker
static constexpr uint16_t iptc_ = 0x0404; //!< %Photoshop IPTC marker
static constexpr uint16_t preview_ = 0x040c; //!< %Photoshop preview marker
/// @brief Checks an IRB
/// @param pPsData Existing IRB buffer. It is expected to be of size 4.

@ -8,6 +8,7 @@
// included header files
#include <mutex>
#include "datasets.hpp"
// *****************************************************************************
@ -262,6 +263,7 @@ class EXIV2API XmpKey : public Key {
[[nodiscard]] std::string groupName() const override;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Properties don't have a tag number. Return 0.
[[nodiscard]] uint16_t tag() const override;

@ -53,7 +53,7 @@ class EXIV2API PsdImage : public Image {
/*!
@brief Not supported. Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -64,7 +64,7 @@ class EXIV2API RafImage : public Image {
@brief Not supported. RAF format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -62,7 +62,7 @@ class EXIV2API Rw2Image : public Image {
@brief Not supported. RW2 format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -263,7 +263,7 @@ struct ContainerStorage {
using const_iterator = typename container::const_iterator;
using value_type = std::remove_cv_t<typename container::value_type>;
using value_type = typename std::remove_cv<typename container::value_type>::type;
/*!
* @throw std::out_of_range when end is larger than the container's
@ -324,7 +324,7 @@ struct ContainerStorage {
*/
template <typename storage_type>
struct PtrSliceStorage {
using value_type = std::remove_cv_t<std::remove_pointer_t<storage_type>>;
using value_type = typename std::remove_cv<typename std::remove_pointer<storage_type>::type>::type;
using iterator = value_type*;
using const_iterator = const value_type*;
@ -423,7 +423,7 @@ struct Slice : public Internal::MutableSliceBase<Internal::ContainerStorage, con
using const_iterator = typename container::const_iterator;
using value_type = std::remove_cv_t<typename container::value_type>;
using value_type = typename std::remove_cv<typename container::value_type>::type;
/*!
* @brief Construct a slice of the container `cont` starting at `begin`
@ -476,7 +476,7 @@ struct Slice<const container> : public Internal::ConstSliceBase<Internal::Contai
using const_iterator = typename container::const_iterator;
using value_type = std::remove_cv_t<typename container::value_type>;
using value_type = typename std::remove_cv<typename container::value_type>::type;
Slice(const container& cont, size_t begin, size_t end) :
Internal::ConstSliceBase<Internal::ContainerStorage, const container>(cont, begin, end) {

@ -30,12 +30,161 @@ using TagListFct = const TagInfo* (*)();
// *****************************************************************************
// class definitions
//! Type to specify the IFD to which a metadata belongs
enum class IfdId : uint32_t {
ifdIdNotSet,
ifd0Id,
ifd1Id,
ifd2Id,
ifd3Id,
exifId,
gpsId,
iopId,
mpfId,
subImage1Id,
subImage2Id,
subImage3Id,
subImage4Id,
subImage5Id,
subImage6Id,
subImage7Id,
subImage8Id,
subImage9Id,
subThumb1Id,
panaRawId,
mnId,
canonId,
canonAfCId,
canonAfMiAdjId,
canonAmId,
canonAsId,
canonCbId,
canonCiId,
canonCsId,
canonFilId,
canonFlId,
canonHdrId,
canonLeId,
canonMeId,
canonMoID,
canonMvId,
canonRawBId,
canonSiId,
canonCfId,
canonContrastId,
canonFcd1Id,
canonFcd2Id,
canonFcd3Id,
canonLiOpId,
canonMyColorID,
canonPiId,
canonPaId,
canonTiId,
canonFiId,
canonPrId,
canonPreID,
canonVigCorId,
canonVigCor2Id,
canonWbId,
casioId,
casio2Id,
fujiId,
minoltaId,
minoltaCs5DId,
minoltaCs7DId,
minoltaCsOldId,
minoltaCsNewId,
nikon1Id,
nikon2Id,
nikon3Id,
nikonPvId,
nikonVrId,
nikonPcId,
nikonWtId,
nikonIiId,
nikonAfId,
nikonAf21Id,
nikonAf22Id,
nikonAFTId,
nikonFiId,
nikonMeId,
nikonFl1Id,
nikonFl2Id,
nikonFl3Id,
nikonFl7Id,
nikonSi1Id,
nikonSi2Id,
nikonSi3Id,
nikonSi4Id,
nikonSi5Id,
nikonSi6Id,
nikonLd1Id,
nikonLd2Id,
nikonLd3Id,
nikonLd4Id,
nikonCb1Id,
nikonCb2Id,
nikonCb2aId,
nikonCb2bId,
nikonCb3Id,
nikonCb4Id,
olympusId,
olympus2Id,
olympusCsId,
olympusEqId,
olympusRdId,
olympusRd2Id,
olympusIpId,
olympusFiId,
olympusFe1Id,
olympusFe2Id,
olympusFe3Id,
olympusFe4Id,
olympusFe5Id,
olympusFe6Id,
olympusFe7Id,
olympusFe8Id,
olympusFe9Id,
olympusRiId,
panasonicId,
pentaxId,
pentaxDngId,
samsung2Id,
samsungPvId,
samsungPwId,
sigmaId,
sony1Id,
sony2Id,
sonyMltId,
sony1CsId,
sony1Cs2Id,
sony2CsId,
sony2Cs2Id,
sony2FpId,
sonyMisc1Id,
sonyMisc2bId,
sonyMisc3cId,
sonySInfo1Id,
sony2010eId,
sony1MltCs7DId,
sony1MltCsOldId,
sony1MltCsNewId,
sony1MltCsA100Id,
tagInfoMvId,
lastId,
ignoreId = lastId
};
inline std::ostream& operator<<(std::ostream& os, IfdId id) {
return os << static_cast<int>(id);
}
//! The details of an Exif group. Groups include IFDs and binary arrays.
struct EXIV2API GroupInfo {
struct GroupName;
bool operator==(int ifdId) const; //!< Comparison operator for IFD id
bool operator==(IfdId ifdId) const; //!< Comparison operator for IFD id
bool operator==(const GroupName& groupName) const; //!< Comparison operator for group name
int ifdId_; //!< IFD id
IfdId ifdId_; //!< IFD id
const char* ifdName_; //!< IFD name
const char* groupName_; //!< Group name, unique for each group.
TagListFct tagList_; //!< Tag list
@ -47,18 +196,47 @@ struct EXIV2API GroupInfo::GroupName {
std::string g_; //!< Group name
};
/*!
@brief Section identifiers to logically group tags. A section consists
of nothing more than a name, based on the Exif standard.
*/
enum class SectionId {
sectionIdNotSet,
imgStruct, // 4.6.4 A
recOffset, // 4.6.4 B
imgCharacter, // 4.6.4 C
otherTags, // 4.6.4 D
exifFormat, // 4.6.3
exifVersion, // 4.6.5 A
imgConfig, // 4.6.5 C
userInfo, // 4.6.5 D
relatedFile, // 4.6.5 E
dateTime, // 4.6.5 F
captureCond, // 4.6.5 G
gpsTags, // 4.6.6
iopTags, // 4.6.7
mpfTags,
makerTags, // MakerNote
dngTags, // DNG Spec
panaRaw,
tiffEp, // TIFF-EP Spec
tiffPm6,
adobeOpi,
lastSectionId
};
//! Tag information
struct EXIV2API TagInfo {
uint16_t tag_; //!< Tag
const char* name_; //!< One word tag label
const char* title_; //!< Tag title
const char* desc_; //!< Short tag description
int ifdId_; //!< Link to the (preferred) IFD
int sectionId_; //!< Section id
TypeId typeId_; //!< Type id
int16_t count_; //!< The number of values (not bytes!), 0=any, -1=count not known.
PrintFct printFct_; //!< Pointer to tag print function
}; // struct TagInfo
uint16_t tag_; //!< Tag
const char* name_; //!< One word tag label
const char* title_; //!< Tag title
const char* desc_; //!< Short tag description
IfdId ifdId_; //!< Link to the (preferred) IFD
SectionId sectionId_; //!< Section id
TypeId typeId_; //!< Type id
int16_t count_; //!< The number of values (not bytes!), 0=any, -1=count not known.
PrintFct printFct_; //!< Pointer to tag print function
}; // struct TagInfo
//! Access to Exif group and tag lists and misc. tag reference methods, implemented as a static class.
class EXIV2API ExifTags {
@ -156,13 +334,12 @@ class EXIV2API ExifKey : public Key {
[[nodiscard]] std::string key() const override;
[[nodiscard]] const char* familyName() const override;
[[nodiscard]] std::string groupName() const override;
//! Return the IFD id as an integer. (Do not use, this is meant for library internal use.)
[[nodiscard]] int ifdId() const;
//! Return the IFD id. (Do not use, this is meant for library internal use.)
[[nodiscard]] IfdId ifdId() const;
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] std::string tagLabel() const override;
//! Return the tag description.
[[nodiscard]] std::string tagDesc() const; // Todo: should be in the base class
[[nodiscard]] std::string tagDesc() const override;
//! Return the default type id for this tag.
[[nodiscard]] TypeId defaultTypeId() const; // Todo: should be in the base class

@ -68,7 +68,7 @@ class EXIV2API TgaImage : public Image {
@brief Not supported. Calling this function will throw an instance
of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -58,7 +58,7 @@ class EXIV2API TiffImage : public Image {
@brief Not supported. TIFF format does not contain a comment.
Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors
@ -85,10 +85,10 @@ class EXIV2API TiffImage : public Image {
//@}
// DATA
mutable std::string primaryGroup_; //!< The primary group
mutable std::string mimeType_; //!< The MIME type
mutable uint32_t pixelWidthPrimary_; //!< Width of the primary image in pixels
mutable uint32_t pixelHeightPrimary_; //!< Height of the primary image in pixels
mutable std::string primaryGroup_; //!< The primary group
mutable std::string mimeType_; //!< The MIME type
mutable uint32_t pixelWidthPrimary_{0}; //!< Width of the primary image in pixels
mutable uint32_t pixelHeightPrimary_{0}; //!< Height of the primary image in pixels
}; // class TiffImage

@ -14,6 +14,7 @@
#include <cstring>
#include <iomanip>
#include <map>
#include <memory>
// *****************************************************************************
// namespace extensions
@ -228,7 +229,7 @@ class EXIV2API Value {
*/
Value& operator=(const Value&) = default;
// DATA
mutable bool ok_; //!< Indicates the status of the previous to<Type> conversion
mutable bool ok_{true}; //!< Indicates the status of the previous to<Type> conversion
private:
//! Internal virtual copy constructor.
@ -647,8 +648,8 @@ class EXIV2API XmpValue : public Value {
private:
// DATA
XmpArrayType xmpArrayType_; //!< Type of XMP array
XmpStruct xmpStruct_; //!< XMP structure indicator
XmpArrayType xmpArrayType_{xaNone}; //!< Type of XMP array
XmpStruct xmpStruct_{xsNone}; //!< XMP structure indicator
}; // class XmpValue
@ -931,16 +932,16 @@ class EXIV2API DateValue : public Value {
//! Default constructor.
DateValue();
//! Constructor
DateValue(int year, int month, int day);
DateValue(int32_t year, int32_t month, int32_t day);
//! Virtual destructor.
~DateValue() override = default;
//@}
//! Simple Date helper structure
struct EXIV2API Date {
int year{0}; //!< Year
int month{0}; //!< Month
int day{0}; //!< Day
int32_t year{0}; //!< Year
int32_t month{0}; //!< Month
int32_t day{0}; //!< Day
};
//! @name Manipulators
@ -1024,7 +1025,7 @@ class EXIV2API TimeValue : public Value {
//! Default constructor.
TimeValue();
//! Constructor
TimeValue(int hour, int minute, int second = 0, int tzHour = 0, int tzMinute = 0);
TimeValue(int32_t hour, int32_t minute, int32_t second = 0, int32_t tzHour = 0, int32_t tzMinute = 0);
//! Virtual destructor.
~TimeValue() override = default;
@ -1034,11 +1035,11 @@ class EXIV2API TimeValue : public Value {
struct Time {
Time() = default;
int hour{0}; //!< Hour
int minute{0}; //!< Minute
int second{0}; //!< Second
int tzHour{0}; //!< Hours ahead or behind UTC
int tzMinute{0}; //!< Minutes ahead or behind UTC
int32_t hour{0}; //!< Hour
int32_t minute{0}; //!< Minute
int32_t second{0}; //!< Second
int32_t tzHour{0}; //!< Hours ahead or behind UTC
int32_t tzMinute{0}; //!< Minutes ahead or behind UTC
};
//! @name Manipulators
@ -1260,7 +1261,8 @@ class ValueType : public Value {
//! Utility for toInt64, toUint32, etc.
template <typename I>
inline I rational_to_integer_helper(size_t n) const {
auto&& [a, b] = value_.at(n);
auto a = value_.at(n).first;
auto b = value_.at(n).second;
// Protect against divide-by-zero.
if (b <= 0) {
@ -1268,16 +1270,16 @@ class ValueType : public Value {
}
// Check for integer overflow.
if (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
// conversion does not change sign
const auto imin = std::numeric_limits<I>::min();
const auto imax = std::numeric_limits<I>::max();
if (imax < b || a < imin || imax < a) {
return 0;
}
} else if (std::is_signed_v<I>) {
} else if (std::is_signed<I>::value) {
// conversion is from unsigned to signed
const auto imax = std::make_unsigned_t<I>(std::numeric_limits<I>::max());
const auto imax = typename std::make_unsigned<I>::type(std::numeric_limits<I>::max());
if (imax < b || imax < a) {
return 0;
}
@ -1288,8 +1290,8 @@ class ValueType : public Value {
return 0;
}
// Inputs are not negative so convert them to unsigned.
const auto a_u = std::make_unsigned_t<decltype(a)>(a);
const auto b_u = std::make_unsigned_t<decltype(b)>(b);
const auto a_u = typename std::make_unsigned<decltype(a)>::type(a);
const auto b_u = typename std::make_unsigned<decltype(b)>::type(b);
if (imax < b_u || imax < a_u) {
return 0;
}

@ -72,9 +72,9 @@
// namespace extensions
namespace Exiv2 {
/*!
@brief Return the version of %Exiv2 available at runtime as an integer.
@brief Return the version of %Exiv2 available at runtime as a uint32_t.
*/
EXIV2API int versionNumber();
EXIV2API uint32_t versionNumber();
/*!
@brief Return the version string Example: "0.25.0" (major.minor.patch)
*/
@ -96,7 +96,7 @@ EXIV2API const char* version();
Versions are denoted using a triplet of integers: \em major.minor.patch .
The fourth version number is designated a "tweak" an used by Release Candidates
*/
EXIV2API bool testVersion(int major, int minor, int patch);
EXIV2API bool testVersion(uint32_t major, uint32_t minor, uint32_t patch);
/*!
@brief dumpLibraryInfo implements the exiv2 option --version --verbose
used by exiv2 test suite to inspect libraries loaded at run-time

@ -46,7 +46,7 @@ class EXIV2API WebPImage : public Image {
/*!
@brief Not supported. Calling this function will throw an Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
void setIptcData(const IptcData& /*iptcData*/) override;
//! @name Accessors
@ -54,6 +54,7 @@ class EXIV2API WebPImage : public Image {
[[nodiscard]] std::string mimeType() const override;
//@}
~WebPImage() override = default;
//! Copy constructor
WebPImage(const WebPImage&) = delete;
//! Assignment operator
@ -62,13 +63,15 @@ class EXIV2API WebPImage : public Image {
private:
void doWriteMetadata(BasicIo& outIo);
//! @name NOT Implemented
//@{
static long getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size);
static bool equalsWebPTag(Exiv2::DataBuf& buf, const char* str);
void debugPrintHex(byte* data, long size);
void decodeChunks(long filesize);
void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_alpha, bool has_icc, int width, int height);
//! Finds the offset of header in data. Returns std::string::npos if the header isn't found.
static size_t getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size);
static bool equalsWebPTag(const Exiv2::DataBuf& buf, const char* str);
void debugPrintHex(byte* data, size_t size);
void decodeChunks(uint32_t filesize);
void inject_VP8X(BasicIo& iIo, bool has_xmp, bool has_exif, bool has_alpha, bool has_icc, uint32_t width,
uint32_t height);
/* Misc. */
static constexpr byte WEBP_PAD_ODD = 0;
static constexpr int WEBP_TAG_SIZE = 0x4;

@ -58,16 +58,11 @@ class EXIV2API Xmpdatum : public Metadatum {
Calls setValue(const std::string&).
*/
Xmpdatum& operator=(const std::string& value);
/*!
@brief Assign const char* \em value to the %Xmpdatum.
Calls operator=(const std::string&).
*/
Xmpdatum& operator=(const char* value);
/*!
@brief Assign a boolean \em value to the %Xmpdatum.
Translates the value to a string "true" or "false".
*/
Xmpdatum& operator=(const bool& value);
Xmpdatum& operator=(bool value);
/*!
@brief Assign a \em value of any type with an output operator
to the %Xmpdatum. Calls operator=(const std::string&).
@ -108,6 +103,7 @@ class EXIV2API Xmpdatum : public Metadatum {
//! Return the property name.
[[nodiscard]] std::string tagName() const override;
[[nodiscard]] std::string tagLabel() const override;
[[nodiscard]] std::string tagDesc() const override;
//! Properties don't have a tag number. Return 0.
[[nodiscard]] uint16_t tag() const override;
[[nodiscard]] TypeId typeId() const override;
@ -227,23 +223,23 @@ class EXIV2API XmpData {
//! are we to use the packet?
[[nodiscard]] bool usePacket() const {
return usePacket_;
};
}
//! set usePacket_
bool usePacket(bool b) {
bool r = usePacket_;
usePacket_ = b;
return r;
};
}
//! setPacket
void setPacket(std::string xmpPacket) {
xmpPacket_ = std::move(xmpPacket);
usePacket(false);
};
}
// ! getPacket
[[nodiscard]] const std::string& xmpPacket() const {
return xmpPacket_;
};
}
//@}
@ -404,11 +400,7 @@ class EXIV2API XmpParser {
// *****************************************************************************
// free functions, template and inline definitions
inline Xmpdatum& Xmpdatum::operator=(const char* value) {
return Xmpdatum::operator=(std::string(value));
}
inline Xmpdatum& Xmpdatum::operator=(const bool& value) {
inline Xmpdatum& Xmpdatum::operator=(bool value) {
return operator=(value ? "True" : "False");
}

@ -46,7 +46,7 @@ class EXIV2API XmpSidecar : public Image {
@brief Not supported. XMP sidecar files do not contain a comment.
Calling this function will throw an instance of Error(ErrorCode::kerInvalidSettingForImage).
*/
void setComment(std::string_view comment) override;
void setComment(const std::string&) override;
//@}
//! @name Accessors

@ -670,8 +670,8 @@ msgstr ""
"Sadrzaj koda drzave je fokusiran na -- ili je drzava prikazana u vizuelom "
"mediju ili je navedena u tekstualnom ili zvucnom mediju. Ovaj element je na "
"vrhu/prvom nivou odozgo prema dole geografskoj hijerarhiji. Sifra treba biti "
"uzeta iz ISO 3166 dva ili tri slova. Puni naziv drzave treba ici u \"Drzava"
"\" element."
"uzeta iz ISO 3166 dva ili tri slova. Puni naziv drzave treba ici u "
"\"Drzava\" element."
#: src/properties.cpp:965
#, fuzzy
@ -2842,8 +2842,8 @@ msgstr "Alžir"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Aliases nisu podržani. Molimo pošaljite ovaj XMP paket ahuggel@gmx.net '% "
"1', '% 2', '% 3'"
@ -13170,8 +13170,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
"Pokazuje jedinicu upotrijebljenu za izražavanje udaljenosti do krajnje "
"destinacije. \"K\",\"M\" i \"N\" predstavljaju kilometre, milje i čvorova."
@ -13229,8 +13229,8 @@ msgid ""
"latitude. The ASCII value \"N\" indicates north latitude, and \"S\" is south "
"latitude."
msgstr ""
"Pokazuje da li je smjer destinacije sjeverno ili južno. ASCII vrijednost \"N"
"\" označava sjevernu, a \"S\" južnu usmjerenost."
"Pokazuje da li je smjer destinacije sjeverno ili južno. ASCII vrijednost "
"\"N\" označava sjevernu, a \"S\" južnu usmjerenost."
#: src/tags.cpp:2000
msgid ""
@ -19872,7 +19872,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""
@ -24184,8 +24184,8 @@ msgid ""
"\"Oktoberfest, Munich Germany\" For more accurate positioning, use the EXIF "
"GPS values."
msgstr ""
"Naziv mjesta gdje je video snimljen. Naprimjer: \"Oktoberfest, Munich Germany"
"\". Za preciznije pozicioniranje, iskoristi EXIF GPS vrijednosti."
"Naziv mjesta gdje je video snimljen. Naprimjer: \"Oktoberfest, Munich "
"Germany\". Za preciznije pozicioniranje, iskoristi EXIF GPS vrijednosti."
#: src/properties.cpp:2293
msgid ""

File diff suppressed because it is too large Load Diff

@ -2686,8 +2686,8 @@ msgstr "Justiere"
#: src/exiv2.cpp:1026
msgid "Adjust action requires at least one -a, -Y, -O or -D option\n"
msgstr ""
"Die Aktion \"justieren\" benötigt mindestens eine der Optionen \"-a\", \"-Y"
"\", \"-O\" oder \"-D\"\n"
"Die Aktion \"justieren\" benötigt mindestens eine der Optionen \"-a\", \"-"
"Y\", \"-O\" oder \"-D\"\n"
#: src/actions.cpp:1745
msgid "Adjusting"
@ -2894,8 +2894,8 @@ msgstr "Algier"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Aliase werden nicht unterstützt. Bitte senden Sie dieses XMP-Packet an "
"ahuggel@gmx.net `%1', `%2', `%3'"
@ -13532,8 +13532,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -20475,7 +20475,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2911,8 +2911,8 @@ msgstr "Argel"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Los alias no están permitidos. Por favor envíe este paquete XMP a "
"ahuggel@gmx.net «%1», «%2», «%3»"
@ -8800,8 +8800,8 @@ msgstr ""
#: src/error.cpp:78
msgid "Entry::setValue: Value too large (tag=%1, size=%2, requested=%3)"
msgstr ""
"Entry::setValue: Valor demasiado grande (etiqueta=%1, tamaño=%2, solicitado="
"%3)"
"Entry::setValue: Valor demasiado grande (etiqueta=%1, tamaño=%2, "
"solicitado=%3)"
#: src/datasets.cpp:108
msgid "Envelope Number"
@ -13130,8 +13130,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
"Indica la unidad de medida empleada para expresar la distancia al punto de "
"destino. «K», «M» y «N» representan kilómetros, millas y nudos, "
@ -19696,7 +19696,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""
@ -23886,8 +23886,8 @@ msgid ""
"'/' character (ex.: \"City/Paris/Monument/Eiffel Tower\"."
msgstr ""
"La lista de ruta de etiquetas completa como cadena. La jerarquía de la ruta "
"se separa por el carácter «/» (ej.: «Ciudad/Madrid/Monumento/Museo del Prado"
"\"."
"se separa por el carácter «/» (ej.: «Ciudad/Madrid/Monumento/Museo del "
"Prado\"."
#: src/properties.cpp:212
msgid ""

@ -2664,8 +2664,8 @@ msgstr ""
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -12977,8 +12977,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -19804,7 +19804,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2856,8 +2856,8 @@ msgstr "Alger"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -13469,8 +13469,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -20506,7 +20506,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2778,8 +2778,8 @@ msgstr "Alxeria"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Non se admiten os alias. E envíe este paquete XMP a ahuggel@gmx.net «%1», "
"«%2», «%3»"
@ -8744,14 +8744,14 @@ msgstr "Valores do mellorador"
#: src/error.cpp:79
msgid "Entry::setDataArea: Value too large (tag=%1, size=%2, requested=%3)"
msgstr ""
"Entry::setDataArea: Valor grande de máis (etiqueta=%1, tamaño=%2, solicitado="
"%3)"
"Entry::setDataArea: Valor grande de máis (etiqueta=%1, tamaño=%2, "
"solicitado=%3)"
#: src/error.cpp:78
msgid "Entry::setValue: Value too large (tag=%1, size=%2, requested=%3)"
msgstr ""
"Entry::setValue: Valor grande de máis (etiqueta=%1, tamaño=%2, solicitado="
"%3)"
"Entry::setValue: Valor grande de máis (etiqueta=%1, tamaño=%2, "
"solicitado=%3)"
#: src/datasets.cpp:108
msgid "Envelope Number"
@ -13119,8 +13119,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -19807,7 +19807,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2900,11 +2900,11 @@ msgstr "Algiers"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Alias tidak disokong. Sila hantar paket XMP ini ke ahuggel@gmx.net `%1', `"
"%2', `%3'"
"Alias tidak disokong. Sila hantar paket XMP ini ke ahuggel@gmx.net `%1', "
"`%2', `%3'"
#: src/nikonmn.cpp:1680
msgid "All 11 Points"
@ -13169,11 +13169,11 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
"Menunjukkan unit yang digunakan untuk mengungkap jarak titik destinasi. \"K"
"\", \"M\" dan \"N\" mewakili kilometer, batu dan knot."
"Menunjukkan unit yang digunakan untuk mengungkap jarak titik destinasi. "
"\"K\", \"M\" dan \"N\" mewakili kilometer, batu dan knot."
#: src/tags.cpp:1981
msgid ""
@ -19805,7 +19805,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""
@ -25750,8 +25750,9 @@ msgid ""
"default \"look\" table. The data for this table is stored in the "
"ProfileLookTableData tag."
msgstr ""
"Tag ini menyatakan bilangan sampel input dalam setiap dimensi jadual \"lihat"
"\" lalai. Data bagi jadual ini disimpan dalam tag ProfileLookTableData."
"Tag ini menyatakan bilangan sampel input dalam setiap dimensi jadual "
"\"lihat\" lalai. Data bagi jadual ini disimpan dalam tag "
"ProfileLookTableData."
#: src/tags.cpp:1256
msgid ""

@ -2657,8 +2657,8 @@ msgstr ""
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -12196,8 +12196,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -18487,7 +18487,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -23,8 +23,8 @@ msgstr ""
"X-Poedit-Country: POLAND\n"
"X-Poedit-Bookmarks: 991,1974,-1,-1,-1,-1,-1,-1,-1,-1\n"
"X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n"
"%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && "
"(n%100<10 || n%100>=20) ? 1 : 2);\n"
#: src/exiv2.cpp:262
msgid ""
@ -370,8 +370,8 @@ msgstr ""
msgid ""
" -t Also set the file timestamp in 'rename' action (overrides -k).\n"
msgstr ""
" -t Ustawia także znacznik czasowy pliku podczas akcji \"rename"
"\" (nadpisuje opcję -k).\n"
" -t Ustawia także znacznik czasowy pliku podczas akcji "
"\"rename\" (nadpisuje opcję -k).\n"
#: src/exiv2.cpp:287
msgid " -u Show unknown tags.\n"
@ -2814,8 +2814,8 @@ msgstr "Algier"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Aliasy nie są obsługiwane. Prześlij proszę ten pakiet XMP do ahuggel@gmx.net "
"\"%1\", \"%2\", \"%3\""
@ -13280,8 +13280,8 @@ msgid ""
"Indicates the reference for giving the direction of the image when it is "
"captured. \"T\" denotes true direction and \"M\" is magnetic direction."
msgstr ""
"Oznaczenie rodzaju kierunku (namiaru) do obrazu podczas jego wykonywania. \"T"
"\" oznacza kierunek rzeczywisty, a \"M\" kierunek magnetyczny."
"Oznaczenie rodzaju kierunku (namiaru) do obrazu podczas jego wykonywania. "
"\"T\" oznacza kierunek rzeczywisty, a \"M\" kierunek magnetyczny."
#: src/tags.cpp:2099
msgid ""
@ -13394,13 +13394,13 @@ msgid ""
"Indicates the unit used to express the GPS receiver speed of movement. \"K\" "
"\"M\" and \"N\" represents kilometers per hour, miles per hour, and knots."
msgstr ""
"Jednostka użyta do pomiaru prędkości ruchu odbiornika GPS. \"K\", \"M\" i \"N"
"\" oznaczają kilometry, mile i węzły."
"Jednostka użyta do pomiaru prędkości ruchu odbiornika GPS. \"K\", \"M\" i "
"\"N\" oznaczają kilometry, mile i węzły."
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
"Jednostki użyte do wyrażenia odległości do punktu docelowego. \"K\", \"M\" i "
"\"N\" oznaczają kilometry, mile i węzły."
@ -13473,8 +13473,8 @@ msgid ""
"longitude. ASCII \"E\" indicates east longitude, and \"W\" is west longitude."
msgstr ""
"Określenie, czy długość geograficzna punktu docelowego jest wschodnia, czy "
"zachodnia. Wartość ASCII \"E\" oznacza długość geograficzną wschodnią, a \"W"
"\" zachodnią."
"zachodnia. Wartość ASCII \"E\" oznacza długość geograficzną wschodnią, a "
"\"W\" zachodnią."
#: src/properties.cpp:1443
msgid "Indication of movie format (computer-generated, digitized, and so on)."
@ -20307,7 +20307,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2822,8 +2822,8 @@ msgstr ""
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -13520,8 +13520,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -20388,7 +20388,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -16,8 +16,8 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.10.2\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: src/exiv2.cpp:262
msgid ""
@ -2831,8 +2831,8 @@ msgstr ""
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -13683,8 +13683,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -20842,7 +20842,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2866,8 +2866,8 @@ msgstr "Algiers"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
# AF = automatické zaostrenie
@ -8957,8 +8957,8 @@ msgstr ""
#: src/error.cpp:78
msgid "Entry::setValue: Value too large (tag=%1, size=%2, requested=%3)"
msgstr ""
"Entry::setValue: Hodnota je príliš veľká (značka=%1, veľkosť=%2, požadovaná="
"%3)"
"Entry::setValue: Hodnota je príliš veľká (značka=%1, veľkosť=%2, "
"požadovaná=%3)"
#: src/datasets.cpp:108
msgid "Envelope Number"
@ -13517,8 +13517,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -20562,7 +20562,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -3001,8 +3001,8 @@ msgstr "Alger"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Alias stöds inte. Skicka detta XMP-paket till ahuggel@gmx.net ”%1”, ”%2”, "
"”%3”"
@ -13244,8 +13244,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
"Visar enheten som används för att visa avstånd till destinationen. ”K”, ”M” "
"och ”N” representerar kilometer, miles, och knop."
@ -19811,7 +19811,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2664,8 +2664,8 @@ msgstr "ئالجىر"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -12824,8 +12824,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -19575,7 +19575,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2765,8 +2765,8 @@ msgstr "Алжир"
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
"Псевдоніми не підтримуються. Будь ласка, відправте цей XMP пакунок за "
"адресою ahuggel@gmx.net `%1', `%2', `%3'"
@ -13078,8 +13078,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -19894,7 +19894,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -2706,8 +2706,8 @@ msgstr ""
#: src/error.cpp:101
msgid ""
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net `"
"%1', `%2', `%3'"
"Aliases are not supported. Please send this XMP packet to ahuggel@gmx.net "
"`%1', `%2', `%3'"
msgstr ""
#: src/nikonmn.cpp:1680
@ -13077,8 +13077,8 @@ msgstr ""
#: src/tags.cpp:2107
msgid ""
"Indicates the unit used to express the distance to the destination point. \"K"
"\", \"M\" and \"N\" represent kilometers, miles and knots."
"Indicates the unit used to express the distance to the destination point. "
"\"K\", \"M\" and \"N\" represent kilometers, miles and knots."
msgstr ""
#: src/tags.cpp:1981
@ -19876,7 +19876,7 @@ msgstr ""
#: src/properties.cpp:277
msgid ""
"References to resources that were incorporated, byinclusion or reference, "
"References to resources that were incorporated, by inclusion or reference, "
"into this resource."
msgstr ""

@ -31,10 +31,10 @@ int main(int argc, char* const argv[]) {
// This is the quickest way to add (simple) Exif data. If a metadatum for
// a given key already exists, its value is overwritten. Otherwise a new
// tag is added.
exifData["Exif.Image.Model"] = "Test 1"; // AsciiValue
exifData["Exif.Image.SamplesPerPixel"] = uint16_t(162); // UShortValue
exifData["Exif.Image.XResolution"] = -2; // LongValue
exifData["Exif.Image.YResolution"] = Exiv2::Rational(-2, 3); // RationalValue
exifData["Exif.Image.Model"] = "Test 1"; // AsciiValue
exifData["Exif.Image.SamplesPerPixel"] = static_cast<uint16_t>(162); // UShortValue
exifData["Exif.Image.XResolution"] = -2; // LongValue
exifData["Exif.Image.YResolution"] = Exiv2::Rational(-2, 3); // RationalValue
std::cout << "Added a few tags the quick way.\n";
// Create a ASCII string value (note the use of create)

@ -34,9 +34,9 @@ int main(int argc, char* const argv[]) {
std::cout << "Copy construction, non-intrusive changes\n";
Exiv2::ExifData ed1(ed);
ed1["Exif.Image.DateTime"] = "Sunday, 11am";
ed1["Exif.Image.Orientation"] = uint16_t(2);
ed1["Exif.Image.Orientation"] = static_cast<uint16_t>(2);
ed1["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am";
ed1["Exif.Photo.MeteringMode"] = uint16_t(1);
ed1["Exif.Photo.MeteringMode"] = static_cast<uint16_t>(1);
ed1["Exif.Iop.InteroperabilityIndex"] = "123";
// ed1["Exif.Thumbnail.Orientation"] = uint16_t(2);
write(file, ed1);
@ -61,11 +61,11 @@ int main(int argc, char* const argv[]) {
ed3["Exif.Thumbnail.Artist"] = "Test 6 Ifd1 tag";
ed3 = ed;
ed3["Exif.Image.DateTime"] = "Sunday, 11am";
ed3["Exif.Image.Orientation"] = uint16_t(2);
ed3["Exif.Image.Orientation"] = static_cast<uint16_t>(2);
ed3["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am";
ed3["Exif.Photo.MeteringMode"] = uint16_t(1);
ed3["Exif.Photo.MeteringMode"] = static_cast<uint16_t>(1);
ed3["Exif.Iop.InteroperabilityIndex"] = "123";
ed3["Exif.Thumbnail.Orientation"] = uint16_t(2);
ed3["Exif.Thumbnail.Orientation"] = static_cast<uint16_t>(2);
write(file, ed3);
print(file);
std::cout << "----------------------------------------------\n";
@ -78,9 +78,9 @@ int main(int argc, char* const argv[]) {
ed4["Exif.Image.DateTime"] = "Sunday, 11am and ten minutes";
ed4["Exif.Image.Orientation"] = "2 3 4 5";
ed4["Exif.Photo.DateTimeOriginal"] = "Sunday, 11am and ten minutes";
ed4["Exif.Photo.MeteringMode"] = uint16_t(1);
ed4["Exif.Photo.MeteringMode"] = static_cast<uint16_t>(1);
ed4["Exif.Iop.InteroperabilityIndex"] = "123";
ed4["Exif.Thumbnail.Orientation"] = uint16_t(2);
ed4["Exif.Thumbnail.Orientation"] = static_cast<uint16_t>(2);
write(file, ed4);
print(file);

@ -23,7 +23,7 @@ int main(int argc, char* const argv[]) try {
iptcData["Iptc.Application2.Headline"] = "The headline I am";
iptcData["Iptc.Application2.Keywords"] = "Yet another keyword";
iptcData["Iptc.Application2.DateCreated"] = "2004-8-3";
iptcData["Iptc.Application2.Urgency"] = uint16_t(1);
iptcData["Iptc.Application2.Urgency"] = static_cast<uint16_t>(1);
iptcData["Iptc.Envelope.ModelVersion"] = 42;
iptcData["Iptc.Envelope.TimeSent"] = "14:41:0-05:00";
iptcData["Iptc.Application2.RasterizedCaption"] = "230 42 34 2 90 84 23 146";

@ -34,12 +34,12 @@ int main(int argc, char* const argv[]) {
// set/add metadata
std::cout << "Modify the metadata ...\n";
Exiv2::ExifData exifData;
exifData["Exif.Photo.UserComment"] = "Hello World"; // AsciiValue
exifData["Exif.Image.Software"] = "Exiv2"; // AsciiValue
exifData["Exif.Image.Copyright"] = "Exiv2"; // AsciiValue
exifData["Exif.Image.Make"] = "Canon"; // AsciiValue
exifData["Exif.Canon.OwnerName"] = "Tuan"; // UShortValue
exifData["Exif.CanonCs.LensType"] = uint16_t(65535); // LongValue
exifData["Exif.Photo.UserComment"] = "Hello World"; // AsciiValue
exifData["Exif.Image.Software"] = "Exiv2"; // AsciiValue
exifData["Exif.Image.Copyright"] = "Exiv2"; // AsciiValue
exifData["Exif.Image.Make"] = "Canon"; // AsciiValue
exifData["Exif.Canon.OwnerName"] = "Tuan"; // UShortValue
exifData["Exif.CanonCs.LensType"] = static_cast<uint16_t>(65535); // LongValue
Exiv2::Value::UniquePtr v = Exiv2::Value::create(Exiv2::asciiString);
v->read("2013:06:09 14:30:30");
Exiv2::ExifKey key("Exif.Image.DateTime");

@ -61,7 +61,7 @@ void mini1(const char* path) {
enforce(wm == wmIntrusive, Exiv2::ErrorCode::kerErrorMessage, "encode returned an unexpected value");
std::cout << "Test 3: Wrote non-empty Exif data without original binary data:\n";
exifData.clear();
ByteOrder bo = ExifParser::decode(exifData, &blob[0], blob.size());
ByteOrder bo = ExifParser::decode(exifData, blob.data(), blob.size());
enforce(bo == bigEndian, Exiv2::ErrorCode::kerErrorMessage, "decode returned an unexpected value");
print(exifData);
}

@ -56,11 +56,11 @@ int main(int argc, char* const argv[]) {
edMn1["Exif.Image.Make"] = "Canon";
edMn1["Exif.Image.Model"] = "Canon PowerShot S40";
edMn1["Exif.Canon.0xabcd"] = "A Canon makernote tag";
edMn1["Exif.CanonCs.0x0002"] = uint16_t(41);
edMn1["Exif.CanonSi.0x0005"] = uint16_t(42);
edMn1["Exif.CanonCf.0x0001"] = uint16_t(43);
edMn1["Exif.CanonPi.0x0001"] = uint16_t(44);
edMn1["Exif.CanonPa.0x0001"] = uint16_t(45);
edMn1["Exif.CanonCs.0x0002"] = static_cast<uint16_t>(41);
edMn1["Exif.CanonSi.0x0005"] = static_cast<uint16_t>(42);
edMn1["Exif.CanonCf.0x0001"] = static_cast<uint16_t>(43);
edMn1["Exif.CanonPi.0x0001"] = static_cast<uint16_t>(44);
edMn1["Exif.CanonPa.0x0001"] = static_cast<uint16_t>(45);
write(file, edMn1);
print(file);
@ -69,8 +69,8 @@ int main(int argc, char* const argv[]) {
image->readMetadata();
Exiv2::ExifData& rEd = image->exifData();
rEd["Exif.CanonCs.0x0001"] = uint16_t(88);
rEd["Exif.CanonSi.0x0004"] = uint16_t(99);
rEd["Exif.CanonCs.0x0001"] = static_cast<uint16_t>(88);
rEd["Exif.CanonSi.0x0004"] = static_cast<uint16_t>(99);
image->writeMetadata();
print(file);
@ -118,7 +118,7 @@ int main(int argc, char* const argv[]) {
Exiv2::ExifData edMn7;
edMn7["Exif.Image.Make"] = "OLYMPUS CORPORATION";
edMn7["Exif.Image.Model"] = "C8080WZ";
edMn7["Exif.Olympus.0x0201"] = uint16_t(1);
edMn7["Exif.Olympus.0x0201"] = static_cast<uint16_t>(1);
write(file, edMn7);
print(file);
@ -126,7 +126,7 @@ int main(int argc, char* const argv[]) {
Exiv2::ExifData edMn8;
edMn8["Exif.Image.Make"] = "Panasonic";
edMn8["Exif.Image.Model"] = "DMC-FZ5";
edMn8["Exif.Panasonic.0x0001"] = uint16_t(1);
edMn8["Exif.Panasonic.0x0001"] = static_cast<uint16_t>(1);
write(file, edMn8);
print(file);
@ -142,13 +142,13 @@ int main(int argc, char* const argv[]) {
Exiv2::ExifData edMn10;
edMn10["Exif.Image.Make"] = "Minolta";
edMn10["Exif.Image.Model"] = "A fancy Minolta camera";
edMn10["Exif.Minolta.ColorMode"] = uint32_t(1);
edMn10["Exif.MinoltaCsNew.WhiteBalance"] = uint32_t(2);
edMn10["Exif.MinoltaCs5D.WhiteBalance"] = uint16_t(3);
edMn10["Exif.MinoltaCs5D.ColorTemperature"] = int16_t(-1);
edMn10["Exif.MinoltaCs7D.WhiteBalance"] = uint16_t(4);
edMn10["Exif.MinoltaCs7D.ExposureCompensation"] = int16_t(-2);
edMn10["Exif.MinoltaCs7D.ColorTemperature"] = int16_t(-3);
edMn10["Exif.Minolta.ColorMode"] = static_cast<uint32_t>(1);
edMn10["Exif.MinoltaCsNew.WhiteBalance"] = static_cast<uint32_t>(2);
edMn10["Exif.MinoltaCs5D.WhiteBalance"] = static_cast<uint16_t>(3);
edMn10["Exif.MinoltaCs5D.ColorTemperature"] = static_cast<int16_t>(-1);
edMn10["Exif.MinoltaCs7D.WhiteBalance"] = static_cast<uint16_t>(4);
edMn10["Exif.MinoltaCs7D.ExposureCompensation"] = static_cast<int16_t>(-2);
edMn10["Exif.MinoltaCs7D.ColorTemperature"] = static_cast<int16_t>(-3);
write(file, edMn10);
print(file);

@ -40,7 +40,7 @@ int main() try {
xmpData["Xmp.dc.one"] = -1;
xmpData["Xmp.dc.two"] = 3.1415;
xmpData["Xmp.dc.three"] = Exiv2::Rational(5, 7);
xmpData["Xmp.dc.four"] = uint16_t(255);
xmpData["Xmp.dc.four"] = static_cast<uint16_t>(255);
xmpData["Xmp.dc.five"] = 256;
xmpData["Xmp.dc.six"] = false;

@ -458,8 +458,10 @@ int FileIo::seek(int64_t offset, Position pos) {
#endif
}
long FileIo::tell() const {
return std::ftell(p_->fp_);
size_t FileIo::tell() const {
const long pos = std::ftell(p_->fp_);
enforce(pos >= 0, ErrorCode::kerInputDataReadFailed);
return static_cast<size_t>(pos);
}
size_t FileIo::size() const {
@ -786,8 +788,8 @@ int MemIo::munmap() {
return 0;
}
long MemIo::tell() const {
return static_cast<long>(p_->idx_);
size_t MemIo::tell() const {
return p_->idx_;
}
size_t MemIo::size() const {
@ -899,7 +901,7 @@ void XPathIo::ReadDataUri(const std::string& path) {
}
#else
XPathIo::XPathIo(const std::string& orgPath) : FileIo(XPathIo::writeDataToFile(orgPath)), isTemp_(true) {
XPathIo::XPathIo(const std::string& orgPath) : FileIo(XPathIo::writeDataToFile(orgPath)) {
tempFilePath_ = path();
}
@ -992,15 +994,15 @@ class RemoteIo::Impl {
Impl& operator=(const Impl&) = delete;
// DATA
std::string path_; //!< (Standard) path
size_t blockSize_; //!< Size of the block memory.
BlockMap* blocksMap_; //!< An array contains all blocksMap
size_t size_; //!< The file size
size_t idx_; //!< Index into the memory area
bool isMalloced_; //!< Was the blocksMap_ allocated?
bool eof_; //!< EOF indicator
Protocol protocol_; //!< the protocol of url
size_t totalRead_; //!< bytes requested from host
std::string path_; //!< (Standard) path
size_t blockSize_; //!< Size of the block memory.
BlockMap* blocksMap_{nullptr}; //!< An array contains all blocksMap
size_t size_{0}; //!< The file size
size_t idx_{0}; //!< Index into the memory area
bool isMalloced_{false}; //!< Was the blocksMap_ allocated?
bool eof_{false}; //!< EOF indicator
Protocol protocol_; //!< the protocol of url
size_t totalRead_{0}; //!< bytes requested from host
// METHODS
/*!
@ -1042,15 +1044,7 @@ class RemoteIo::Impl {
}; // class RemoteIo::Impl
RemoteIo::Impl::Impl(const std::string& url, size_t blockSize) :
path_(url),
blockSize_(blockSize),
blocksMap_(nullptr),
size_(0),
idx_(0),
isMalloced_(false),
eof_(false),
protocol_(fileProtocol(url)),
totalRead_(0) {
path_(url), blockSize_(blockSize), protocol_(fileProtocol(url)) {
}
size_t RemoteIo::Impl::populateBlocks(size_t lowBlock, size_t highBlock) {
@ -1341,8 +1335,8 @@ int RemoteIo::munmap() {
return 0;
}
long RemoteIo::tell() const {
return static_cast<long>(p_->idx_);
size_t RemoteIo::tell() const {
return p_->idx_;
}
size_t RemoteIo::size() const {
@ -1473,7 +1467,7 @@ void HttpIo::HttpImpl::writeRemote(const byte* data, size_t size, size_t from, s
// standardize the path without "/" at the beginning.
std::size_t protocolIndex = scriptPath.find("://");
if (protocolIndex == std::string::npos && scriptPath[0] != '/') {
if (protocolIndex == std::string::npos && scriptPath.front() != '/') {
scriptPath = "/" + scriptPath;
}
@ -1663,7 +1657,7 @@ void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, size_t from, s
// add the protocol and host to the path
std::size_t protocolIndex = scriptPath.find("://");
if (protocolIndex == std::string::npos) {
if (scriptPath[0] != '/')
if (scriptPath.front() != '/')
scriptPath = "/" + scriptPath;
scriptPath = hostInfo.Protocol + "://" + hostInfo.Host + scriptPath;
}

@ -74,7 +74,7 @@ BmffImage::BmffImage(BasicIo::UniquePtr io, bool /* create */) :
Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io)) {
} // BmffImage::BmffImage
std::string BmffImage::toAscii(long n) {
std::string BmffImage::toAscii(uint32_t n) {
const auto p = reinterpret_cast<const char*>(&n);
std::string result;
for (int i = 0; i < 4; i++) {
@ -152,9 +152,9 @@ std::string BmffImage::uuidName(Exiv2::DataBuf& uuid) {
return result;
}
long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStructureOption option /* = kpsNone */,
long pbox_end, int depth) {
long address = io_->tell();
uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStructureOption option /* = kpsNone */,
uint64_t pbox_end, int depth) {
const size_t address = io_->tell();
// never visit a box twice!
if (depth == 0)
visits_.clear();
@ -198,22 +198,22 @@ long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStruc
}
// read data in box and restore file position
long restore = io_->tell();
const size_t restore = io_->tell();
enforce(box_length >= hdrsize, Exiv2::ErrorCode::kerCorruptedMetadata);
enforce(box_length - hdrsize <= static_cast<uint64_t>(pbox_end - restore), Exiv2::ErrorCode::kerCorruptedMetadata);
enforce(box_length - hdrsize <= pbox_end - restore, Exiv2::ErrorCode::kerCorruptedMetadata);
const auto buffer_size = static_cast<size_t>(box_length - hdrsize);
const auto buffer_size = box_length - hdrsize;
if (skipBox(box_type)) {
if (bTrace) {
out << std::endl;
}
// The enforce() above checks that restore + buffer_size won't
// exceed pbox_end, and by implication, won't exceed LONG_MAX
return restore + static_cast<long>(buffer_size);
return restore + buffer_size;
}
DataBuf data(buffer_size);
const long box_end = restore + static_cast<long>(data.size());
DataBuf data(static_cast<size_t>(buffer_size));
const size_t box_end = restore + data.size();
io_->read(data.data(), data.size());
io_->seek(restore, BasicIo::beg);
@ -437,10 +437,10 @@ long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStruc
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) {
@ -478,26 +478,25 @@ long BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintStruc
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length, uint64_t start) {
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
enforce(start <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
enforce(length <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
enforce(start <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()), ErrorCode::kerCorruptedMetadata);
enforce(length <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
// read and parse exif data
long restore = io_->tell();
const size_t restore = io_->tell();
DataBuf exif(static_cast<size_t>(length));
io_->seek(static_cast<long>(start), BasicIo::beg);
io_->seek(static_cast<int64_t>(start), BasicIo::beg);
if (exif.size() > 8 && io_->read(exif.data(), exif.size()) == exif.size()) {
// hunt for "II" or "MM"
long eof = 0xffffffff; // impossible value for punt
long punt = eof;
const size_t eof = std::numeric_limits<size_t>::max(); // impossible value for punt
size_t punt = eof;
for (size_t i = 0; i < exif.size() - 8 && punt == eof; i += 2) {
if (exif.read_uint8(i) == exif.read_uint8(i + 1))
if (exif.read_uint8(i) == 'I' || exif.read_uint8(i) == 'M')
punt = static_cast<long>(i);
punt = i;
}
if (punt != eof) {
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt),
static_cast<uint32_t>(exif.size() - punt), root_tag,
Internal::TiffMapping::findDecoder);
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt), exif.size() - punt,
root_tag, Internal::TiffMapping::findDecoder);
}
}
io_->seek(restore, BasicIo::beg);
@ -506,7 +505,7 @@ void BmffImage::parseTiff(uint32_t root_tag, uint64_t length, uint64_t start) {
void BmffImage::parseTiff(uint32_t root_tag, uint64_t length) {
if (length > 8) {
enforce(length - 8 <= io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
enforce(length - 8 <= std::numeric_limits<uint64_t>::max(), ErrorCode::kerCorruptedMetadata);
enforce(length - 8 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
DataBuf data(static_cast<size_t>(length - 8u));
const size_t bufRead = io_->read(data.data(), data.size());
@ -521,37 +520,34 @@ void BmffImage::parseTiff(uint32_t root_tag, uint64_t length) {
}
void BmffImage::parseXmp(uint64_t length, uint64_t start) {
if (length > 8) {
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
long restore = io_->tell();
io_->seek(static_cast<long>(start), BasicIo::beg);
auto lengthSizeT = static_cast<size_t>(length);
DataBuf xmp(lengthSizeT + 1);
xmp.write_uint8(lengthSizeT, 0); // ensure xmp is null terminated!
if (io_->read(xmp.data(), lengthSizeT) != lengthSizeT)
throw Error(ErrorCode::kerInputDataReadFailed);
if (io_->error())
throw Error(ErrorCode::kerFailedToReadImageData);
try {
Exiv2::XmpParser::decode(xmpData(), std::string(xmp.c_str()));
} catch (...) {
throw Error(ErrorCode::kerFailedToReadImageData);
}
enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
io_->seek(restore, BasicIo::beg);
const size_t restore = io_->tell();
io_->seek(static_cast<int64_t>(start), BasicIo::beg);
auto lengthSizeT = static_cast<size_t>(length);
DataBuf xmp(lengthSizeT + 1);
xmp.write_uint8(lengthSizeT, 0); // ensure xmp is null terminated!
if (io_->read(xmp.data(), lengthSizeT) != lengthSizeT)
throw Error(ErrorCode::kerInputDataReadFailed);
if (io_->error())
throw Error(ErrorCode::kerFailedToReadImageData);
try {
Exiv2::XmpParser::decode(xmpData(), std::string(xmp.c_str()));
} catch (...) {
throw Error(ErrorCode::kerFailedToReadImageData);
}
io_->seek(restore, BasicIo::beg);
}
/// \todo instead of passing the last 4 parameters, pass just one and build the different offsets inside
void BmffImage::parseCr3Preview(DataBuf& data, std::ostream& out, bool bTrace, uint8_t version, size_t width_offset,
size_t height_offset, size_t size_offset, size_t relative_position) {
// Derived from https://github.com/lclevy/canon_cr3
long here = io_->tell();
enforce(here >= 0 && here <= std::numeric_limits<long>::max() - static_cast<long>(relative_position),
ErrorCode::kerCorruptedMetadata);
const size_t here = io_->tell();
enforce(here <= std::numeric_limits<size_t>::max() - relative_position, ErrorCode::kerCorruptedMetadata);
NativePreview nativePreview;
nativePreview.position_ = here + relative_position;
nativePreview.width_ = data.read_uint16(width_offset, endian_);
@ -569,12 +565,12 @@ void BmffImage::parseCr3Preview(DataBuf& data, std::ostream& out, bool bTrace, u
nativePreviews_.push_back(nativePreview);
if (bTrace) {
out << Internal::stringFormat("width,height,size = %u,%u,%u", nativePreview.width_, nativePreview.height_,
out << Internal::stringFormat("width,height,size = %zu,%zu,%zu", nativePreview.width_, nativePreview.height_,
nativePreview.size_);
}
}
void BmffImage::setComment(std::string_view /*comment*/) {
void BmffImage::setComment(const std::string&) {
// bmff files are read-only
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "BMFF"));
}
@ -602,8 +598,8 @@ void BmffImage::readMetadata() {
exifID_ = unknownID_;
xmpID_ = unknownID_;
long address = 0;
const auto file_end = static_cast<long>(io_->size());
uint64_t address = 0;
const auto file_end = io_->size();
while (address < file_end) {
io_->seek(address, BasicIo::beg);
address = boxHandler(std::cout, kpsNone, file_end, 0);
@ -637,8 +633,8 @@ void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption op
openOrThrow();
IoCloser closer(*io_);
long address = 0;
const auto file_end = static_cast<long>(io_->size());
uint64_t address = 0;
const auto file_end = io_->size();
while (address < file_end) {
io_->seek(address, BasicIo::beg);
address = boxHandler(out, option, file_end, depth);
@ -684,7 +680,7 @@ bool isBmffType(BasicIo& iIo, bool advance) {
bool const is_video = (buf[8] == 'q' && buf[9] == 't' && buf[10] == ' ' && buf[11] == ' ');
bool matched = is_jxl || (is_ftyp && !is_video);
if (!advance || !matched) {
iIo.seek(static_cast<long>(0), BasicIo::beg);
iIo.seek(0, BasicIo::beg);
}
return matched;
}

@ -35,7 +35,7 @@ void BmpImage::setIptcData(const IptcData& /*iptcData*/) {
throw(Error(ErrorCode::kerInvalidSettingForImage, "IPTC metadata", "BMP"));
}
void BmpImage::setComment(std::string_view /*comment*/) {
void BmpImage::setComment(const std::string&) {
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "BMP"));
}

File diff suppressed because it is too large Load Diff

@ -80,43 +80,45 @@ constexpr TagDetails casioCCDSensitivity[] = {
// Casio MakerNote Tag Info
constexpr TagInfo CasioMakerNote::tagInfo_[] = {
{0x0001, "RecodingMode", N_("RecodingMode"), N_("Recording Mode"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioRecordingMode)},
{0x0002, "Quality", N_("Quality"), N_("Quality"), casioId, makerTags, unsignedShort, -1,
{0x0001, "RecodingMode", N_("RecodingMode"), N_("Recording Mode"), IfdId::casioId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casioRecordingMode)},
{0x0002, "Quality", N_("Quality"), N_("Quality"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioQuality)},
{0x0003, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), casioId, makerTags, unsignedShort, -1,
{0x0003, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFocusMode)},
{0x0004, "FlashMode", N_("Flash Mode"), N_("Flash Mode"), casioId, makerTags, unsignedShort, -1,
{0x0004, "FlashMode", N_("Flash Mode"), N_("Flash Mode"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFlashMode)},
{0x0005, "FlashIntensity", N_("Flash Intensity"), N_("Flash Intensity"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFlashIntensity)},
{0x0006, "ObjectDistance", N_("Object Distance"), N_("Distance to object"), casioId, makerTags, unsignedLong, -1,
print0x0006},
{0x0007, "WhiteBalance", N_("White Balance"), N_("White balance settings"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioWhiteBalance)},
{0x000a, "DigitalZoom", N_("Digital Zoom"), N_("Digital zoom"), casioId, makerTags, unsignedLong, -1,
EXV_PRINT_TAG(casioDigitalZoom)},
{0x000b, "Sharpness", N_("Sharpness"), N_("Sharpness"), casioId, makerTags, unsignedShort, -1,
{0x0005, "FlashIntensity", N_("Flash Intensity"), N_("Flash Intensity"), IfdId::casioId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casioFlashIntensity)},
{0x0006, "ObjectDistance", N_("Object Distance"), N_("Distance to object"), IfdId::casioId, SectionId::makerTags,
unsignedLong, -1, print0x0006},
{0x0007, "WhiteBalance", N_("White Balance"), N_("White balance settings"), IfdId::casioId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casioWhiteBalance)},
{0x000a, "DigitalZoom", N_("Digital Zoom"), N_("Digital zoom"), IfdId::casioId, SectionId::makerTags, unsignedLong,
-1, EXV_PRINT_TAG(casioDigitalZoom)},
{0x000b, "Sharpness", N_("Sharpness"), N_("Sharpness"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioSharpness)},
{0x000c, "Contrast", N_("Contrast"), N_("Contrast"), casioId, makerTags, unsignedShort, -1,
{0x000c, "Contrast", N_("Contrast"), N_("Contrast"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioContrast)},
{0x000d, "Saturation", N_("Saturation"), N_("Saturation"), casioId, makerTags, unsignedShort, -1,
{0x000d, "Saturation", N_("Saturation"), N_("Saturation"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioSaturation)},
{0x0014, "ISO", N_("ISO"), N_("ISO"), casioId, makerTags, unsignedShort, -1, printValue},
{0x0015, "FirmwareDate", N_("Firmware date"), N_("Firmware date"), casioId, makerTags, asciiString, -1,
print0x0015},
{0x0016, "Enhancement", N_("Enhancement"), N_("Enhancement"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioEnhancement)},
{0x0017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioColorFilter)},
{0x0018, "AFPoint", N_("AF Point"), N_("AF Point"), casioId, makerTags, unsignedShort, -1, printValue},
{0x0019, "FlashIntensity2", N_("Flash Intensity"), N_("Flash Intensity"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioFlashIntensity2)},
{0x0020, "CCDSensitivity", N_("CCDSensitivity"), N_("CCDSensitivity"), casioId, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casioCCDSensitivity)},
{0x0e00, "PrintIM", N_("Print IM"), N_("PrintIM information"), casioId, makerTags, undefined, -1, printValue},
{0xffff, "(UnknownCasioMakerNoteTag)", "(UnknownCasioMakerNoteTag)", N_("Unknown CasioMakerNote tag"), casioId,
makerTags, asciiString, -1, printValue},
{0x0014, "ISO", N_("ISO"), N_("ISO"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1, printValue},
{0x0015, "FirmwareDate", N_("Firmware date"), N_("Firmware date"), IfdId::casioId, SectionId::makerTags,
asciiString, -1, print0x0015},
{0x0016, "Enhancement", N_("Enhancement"), N_("Enhancement"), IfdId::casioId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(casioEnhancement)},
{0x0017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), IfdId::casioId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(casioColorFilter)},
{0x0018, "AFPoint", N_("AF Point"), N_("AF Point"), IfdId::casioId, SectionId::makerTags, unsignedShort, -1,
printValue},
{0x0019, "FlashIntensity2", N_("Flash Intensity"), N_("Flash Intensity"), IfdId::casioId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casioFlashIntensity2)},
{0x0020, "CCDSensitivity", N_("CCDSensitivity"), N_("CCDSensitivity"), IfdId::casioId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casioCCDSensitivity)},
{0x0e00, "PrintIM", N_("Print IM"), N_("PrintIM information"), IfdId::casioId, SectionId::makerTags, undefined, -1,
printValue},
{0xffff, "(UnknownCasioMakerNoteTag)", "(UnknownCasioMakerNoteTag)", N_("Unknown CasioMakerNote tag"),
IfdId::casioId, SectionId::makerTags, asciiString, -1, printValue},
};
const TagInfo* CasioMakerNote::tagList() {
@ -146,11 +148,10 @@ std::ostream& CasioMakerNote::print0x0015(std::ostream& os, const Value& value,
if (numbers.size() >= 10) {
// year
long l = (numbers[0] - 48) * 10 + (numbers[1] - 48);
if (l < 70) {
if (l < 70)
l += 2000;
} else {
else
l += 1900;
};
os << l << ":";
// month, day, hour, minutes
os << numbers[2] << numbers[3] << ":" << numbers[4] << numbers[5] << " " << numbers[6] << numbers[7] << ":"
@ -158,10 +159,9 @@ std::ostream& CasioMakerNote::print0x0015(std::ostream& os, const Value& value,
// optional seconds
if (numbers.size() == 12) {
os << ":" << numbers[10] << numbers[11];
};
} else {
}
} else
os << value;
};
return os;
}
@ -273,98 +273,105 @@ constexpr TagDetails casio2VideoQuality[] = {
// Casio2 MakerNote Tag Info
constexpr TagInfo Casio2MakerNote::tagInfo_[] = {
{0x0002, "PreviewImageSize", N_("Preview Image Size"), N_("Preview Image Size"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x0003, "PreviewImageLength", N_("Preview Image Length"), N_("Preview Image Length"), casio2Id, makerTags,
unsignedLong, -1, printValue},
{0x0004, "PreviewImageStart", N_("Preview Image Start"), N_("Preview Image Start"), casio2Id, makerTags,
unsignedLong, -1, printValue},
{0x0008, "QualityMode", N_("Quality Mode"), N_("Quality Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2QualityMode)},
{0x0009, "ImageSize", N_("Image Size"), N_("Image Size"), casio2Id, makerTags, unsignedShort, -1,
{0x0002, "PreviewImageSize", N_("Preview Image Size"), N_("Preview Image Size"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x0003, "PreviewImageLength", N_("Preview Image Length"), N_("Preview Image Length"), IfdId::casio2Id,
SectionId::makerTags, unsignedLong, -1, printValue},
{0x0004, "PreviewImageStart", N_("Preview Image Start"), N_("Preview Image Start"), IfdId::casio2Id,
SectionId::makerTags, unsignedLong, -1, printValue},
{0x0008, "QualityMode", N_("Quality Mode"), N_("Quality Mode"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2QualityMode)},
{0x0009, "ImageSize", N_("Image Size"), N_("Image Size"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ImageSize)},
{0x000d, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), casio2Id, makerTags, unsignedShort, -1,
{0x000d, "FocusMode", N_("Focus Mode"), N_("Focus Mode"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2FocusMode)},
{0x0014, "ISOSpeed", N_("ISO Speed"), N_("ISO Speed"), casio2Id, makerTags, unsignedShort, -1,
{0x0014, "ISOSpeed", N_("ISO Speed"), N_("ISO Speed"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2IsoSpeed)},
{0x0019, "WhiteBalance", N_("White Balance"), N_("White Balance Setting"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2WhiteBalance)},
{0x001d, "FocalLength", N_("Focal Length"), N_("Focal Length"), casio2Id, makerTags, unsignedRational, -1,
printValue},
{0x001f, "Saturation", N_("Saturation"), N_("Saturation"), casio2Id, makerTags, unsignedShort, -1,
{0x0019, "WhiteBalance", N_("White Balance"), N_("White Balance Setting"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2WhiteBalance)},
{0x001d, "FocalLength", N_("Focal Length"), N_("Focal Length"), IfdId::casio2Id, SectionId::makerTags,
unsignedRational, -1, printValue},
{0x001f, "Saturation", N_("Saturation"), N_("Saturation"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Saturation)},
{0x0020, "Contrast", N_("Contrast"), N_("Contrast"), casio2Id, makerTags, unsignedShort, -1,
{0x0020, "Contrast", N_("Contrast"), N_("Contrast"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Contrast)},
{0x0021, "Sharpness", N_("Sharpness"), N_("Sharpness"), casio2Id, makerTags, unsignedShort, -1,
{0x0021, "Sharpness", N_("Sharpness"), N_("Sharpness"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Sharpness)},
{0x0e00, "PrintIM", N_("Print IM"), N_("PrintIM information"), casio2Id, makerTags, undefined, -1, printValue},
{0x2000, "PreviewImage", N_("Preview Image"), N_("Preview Image"), casio2Id, makerTags, undefined, -1, printValue},
{0x2001, "FirmwareDate", N_("Firmware Date"), N_("Firmware Date"), casio2Id, makerTags, asciiString, -1,
print0x2001},
{0x2011, "WhiteBalanceBias", N_("White Balance Bias"), N_("White Balance Bias"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x2012, "WhiteBalance2", N_("White Balance"), N_("White Balance Setting"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2WhiteBalance2)},
{0x2021, "AFPointPosition", N_("AF Point Position"), N_("AF Point Position"), casio2Id, makerTags, unsignedShort,
{0x0e00, "PrintIM", N_("Print IM"), N_("PrintIM information"), IfdId::casio2Id, SectionId::makerTags, undefined, -1,
printValue},
{0x2000, "PreviewImage", N_("Preview Image"), N_("Preview Image"), IfdId::casio2Id, SectionId::makerTags, undefined,
-1, printValue},
{0x2022, "ObjectDistance", N_("Object Distance"), N_("Object Distance"), casio2Id, makerTags, unsignedLong, -1,
print0x2022},
{0x2034, "FlashDistance", N_("Flash Distance"), N_("Flash Distance"), casio2Id, makerTags, unsignedShort, -1,
{0x2001, "FirmwareDate", N_("Firmware Date"), N_("Firmware Date"), IfdId::casio2Id, SectionId::makerTags,
asciiString, -1, print0x2001},
{0x2011, "WhiteBalanceBias", N_("White Balance Bias"), N_("White Balance Bias"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x2012, "WhiteBalance2", N_("White Balance"), N_("White Balance Setting"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2WhiteBalance2)},
{0x2021, "AFPointPosition", N_("AF Point Position"), N_("AF Point Position"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x2022, "ObjectDistance", N_("Object Distance"), N_("Object Distance"), IfdId::casio2Id, SectionId::makerTags,
unsignedLong, -1, print0x2022},
{0x2034, "FlashDistance", N_("Flash Distance"), N_("Flash Distance"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x2076, "SpecialEffectMode", N_("Special Effect Mode"), N_("Special Effect Mode"), IfdId::casio2Id,
SectionId::makerTags, unsignedByte, -1, printValue},
{0x2089, "FaceInfo", N_("Face Info"), N_("Face Info"), IfdId::casio2Id, SectionId::makerTags, undefined, -1,
printValue},
{0x2076, "SpecialEffectMode", N_("Special Effect Mode"), N_("Special Effect Mode"), casio2Id, makerTags,
{0x211c, "FacesDetected", N_("Faces detected"), N_("Faces detected"), IfdId::casio2Id, SectionId::makerTags,
unsignedByte, -1, printValue},
{0x2089, "FaceInfo", N_("Face Info"), N_("Face Info"), casio2Id, makerTags, undefined, -1, printValue},
{0x211c, "FacesDetected", N_("Faces detected"), N_("Faces detected"), casio2Id, makerTags, unsignedByte, -1,
printValue},
{0x3000, "RecordMode", N_("Record Mode"), N_("Record Mode"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3001, "ReleaseMode", N_("Release Mode"), N_("Release Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ReleaseMode)},
{0x3002, "Quality", N_("Quality"), N_("Quality"), casio2Id, makerTags, unsignedShort, -1,
{0x3000, "RecordMode", N_("Record Mode"), N_("Record Mode"), IfdId::casio2Id, SectionId::makerTags, unsignedShort,
-1, printValue},
{0x3001, "ReleaseMode", N_("Release Mode"), N_("Release Mode"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2ReleaseMode)},
{0x3002, "Quality", N_("Quality"), N_("Quality"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Quality)},
{0x3003, "FocusMode2", N_("Focus Mode2"), N_("Focus Mode2"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2FocusMode2)},
{0x3006, "HometownCity", N_("Home town city"), N_("Home town city"), casio2Id, makerTags, asciiString, -1,
printValue},
{0x3007, "BestShotMode", N_("Best Shot Mode"), N_("Best Shot Mode"), casio2Id, makerTags, unsignedShort, -1,
printValue},
{0x3008, "AutoISO", N_("Auto ISO"), N_("Auto ISO"), casio2Id, makerTags, unsignedShort, -1,
{0x3003, "FocusMode2", N_("Focus Mode2"), N_("Focus Mode2"), IfdId::casio2Id, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(casio2FocusMode2)},
{0x3006, "HometownCity", N_("Home town city"), N_("Home town city"), IfdId::casio2Id, SectionId::makerTags,
asciiString, -1, printValue},
{0x3007, "BestShotMode", N_("Best Shot Mode"), N_("Best Shot Mode"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x3008, "AutoISO", N_("Auto ISO"), N_("Auto ISO"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2AutoISO)},
{0x3009, "AFMode", N_("AF Mode"), N_("AF Mode"), casio2Id, makerTags, unsignedShort, -1,
{0x3009, "AFMode", N_("AF Mode"), N_("AF Mode"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2AFMode)},
{0x3011, "Sharpness2", N_("Sharpness"), N_("Sharpness"), casio2Id, makerTags, undefined, -1, printValue},
{0x3012, "Contrast2", N_("Contrast"), N_("Contrast"), casio2Id, makerTags, undefined, -1, printValue},
{0x3013, "Saturation2", N_("Saturation"), N_("Saturation"), casio2Id, makerTags, undefined, -1, printValue},
{0x3014, "ISO", N_("ISO"), N_("ISO"), casio2Id, makerTags, unsignedShort, -1, printValue},
{0x3015, "ColorMode", N_("Color Mode"), N_("Color Mode"), casio2Id, makerTags, unsignedShort, -1,
{0x3011, "Sharpness2", N_("Sharpness"), N_("Sharpness"), IfdId::casio2Id, SectionId::makerTags, undefined, -1,
printValue},
{0x3012, "Contrast2", N_("Contrast"), N_("Contrast"), IfdId::casio2Id, SectionId::makerTags, undefined, -1,
printValue},
{0x3013, "Saturation2", N_("Saturation"), N_("Saturation"), IfdId::casio2Id, SectionId::makerTags, undefined, -1,
printValue},
{0x3014, "ISO", N_("ISO"), N_("ISO"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1, printValue},
{0x3015, "ColorMode", N_("Color Mode"), N_("Color Mode"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ColorMode)},
{0x3016, "Enhancement", N_("Enhancement"), N_("Enhancement"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2Enhancement)},
{0x3017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ColorFilter)},
{0x301b, "ArtMode", N_("Art Mode"), N_("Art Mode"), casio2Id, makerTags, unsignedShort, -1,
{0x3016, "Enhancement", N_("Enhancement"), N_("Enhancement"), IfdId::casio2Id, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(casio2Enhancement)},
{0x3017, "ColorFilter", N_("Color Filter"), N_("Color Filter"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2ColorFilter)},
{0x301b, "ArtMode", N_("Art Mode"), N_("Art Mode"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2ArtMode)},
{0x301c, "SequenceNumber", N_("Sequence Number"), N_("Sequence Number"), casio2Id, makerTags, unsignedShort, -1,
printValue},
{0x3020, "ImageStabilization", N_("Image Stabilization"), N_("Image Stabilization"), casio2Id, makerTags,
unsignedShort, -1, printValue},
{0x302a, "LightingMode", N_("Lighting Mode"), N_("Lighting Mode"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2LightingMode)},
{0x302b, "PortraitRefiner", N_("Portrait Refiner"), N_("Portrait Refiner settings"), casio2Id, makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2PortraitRefiner)},
{0x3030, "SpecialEffectLevel", N_("Special Effect Level"), N_("Special Effect Level"), casio2Id, makerTags,
{0x301c, "SequenceNumber", N_("Sequence Number"), N_("Sequence Number"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x3031, "SpecialEffectSetting", N_("Special Effect Setting"), N_("Special Effect Setting"), casio2Id, makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2SpecialEffectSetting)},
{0x3103, "DriveMode", N_("Drive Mode"), N_("Drive Mode"), casio2Id, makerTags, unsignedShort, -1,
{0x3020, "ImageStabilization", N_("Image Stabilization"), N_("Image Stabilization"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x302a, "LightingMode", N_("Lighting Mode"), N_("Lighting Mode"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2LightingMode)},
{0x302b, "PortraitRefiner", N_("Portrait Refiner"), N_("Portrait Refiner settings"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2PortraitRefiner)},
{0x3030, "SpecialEffectLevel", N_("Special Effect Level"), N_("Special Effect Level"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x3031, "SpecialEffectSetting", N_("Special Effect Setting"), N_("Special Effect Setting"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(casio2SpecialEffectSetting)},
{0x3103, "DriveMode", N_("Drive Mode"), N_("Drive Mode"), IfdId::casio2Id, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2DriveMode)},
{0x310b, "ArtModeParameters", N_("Art Mode Parameters"), N_("Art Mode Parameters"), casio2Id, makerTags, undefined,
-1, printValue},
{0x4001, "CaptureFrameRate", N_("Capture Frame Rate"), N_("Capture Frame Rate"), casio2Id, makerTags, unsignedShort,
-1, printValue},
{0x4003, "VideoQuality", N_("Video Quality"), N_("Video Quality"), casio2Id, makerTags, unsignedShort, -1,
EXV_PRINT_TAG(casio2VideoQuality)},
{0xffff, "(UnknownCasio2MakerNoteTag)", "(UnknownCasio2MakerNoteTag)", N_("Unknown Casio2MakerNote tag"), casio2Id,
makerTags, asciiString, -1, printValue},
{0x310b, "ArtModeParameters", N_("Art Mode Parameters"), N_("Art Mode Parameters"), IfdId::casio2Id,
SectionId::makerTags, undefined, -1, printValue},
{0x4001, "CaptureFrameRate", N_("Capture Frame Rate"), N_("Capture Frame Rate"), IfdId::casio2Id,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x4003, "VideoQuality", N_("Video Quality"), N_("Video Quality"), IfdId::casio2Id, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(casio2VideoQuality)},
{0xffff, "(UnknownCasio2MakerNoteTag)", "(UnknownCasio2MakerNoteTag)", N_("Unknown Casio2MakerNote tag"),
IfdId::casio2Id, SectionId::makerTags, asciiString, -1, printValue},
};
const TagInfo* Casio2MakerNote::tagList() {
@ -384,18 +391,16 @@ std::ostream& Casio2MakerNote::print0x2001(std::ostream& os, const Value& value,
if (numbers.size() >= 10) {
// year
long l = (numbers[0] - 48) * 10 + (numbers[1] - 48);
if (l < 70) {
if (l < 70)
l += 2000;
} else {
else
l += 1900;
};
os << l << ":";
// month, day, hour, minutes
os << numbers[2] << numbers[3] << ":" << numbers[4] << numbers[5] << " " << numbers[6] << numbers[7] << ":"
<< numbers[8] << numbers[9];
} else {
} else
os << value;
};
return os;
}
@ -405,7 +410,7 @@ std::ostream& Casio2MakerNote::print0x2022(std::ostream& os, const Value& value,
os << N_("Inf");
os.flags(f);
return os;
};
}
std::ostringstream oss;
oss.copyfmt(os);
os << std::fixed << std::setprecision(2) << value.toInt64() / 1000.0 << _(" m");

@ -782,7 +782,7 @@ void Converter::cnvExifFlash(const char* from, const char* to) {
return;
if (!prepareXmpTarget(to))
return;
auto value = pos->toInt64();
auto value = pos->toUint32();
if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
@ -1052,7 +1052,7 @@ void Converter::cnvXmpFlash(const char* from, const char* to) {
unsigned short value = 0;
if (pos != xmpData_->end() && pos->count() > 0) {
auto fired = pos->toInt64();
auto fired = pos->toUint32();
if (pos->value().ok())
value |= fired & 1;
#ifndef SUPPRESS_WARNINGS
@ -1063,7 +1063,7 @@ void Converter::cnvXmpFlash(const char* from, const char* to) {
}
pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Return"));
if (pos != xmpData_->end() && pos->count() > 0) {
auto ret = pos->toInt64();
auto ret = pos->toUint32();
if (pos->value().ok())
value |= (ret & 3) << 1;
#ifndef SUPPRESS_WARNINGS
@ -1074,7 +1074,7 @@ void Converter::cnvXmpFlash(const char* from, const char* to) {
}
pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Mode"));
if (pos != xmpData_->end() && pos->count() > 0) {
auto mode = pos->toInt64();
auto mode = pos->toUint32();
if (pos->value().ok())
value |= (mode & 3) << 3;
#ifndef SUPPRESS_WARNINGS
@ -1085,7 +1085,7 @@ void Converter::cnvXmpFlash(const char* from, const char* to) {
}
pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Function"));
if (pos != xmpData_->end() && pos->count() > 0) {
auto function = pos->toInt64();
auto function = pos->toUint32();
if (pos->value().ok())
value |= (function & 1) << 5;
#ifndef SUPPRESS_WARNINGS
@ -1097,7 +1097,7 @@ void Converter::cnvXmpFlash(const char* from, const char* to) {
pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:RedEyeMode"));
if (pos != xmpData_->end()) {
if (pos->count() > 0) {
auto red = pos->toInt64();
auto red = pos->toUint32();
if (pos->value().ok())
value |= (red & 1) << 6;
#ifndef SUPPRESS_WARNINGS
@ -1284,7 +1284,7 @@ std::string Converter::computeExifDigest(bool tiff) {
}
#else
std::string Converter::computeExifDigest(bool) {
return std::string("");
return {};
}
#endif
@ -1584,7 +1584,7 @@ bool convertStringCharsetIconv(std::string& str, const char* from, const char* t
size_t outbytesleft = sizeof(outbuf);
size_t rc = iconv(cd, &inptr, &inbytesleft, &outptr, &outbytesleft);
const size_t outbytesProduced = sizeof(outbuf) - outbytesleft;
if (rc == size_t(-1) && errno != E2BIG) {
if (rc == static_cast<size_t>(-1) && errno != E2BIG) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "iconv: " << strError() << " inbytesleft = " << inbytesleft << "\n";
#endif

@ -52,7 +52,7 @@ DataBuf Cr2Header::write() const {
bool Cr2Header::isImageTag(uint16_t tag, IfdId group, const PrimaryGroups* /*pPrimaryGroups*/) const {
// CR2 image tags are all IFD2 and IFD3 tags
if (group == ifd2Id || group == ifd3Id)
if (group == IfdId::ifd2Id || group == IfdId::ifd3Id)
return true;
// ...and any (IFD0) tag that is in the TIFF image tags list
return isTiffImageTag(tag, group);

@ -49,7 +49,7 @@ void Cr2Image::printStructure(std::ostream& out, Exiv2::PrintStructureOption opt
printTiffStructure(io(), out, option, depth - 1);
}
void Cr2Image::setComment(std::string_view /*comment*/) {
void Cr2Image::setComment(const std::string&) {
// not supported
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "CR2"));
}
@ -81,15 +81,13 @@ void Cr2Image::writeMetadata() {
byte* pData = nullptr;
size_t size = 0;
IoCloser closer(*io_);
if (io_->open() == 0) {
// Ensure that this is the correct image type
if (isCr2Type(*io_, false)) {
pData = io_->mmap(true);
size = io_->size();
Internal::Cr2Header cr2Header;
if (0 == cr2Header.read(pData, 16)) {
bo = cr2Header.byteOrder();
}
// Ensure that this is the correct image type
if (io_->open() == 0 && isCr2Type(*io_, false)) {
pData = io_->mmap(true);
size = io_->size();
Internal::Cr2Header cr2Header;
if (0 == cr2Header.read(pData, 16)) {
bo = cr2Header.byteOrder();
}
}
if (bo == invalidByteOrder) {
@ -112,7 +110,7 @@ WriteMethod Cr2Parser::encode(BasicIo& io, const byte* pData, size_t size, ByteO
// Delete IFDs which do not occur in TIFF images
static constexpr auto filteredIfds = std::array{
Internal::panaRawId,
IfdId::panaRawId,
};
for (auto&& filteredIfd : filteredIfds) {
#ifdef EXIV2_DEBUG_MESSAGES

@ -93,7 +93,7 @@ void CrwImage::writeMetadata() {
// Write new buffer to file
MemIo tempIo;
tempIo.write((!blob.empty() ? &blob[0] : nullptr), blob.size());
tempIo.write((!blob.empty() ? blob.data() : nullptr), blob.size());
io_->close();
io_->transfer(tempIo); // may throw
@ -108,7 +108,7 @@ void CrwParser::decode(CrwImage* pCrwImage, const byte* pData, size_t size) {
// a hack to get absolute offset of preview image inside CRW structure
auto preview = header.findComponent(0x2007, 0x0000);
if (preview) {
(pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormat"] = uint32_t(preview->pData() - pData);
(pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormat"] = static_cast<uint32_t>(preview->pData() - pData);
(pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormatLength"] = static_cast<uint32_t>(preview->size());
}
} // CrwParser::decode

@ -78,31 +78,31 @@ namespace Exiv2::Internal {
const CrwMapping CrwMap::crwMapping_[] = {
// CrwTag CrwDir Size ExifTag IfdId decodeFct encodeFct
// ------ ------ ---- ------- ----- --------- ---------
CrwMapping(0x0805, 0x300a, 0, 0, canonId, decode0x0805, encode0x0805),
CrwMapping(0x080a, 0x2807, 0, 0, canonId, decode0x080a, encode0x080a),
CrwMapping(0x080b, 0x3004, 0, 0x0007, canonId, decodeBasic, encodeBasic),
CrwMapping(0x0810, 0x2807, 0, 0x0009, canonId, decodeBasic, encodeBasic),
CrwMapping(0x0815, 0x2804, 0, 0x0006, canonId, decodeBasic, encodeBasic),
CrwMapping(0x1029, 0x300b, 0, 0x0002, canonId, decodeBasic, encodeBasic),
CrwMapping(0x102a, 0x300b, 0, 0x0004, canonId, decodeArray, encodeArray),
CrwMapping(0x102d, 0x300b, 0, 0x0001, canonId, decodeArray, encodeArray),
CrwMapping(0x1033, 0x300b, 0, 0x000f, canonId, decodeArray, encodeArray),
CrwMapping(0x1038, 0x300b, 0, 0x0012, canonId, decodeArray, encodeArray),
CrwMapping(0x10a9, 0x300b, 0, 0x00a9, canonId, decodeBasic, encodeBasic),
CrwMapping(0x0805, 0x300a, 0, 0, IfdId::canonId, decode0x0805, encode0x0805),
CrwMapping(0x080a, 0x2807, 0, 0, IfdId::canonId, decode0x080a, encode0x080a),
CrwMapping(0x080b, 0x3004, 0, 0x0007, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x0810, 0x2807, 0, 0x0009, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x0815, 0x2804, 0, 0x0006, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x1029, 0x300b, 0, 0x0002, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x102a, 0x300b, 0, 0x0004, IfdId::canonId, decodeArray, encodeArray),
CrwMapping(0x102d, 0x300b, 0, 0x0001, IfdId::canonId, decodeArray, encodeArray),
CrwMapping(0x1033, 0x300b, 0, 0x000f, IfdId::canonId, decodeArray, encodeArray),
CrwMapping(0x1038, 0x300b, 0, 0x0012, IfdId::canonId, decodeArray, encodeArray),
CrwMapping(0x10a9, 0x300b, 0, 0x00a9, IfdId::canonId, decodeBasic, encodeBasic),
// Mapped to Exif.Photo.ColorSpace instead (see below)
// CrwMapping(0x10b4, 0x300b, 0, 0x00b4, canonId, decodeBasic, encodeBasic),
CrwMapping(0x10b4, 0x300b, 0, 0xa001, exifId, decodeBasic, encodeBasic),
CrwMapping(0x10b5, 0x300b, 0, 0x00b5, canonId, decodeBasic, encodeBasic),
CrwMapping(0x10c0, 0x300b, 0, 0x00c0, canonId, decodeBasic, encodeBasic),
CrwMapping(0x10c1, 0x300b, 0, 0x00c1, canonId, decodeBasic, encodeBasic),
CrwMapping(0x1807, 0x3002, 0, 0x9206, exifId, decodeBasic, encodeBasic),
CrwMapping(0x180b, 0x3004, 0, 0x000c, canonId, decodeBasic, encodeBasic),
CrwMapping(0x180e, 0x300a, 0, 0x9003, exifId, decode0x180e, encode0x180e),
CrwMapping(0x1810, 0x300a, 0, 0xa002, exifId, decode0x1810, encode0x1810),
CrwMapping(0x1817, 0x300a, 4, 0x0008, canonId, decodeBasic, encodeBasic),
// CrwMapping(0x1818, 0x3002, 0, 0x9204, exifId, decodeBasic, encodeBasic),
CrwMapping(0x183b, 0x300b, 0, 0x0015, canonId, decodeBasic, encodeBasic),
CrwMapping(0x2008, 0x0000, 0, 0, ifd1Id, decode0x2008, encode0x2008),
// CrwMapping(0x10b4, 0x300b, 0, 0x00b4, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x10b4, 0x300b, 0, 0xa001, IfdId::exifId, decodeBasic, encodeBasic),
CrwMapping(0x10b5, 0x300b, 0, 0x00b5, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x10c0, 0x300b, 0, 0x00c0, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x10c1, 0x300b, 0, 0x00c1, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x1807, 0x3002, 0, 0x9206, IfdId::exifId, decodeBasic, encodeBasic),
CrwMapping(0x180b, 0x3004, 0, 0x000c, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x180e, 0x300a, 0, 0x9003, IfdId::exifId, decode0x180e, encode0x180e),
CrwMapping(0x1810, 0x300a, 0, 0xa002, IfdId::exifId, decode0x1810, encode0x1810),
CrwMapping(0x1817, 0x300a, 4, 0x0008, IfdId::canonId, decodeBasic, encodeBasic),
// CrwMapping(0x1818, 0x3002, 0, 0x9204, IfdId::exifId, decodeBasic, encodeBasic),
CrwMapping(0x183b, 0x300b, 0, 0x0015, IfdId::canonId, decodeBasic, encodeBasic),
CrwMapping(0x2008, 0x0000, 0, 0, IfdId::ifd1Id, decode0x2008, encode0x2008),
}; // CrwMap::crwMapping_[]
/*
@ -246,15 +246,11 @@ void CiffDirectory::readDirectory(const byte* pData, size_t size, ByteOrder byte
for (uint16_t i = 0; i < count; ++i) {
uint16_t tag = getUShort(pData + o, byteOrder);
std::unique_ptr<CiffComponent> m;
switch (CiffComponent::typeId(tag)) {
case directory:
m = std::make_unique<CiffDirectory>();
break;
default:
m = std::make_unique<CiffEntry>();
break;
}
auto m = [this, tag]() -> std::unique_ptr<CiffComponent> {
if (this->typeId(tag) == TypeId::directory)
return std::make_unique<CiffDirectory>();
return std::make_unique<CiffEntry>();
}();
m->setDir(this->tag());
m->read(pData, size, o, byteOrder);
add(std::move(m));
@ -550,18 +546,16 @@ CiffComponent* CiffDirectory::doAdd(CrwDirs& crwDirs, uint16_t crwTagId) {
set value
*/
if (!crwDirs.empty()) {
auto [dir, parent] = crwDirs.top();
auto dir = crwDirs.top();
crwDirs.pop();
// Find the directory
for (auto&& component : components_) {
if (component->tag() == dir) {
cc_ = component;
break;
}
}
auto it =
std::find_if(components_.begin(), components_.end(), [=](const auto& c) { return c->tag() == dir.first; });
if (it != components_.end())
cc_ = *it;
if (!cc_) {
// Directory doesn't exist yet, add it
m_ = std::make_unique<CiffDirectory>(dir, parent);
m_ = std::make_unique<CiffDirectory>(dir.first, dir.second);
cc_ = m_.get();
add(std::move(m_));
}
@ -569,12 +563,10 @@ CiffComponent* CiffDirectory::doAdd(CrwDirs& crwDirs, uint16_t crwTagId) {
cc_ = cc_->add(crwDirs, crwTagId);
} else {
// Find the tag
for (auto&& component : components_) {
if (component->tagId() == crwTagId) {
cc_ = component;
break;
}
}
auto it =
std::find_if(components_.begin(), components_.end(), [=](const auto& c) { return c->tagId() == crwTagId; });
if (it != components_.end())
cc_ = *it;
if (!cc_) {
// Tag doesn't exist yet, add it
m_ = std::make_unique<CiffEntry>(crwTagId, tag());
@ -604,27 +596,23 @@ void CiffComponent::doRemove(CrwDirs& /*crwDirs*/, uint16_t /*crwTagId*/) {
void CiffDirectory::doRemove(CrwDirs& crwDirs, uint16_t crwTagId) {
if (!crwDirs.empty()) {
auto [dir, _] = crwDirs.top();
auto dir = crwDirs.top();
crwDirs.pop();
// Find the directory
for (auto i = components_.begin(); i != components_.end(); ++i) {
if ((*i)->tag() == dir) {
// Recursive call to next lower level directory
(*i)->remove(crwDirs, crwTagId);
if ((*i)->empty())
components_.erase(i);
break;
}
auto it =
std::find_if(components_.begin(), components_.end(), [=](const auto& c) { return c->tag() == dir.first; });
if (it != components_.end()) {
// Recursive call to next lower level directory
(*it)->remove(crwDirs, crwTagId);
if ((*it)->empty())
components_.erase(it);
}
} else {
// Find the tag
for (auto i = components_.begin(); i != components_.end(); ++i) {
if ((*i)->tagId() == crwTagId) {
// Remove the entry and abort the loop
delete *i;
components_.erase(i);
break;
}
auto it = std::find_if(components_.begin(), components_.end(), [=](const auto& c) { return c->tag() == crwTagId; });
if (it != components_.end()) {
delete *it;
components_.erase(it);
}
}
} // CiffDirectory::doRemove
@ -698,19 +686,19 @@ void CrwMap::decodeArray(const CiffComponent& ciffComponent, const CrwMapping* p
int64_t aperture = 0;
int64_t shutterSpeed = 0;
IfdId ifdId = ifdIdNotSet;
IfdId ifdId = IfdId::ifdIdNotSet;
switch (pCrwMapping->tag_) {
case 0x0001:
ifdId = canonCsId;
ifdId = IfdId::canonCsId;
break;
case 0x0004:
ifdId = canonSiId;
ifdId = IfdId::canonSiId;
break;
case 0x000f:
ifdId = canonCfId;
ifdId = IfdId::canonCfId;
break;
case 0x0012:
ifdId = canonPiId;
ifdId = IfdId::canonPiId;
break;
}
@ -725,18 +713,18 @@ void CrwMap::decodeArray(const CiffComponent& ciffComponent, const CrwMapping* p
uint16_t n = 1;
ExifKey key(c, groupName);
UShortValue value;
if (ifdId == canonCsId && c == 23 && component_size >= 52)
if (ifdId == IfdId::canonCsId && c == 23 && component_size >= 52)
n = 3;
value.read(ciffComponent.pData() + c * 2, n * 2, byteOrder);
image.exifData().add(key, &value);
if (ifdId == canonSiId && c == 21)
if (ifdId == IfdId::canonSiId && c == 21)
aperture = value.toInt64();
if (ifdId == canonSiId && c == 22)
if (ifdId == IfdId::canonSiId && c == 22)
shutterSpeed = value.toInt64();
c += n;
}
if (ifdId == canonSiId) {
if (ifdId == IfdId::canonSiId) {
// Exif.Photo.FNumber
float f = fnumber(canonEv(aperture));
auto [r, s] = floatToRationalCast(f);
@ -761,7 +749,7 @@ void CrwMap::decode0x180e(const CiffComponent& ciffComponent, const CrwMapping*
ULongValue v;
v.read(ciffComponent.pData(), 8, byteOrder);
time_t t = v.value_.at(0);
struct tm* tm = std::localtime(&t);
auto tm = std::localtime(&t);
if (tm) {
const size_t m = 20;
char s[m];
@ -912,19 +900,19 @@ void CrwMap::encode0x080a(const Image& image, const CrwMapping* pCrwMapping, Cif
}
void CrwMap::encodeArray(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead) {
IfdId ifdId = ifdIdNotSet;
IfdId ifdId = IfdId::ifdIdNotSet;
switch (pCrwMapping->tag_) {
case 0x0001:
ifdId = canonCsId;
ifdId = IfdId::canonCsId;
break;
case 0x0004:
ifdId = canonSiId;
ifdId = IfdId::canonSiId;
break;
case 0x000f:
ifdId = canonCfId;
ifdId = IfdId::canonCfId;
break;
case 0x0012:
ifdId = canonPiId;
ifdId = IfdId::canonPiId;
break;
}
DataBuf buf = packIfdId(image.exifData(), ifdId, pHead->byteOrder());
@ -970,7 +958,7 @@ void CrwMap::encode0x1810(const Image& image, const CrwMapping* pCrwMapping, Cif
const auto edO = exivData.findKey(kO);
const auto edEnd = exivData.end();
CiffComponent* cc = pHead->findComponent(pCrwMapping->crwTagId_, pCrwMapping->crwDir_);
auto cc = pHead->findComponent(pCrwMapping->crwTagId_, pCrwMapping->crwDir_);
if (edX != edEnd || edY != edEnd || edO != edEnd) {
size_t size = 28;
if (cc) {

@ -60,6 +60,8 @@ class CiffComponent {
//! Constructor taking a tag and directory
CiffComponent(uint16_t tag, uint16_t dir) : dir_(dir), tag_(tag) {
}
CiffComponent(const CiffComponent&) = delete;
CiffComponent& operator=(const CiffComponent&) = delete;
//! Virtual destructor.
virtual ~CiffComponent() = default;
//@}
@ -330,6 +332,9 @@ class CiffDirectory : public CiffComponent {
~CiffDirectory() override;
//@}
CiffDirectory(const CiffDirectory&) = delete;
CiffDirectory& operator=(const CiffDirectory&) = delete;
//! @name Manipulators
//@{
// Default assignment operator is fine
@ -493,8 +498,8 @@ struct CrwMapping {
//! @name Creators
//@{
//! Default constructor
CrwMapping(uint16_t crwTagId, uint16_t crwDir, uint32_t size, uint16_t tag, Internal::IfdId ifdId,
CrwDecodeFct toExif, CrwEncodeFct fromExif) :
CrwMapping(uint16_t crwTagId, uint16_t crwDir, uint32_t size, uint16_t tag, IfdId ifdId, CrwDecodeFct toExif,
CrwEncodeFct fromExif) :
crwTagId_(crwTagId),
crwDir_(crwDir),
size_(size),
@ -522,6 +527,7 @@ struct CrwMapping {
*/
class CrwMap {
public:
~CrwMap() = delete;
//! @name Not implemented
//@{
CrwMap(const CrwMap&) = delete;

@ -531,6 +531,10 @@ std::string IptcKey::tagLabel() const {
return IptcDataSets::dataSetTitle(tag_, record_);
}
std::string IptcKey::tagDesc() const {
return IptcDataSets::dataSetDesc(tag_, record_);
}
uint16_t IptcKey::tag() const {
return tag_;
}

@ -11,6 +11,7 @@
#include "config.h"
#include "basicio.hpp"
#include "enforce.hpp"
#include "epsimage.hpp"
#include "error.hpp"
#include "futils.hpp"
@ -101,13 +102,8 @@ void writeTemp(BasicIo& tempIo, const std::string& data) {
//! Get the current write position of temp file, taking care of errors
uint32_t posTemp(const BasicIo& tempIo) {
const long pos = tempIo.tell();
if (pos == -1) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Internal error while determining current write position in temporary file.\n";
#endif
throw Error(ErrorCode::kerImageWriteFailed);
}
const size_t pos = tempIo.tell();
enforce(pos <= std::numeric_limits<uint32_t>::max(), ErrorCode::kerImageWriteFailed);
return static_cast<uint32_t>(pos);
}
@ -479,7 +475,7 @@ void readWriteEpsMetadata(BasicIo& io, std::string& xmpPacket, NativePreviewList
#endif
// implicit comments
if (line == "%%EOF" || line == "%begin_xml_code" ||
!(line.size() >= 2 && line[0] == '%' && '\x21' <= line[1] && line[1] <= '\x7e')) {
!(line.size() >= 2 && line.front() == '%' && '\x21' <= line[1] && line[1] <= '\x7e')) {
if (posEndComments == posEndEps) {
posEndComments = startPos;
#ifdef DEBUG
@ -496,20 +492,21 @@ void readWriteEpsMetadata(BasicIo& io, std::string& xmpPacket, NativePreviewList
#endif
}
if (posBeginPageSetup == posEndEps &&
(implicitPage || (posPage != posEndEps && !inRemovableEmbedding && !line.empty() && line[0] != '%'))) {
(implicitPage || (posPage != posEndEps && !inRemovableEmbedding && !line.empty() && line.front() != '%'))) {
posBeginPageSetup = startPos;
implicitPageSetup = true;
#ifdef DEBUG
EXV_DEBUG << "readWriteEpsMetadata: Found implicit BeginPageSetup at position: " << startPos << "\n";
#endif
}
if (posEndPageSetup == posEndEps && implicitPageSetup && !inRemovableEmbedding && !line.empty() && line[0] != '%') {
if (posEndPageSetup == posEndEps && implicitPageSetup && !inRemovableEmbedding && !line.empty() &&
line.front() != '%') {
posEndPageSetup = startPos;
#ifdef DEBUG
EXV_DEBUG << "readWriteEpsMetadata: Found implicit EndPageSetup at position: " << startPos << "\n";
#endif
}
if (!line.empty() && line[0] != '%')
if (!line.empty() && line.front() != '%')
continue; // performance optimization
if (line == "%%EOF" || line == "%%Trailer" || line == "%%PageTrailer") {
if (posBeginPageSetup == posEndEps) {
@ -1103,7 +1100,7 @@ std::string EpsImage::mimeType() const {
return "application/postscript";
}
void EpsImage::setComment(std::string_view /*comment*/) {
void EpsImage::setComment(const std::string&) {
throw Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "EPS");
}
@ -1167,7 +1164,7 @@ bool isEpsType(BasicIo& iIo, bool advance) {
bufSize = i.size();
}
}
const long restore = iIo.tell(); // save
const size_t restore = iIo.tell(); // save
DataBuf buf = iIo.read(bufSize);
if (iIo.error() || buf.size() != bufSize) {
iIo.seek(restore, BasicIo::beg);

@ -128,7 +128,7 @@ class JpegThumbnail : public Thumbnail {
int64_t sumToLong(const Exiv2::Exifdatum& md);
//! Helper function to delete all tags of a specific IFD from the metadata.
void eraseIfd(Exiv2::ExifData& ed, Exiv2::Internal::IfdId ifdId);
void eraseIfd(Exiv2::ExifData& ed, Exiv2::IfdId ifdId);
} // namespace
@ -292,16 +292,20 @@ std::string Exifdatum::tagLabel() const {
return key_ ? key_->tagLabel() : "";
}
std::string Exifdatum::tagDesc() const {
return key_ ? key_->tagDesc() : "";
}
uint16_t Exifdatum::tag() const {
return key_ ? key_->tag() : 0xffff;
}
int Exifdatum::ifdId() const {
return key_ ? key_->ifdId() : ifdIdNotSet;
IfdId Exifdatum::ifdId() const {
return key_ ? key_->ifdId() : IfdId::ifdIdNotSet;
}
const char* Exifdatum::ifdName() const {
return key_ ? Internal::ifdName(Internal::IfdId(key_->ifdId())) : "";
return key_ ? Internal::ifdName(static_cast<IfdId>(key_->ifdId())) : "";
}
int Exifdatum::idx() const {
@ -422,15 +426,15 @@ void ExifThumb::setJpegThumbnail(const std::string& path) {
}
void ExifThumb::setJpegThumbnail(const byte* buf, size_t size) {
exifData_["Exif.Thumbnail.Compression"] = uint16_t(6);
exifData_["Exif.Thumbnail.Compression"] = static_cast<uint16_t>(6);
Exifdatum& format = exifData_["Exif.Thumbnail.JPEGInterchangeFormat"];
format = uint32_t(0);
format = static_cast<uint32_t>(0);
format.setDataArea(buf, size);
exifData_["Exif.Thumbnail.JPEGInterchangeFormatLength"] = uint32_t(size);
exifData_["Exif.Thumbnail.JPEGInterchangeFormatLength"] = static_cast<uint32_t>(size);
}
void ExifThumb::erase() {
eraseIfd(exifData_, ifd1Id);
eraseIfd(exifData_, IfdId::ifd1Id);
}
Exifdatum& ExifData::operator[](const std::string& key) {
@ -544,8 +548,9 @@ WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteO
// Delete IFDs which do not occur in JPEGs
static constexpr auto filteredIfds = std::array{
subImage1Id, subImage2Id, subImage3Id, subImage4Id, subImage5Id, subImage6Id, subImage7Id,
subImage8Id, subImage9Id, subThumb1Id, panaRawId, ifd2Id, ifd3Id,
IfdId::subImage1Id, IfdId::subImage2Id, IfdId::subImage3Id, IfdId::subImage4Id, IfdId::subImage5Id,
IfdId::subImage6Id, IfdId::subImage7Id, IfdId::subImage8Id, IfdId::subImage9Id, IfdId::subThumb1Id,
IfdId::panaRawId, IfdId::ifd2Id, IfdId::ifd3Id,
};
for (auto&& filteredIfd : filteredIfds) {
#ifdef EXIV2_DEBUG_MESSAGES
@ -676,26 +681,22 @@ WriteMethod ExifParser::encode(Blob& blob, const byte* pData, size_t size, ByteO
namespace {
//! @cond IGNORE
Thumbnail::UniquePtr Thumbnail::create(const Exiv2::ExifData& exifData) {
std::unique_ptr<Thumbnail> thumbnail;
const Exiv2::ExifKey k1("Exif.Thumbnail.Compression");
auto pos = exifData.findKey(k1);
if (pos != exifData.end()) {
if (pos->count() == 0)
return thumbnail;
return nullptr;
auto compression = pos->toInt64();
if (compression == 6) {
thumbnail = std::make_unique<JpegThumbnail>();
} else {
thumbnail = std::make_unique<TiffThumbnail>();
}
} else {
const Exiv2::ExifKey k2("Exif.Thumbnail.JPEGInterchangeFormat");
pos = exifData.findKey(k2);
if (pos != exifData.end()) {
thumbnail = std::make_unique<JpegThumbnail>();
}
if (compression == 6)
return std::make_unique<JpegThumbnail>();
return std::make_unique<TiffThumbnail>();
}
return thumbnail;
const Exiv2::ExifKey k2("Exif.Thumbnail.JPEGInterchangeFormat");
pos = exifData.findKey(k2);
if (pos != exifData.end())
return std::make_unique<JpegThumbnail>();
return nullptr;
}
const char* TiffThumbnail::mimeType() const {

@ -365,191 +365,272 @@ std::ostream& printFujiFaceElementTypes(std::ostream& os, const Value& value, co
// Fujifilm MakerNote Tag Info
constexpr TagInfo FujiMakerNote::tagInfo_[] = {
{0x0000, "Version", N_("Version"), N_("Fujifilm Makernote version"), fujiId, makerTags, undefined, -1, printValue},
{0x0000, "Version", N_("Version"), N_("Fujifilm Makernote version"), IfdId::fujiId, SectionId::makerTags, undefined,
-1, printValue},
{0x0010, "SerialNumber", N_("Serial Number"),
N_("This number is unique, and contains the date of manufacture, "
"but is not the same as the number printed on the camera body."),
fujiId, makerTags, asciiString, -1, printValue},
{0x1000, "Quality", N_("Quality"), N_("Image quality setting"), fujiId, makerTags, asciiString, -1, printValue},
{0x1001, N_("Sharpness"), N_("Sharpness"), N_("Sharpness setting"), fujiId, makerTags, unsignedShort, -1,
IfdId::fujiId, SectionId::makerTags, asciiString, -1, printValue},
{0x1000, "Quality", N_("Quality"), N_("Image quality setting"), IfdId::fujiId, SectionId::makerTags, asciiString, -1, printValue},
{0x1001, N_("Sharpness"), N_("Sharpness"), N_("Sharpness setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiSharpness)},
{0x1002, "WhiteBalance", N_("White Balance"), N_("White balance setting"), fujiId, makerTags, unsignedShort, -1,
{0x1002, "WhiteBalance", N_("White Balance"), N_("White balance setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiWhiteBalance)},
{0x1003, "Color", N_("Color"), N_("Chroma saturation setting"), fujiId, makerTags, unsignedShort, -1,
{0x1003, "Color", N_("Color"), N_("Chroma saturation setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiColor)},
{0x1004, "Tone", N_("Tone"), N_("Tone (contrast) setting"), fujiId, makerTags, unsignedShort, -1,
{0x1004, "Tone", N_("Tone"), N_("Tone (contrast) setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiTone)},
{0x1005, "ColorTemperature", N_("Color Temperature"), N_("Color temperature setting"), fujiId, makerTags,
{0x1005, "ColorTemperature", N_("Color Temperature"), N_("Color temperature setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x1006, "Contrast", N_("Contrast"), N_("Contrast setting"), fujiId, makerTags, unsignedShort, -1,
{0x1006, "Contrast", N_("Contrast"), N_("Contrast setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiContrast)},
{0x100a, "WhiteBalanceFineTune", N_("White Balance Fine Tune"), N_("White balance fine tune setting"), fujiId,
makerTags, signedLong, -1, printFujiWhiteBalanceFineTune},
{0x100b, "NoiseReduction", N_("Noise Reduction"), N_("Noise reduction setting"), fujiId, makerTags, unsignedShort,
{0x100a, "WhiteBalanceFineTune", N_("White Balance Fine Tune"), N_("White balance fine tune setting"), IfdId::fujiId,
SectionId::makerTags, signedLong, -1, printFujiWhiteBalanceFineTune},
{0x100b, "NoiseReduction", N_("Noise Reduction"), N_("Noise reduction setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(fujiNoiseReduction)},
{0x100e, "HighIsoNoiseReduction", N_("High ISO Noise Reduction"), N_("High ISO NR setting"), fujiId, makerTags,
{0x100e, "HighIsoNoiseReduction", N_("High ISO Noise Reduction"), N_("High ISO NR setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiHighIsoNR)},
{0x100f, "Clarity", N_("Clarity"), N_("Clarity setting"), fujiId, makerTags, signedLong, -1,
{0x100f, "Clarity", N_("Clarity"), N_("Clarity setting"), IfdId::fujiId, SectionId::makerTags, signedLong, -1,
EXV_PRINT_TAG(fujiClarity)},
{0x1010, "FlashMode", N_("Flash Mode"), N_("Flash firing mode setting"), fujiId, makerTags, unsignedShort, -1,
{0x1010, "FlashMode", N_("Flash Mode"), N_("Flash firing mode setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiFlashMode)},
{0x1011, "FlashStrength", N_("Flash Strength"), N_("Flash firing strength compensation setting"), fujiId, makerTags,
{0x1011, "FlashStrength", N_("Flash Strength"), N_("Flash firing strength compensation setting"), IfdId::fujiId, SectionId::makerTags,
signedRational, -1, printValue},
{0x1020, "Macro", N_("Macro"), N_("Macro mode setting"), fujiId, makerTags, unsignedShort, -1,
{0x1020, "Macro", N_("Macro"), N_("Macro mode setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiOffOn)},
{0x1021, "FocusMode", N_("Focus Mode"), N_("Focusing mode setting"), fujiId, makerTags, unsignedShort, -1,
{0x1021, "FocusMode", N_("Focus Mode"), N_("Focusing mode setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiFocusMode)},
{0x1022, "FocusArea", "Focus Area", N_("Focus area setting"), fujiId, makerTags, unsignedShort, -1,
{0x1022, "FocusArea", "Focus Area", N_("Focus area setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiFocusArea)},
{0x1023, "FocusPoint", N_("Focus Point"), N_("X and Y coordinate of focus point"), fujiId, makerTags, unsignedShort,
{0x1023, "FocusPoint", N_("Focus Point"), N_("X and Y coordinate of focus point"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, printValue},
{0x102b, "FocusPrioritySetting", N_("Focus Priority Setting"), N_("Focus priority setting"), fujiId, makerTags,
{0x102b, "FocusPrioritySetting", N_("Focus Priority Setting"), N_("Focus priority setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x102d, "FocusSetting", N_("Focus Setting"), N_("Focus setting"), fujiId, makerTags, unsignedLong, -1, printValue},
{0x102e, "ContinuousFocusSetting", N_("AF-C Focus Setting"), N_("AF-C focus setting"), fujiId, makerTags,
{0x102d, "FocusSetting", N_("Focus Setting"), N_("Focus setting"), IfdId::fujiId, SectionId::makerTags, unsignedLong, -1, printValue},
{0x102e, "ContinuousFocusSetting", N_("AF-C Focus Setting"), N_("AF-C focus setting"), IfdId::fujiId, SectionId::makerTags,
unsignedLong, -1, printValue},
{0x1030, "SlowSync", N_("Slow Sync"), N_("Slow synchro mode setting"), fujiId, makerTags, unsignedShort, -1,
{0x1030, "SlowSync", N_("Slow Sync"), N_("Slow synchro mode setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiOffOn)},
{0x1031, "PictureMode", N_("Picture Mode"), N_("Picture mode setting"), fujiId, makerTags, unsignedShort, -1,
{0x1031, "PictureMode", N_("Picture Mode"), N_("Picture mode setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiPictureMode)},
{0x1032, "ExposureCount", "Exposure Count", N_("Number of exposures used for this image"), fujiId, makerTags,
{0x1032, "ExposureCount", "Exposure Count", N_("Number of exposures used for this image"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x1033, "EXRAuto", "EXR Auto",
N_("EXR Auto"), // TODO find description
fujiId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1034, "EXRMode", "EXR Mode",
N_("EXR Auto"), // TODO find description
fujiId, makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiExrMode)},
{0x1040, "ShadowTone", N_("Shadow Tone"), N_("Shadow tone"), fujiId, makerTags, signedLong, -1,
IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiExrMode)},
{0x1040, "ShadowTone", N_("Shadow Tone"), N_("Shadow tone"), IfdId::fujiId, SectionId::makerTags, signedLong, -1,
EXV_PRINT_TAG(fujiSHTone)},
{0x1041, "HighlightTone", N_("Highlight Tone"), N_("Highlight tone"), fujiId, makerTags, signedLong, -1,
{0x1041, "HighlightTone", N_("Highlight Tone"), N_("Highlight tone"), IfdId::fujiId, SectionId::makerTags, signedLong, -1,
EXV_PRINT_TAG(fujiSHTone)},
{0x1044, "DigitalZoom", N_("Digital Zoom"), N_("Digital zoom"), fujiId, makerTags, unsignedLong, -1,
{0x1044, "DigitalZoom", N_("Digital Zoom"), N_("Digital zoom"), IfdId::fujiId, SectionId::makerTags, unsignedLong, -1,
printFujiDigitalZoom},
{0x1045, "LensModulationOptimizer", N_("Lens Modulation Optimizer"), N_("Lens modulation optimizer setting"),
fujiId, makerTags, unsignedLong, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1047, "GrainEffectRoughness", N_("Grain Effect Roughness"), N_("Grain effect roughness setting"), fujiId,
makerTags, signedLong, -1, EXV_PRINT_TAG(fujiOff0Weak32Strong64)},
{0x1048, "ColorChromeEffect", N_("Color Chrome Effect"), N_("Color Chrome Effect"), fujiId, makerTags, signedLong,
IfdId::fujiId, SectionId::makerTags, unsignedLong, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1047, "GrainEffectRoughness", N_("Grain Effect Roughness"), N_("Grain effect roughness setting"), IfdId::fujiId,
SectionId::makerTags, signedLong, -1, EXV_PRINT_TAG(fujiOff0Weak32Strong64)},
{0x1048, "ColorChromeEffect", N_("Color Chrome Effect"), N_("Color Chrome Effect"), IfdId::fujiId, SectionId::makerTags, signedLong,
-1, EXV_PRINT_TAG(fujiOff0Weak32Strong64)},
{0x1049, "MonochromaticColorWC", N_("Monochromatic Color (Warm-Cool)"),
N_("Monochromatic color (warm-cool) setting. High value results in warm color shift and low values in cold color "
"shift."),
fujiId, makerTags, unsignedByte, -1, printFujiMonochromaticColor},
IfdId::fujiId, SectionId::makerTags, unsignedByte, -1, printFujiMonochromaticColor},
{0x104b, "MonochromaticColorMG", N_("Monochromatic Color (Magenta-Green)"),
N_("Monochromatic color (magenta-green) setting. High value results in magenta color shift and low values in "
"green color shift."),
fujiId, makerTags, unsignedByte, -1, printFujiMonochromaticColor},
{0x104c, "GrainEffectSize", N_("Grain Effect Size"), N_("Grain effect size setting"), fujiId, makerTags,
IfdId::fujiId, SectionId::makerTags, unsignedByte, -1, printFujiMonochromaticColor},
{0x104c, "GrainEffectSize", N_("Grain Effect Size"), N_("Grain effect size setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiOff0Weak32Strong64)},
{0x104d, "CropMode", N_("Crop Mode"), N_("Crop mode"), fujiId, makerTags, unsignedShort, -1,
{0x104d, "CropMode", N_("Crop Mode"), N_("Crop mode"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiCropMode)},
{0x104e, "ColorChromeFXBlue", N_("Color Chrome FX Blue"), N_("Color Chrome FX Blue"), fujiId, makerTags, signedLong,
{0x104e, "ColorChromeFXBlue", N_("Color Chrome FX Blue"), N_("Color Chrome FX Blue"), IfdId::fujiId, SectionId::makerTags, signedLong,
-1, EXV_PRINT_TAG(fujiOff0Weak32Strong64)},
{0x1050, "ShutterType", N_("Shutter Type"), N_("Shutter type"), fujiId, makerTags, unsignedShort, -1,
{0x1050, "ShutterType", N_("Shutter Type"), N_("Shutter type"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiShutterType)},
{0x1100, "Continuous", N_("Continuous"), N_("Continuous shooting or auto bracketing setting"), fujiId, makerTags,
{0x1100, "Continuous", N_("Continuous"), N_("Continuous shooting or auto bracketing setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiContinuous)},
{0x1101, "SequenceNumber", N_("Sequence Number"), N_("Sequence number"), fujiId, makerTags, unsignedShort, -1,
{0x1101, "SequenceNumber", N_("Sequence Number"), N_("Sequence number"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
printValue},
{0x1103, "DriveSetting", N_("Drive Setting"), N_("Drive setting"), fujiId, makerTags, unsignedShort, -1,
{0x1103, "DriveSetting", N_("Drive Setting"), N_("Drive setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
printFujiDriveSetting},
{0x1105, "PixelShiftShots", N_("Pixel Shift Shots"), N_("Pixel shift shots"), fujiId, makerTags, unsignedShort, -1,
{0x1105, "PixelShiftShots", N_("Pixel Shift Shots"), N_("Pixel shift shots"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
printValue},
{0x1105, "PixelShiftOfffset", N_("Pixel Shift Offset"), N_("Pixel shift offset"), fujiId, makerTags, signedRational,
{0x1105, "PixelShiftOfffset", N_("Pixel Shift Offset"), N_("Pixel shift offset"), IfdId::fujiId, SectionId::makerTags, signedRational,
-1, printValue},
{0x1153, "PanoramaAngle", N_("Panorama angle"), N_("Panorama angle"), fujiId, makerTags, unsignedShort, -1,
{0x1153, "PanoramaAngle", N_("Panorama angle"), N_("Panorama angle"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
printValue},
{0x1154, "PanoramaDirection", N_("Panorama direction"), N_("Panorama direction"), fujiId, makerTags, unsignedShort,
{0x1154, "PanoramaDirection", N_("Panorama direction"), N_("Panorama direction"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(fujiPanoramaDirection)},
{0x1200, "0x1200", "0x1200", N_("Unknown"), fujiId, makerTags, unsignedShort, -1, printValue},
{0x1201, "AdvancedFilter", N_("Advanced filter"), N_("Advanced filter setting"), fujiId, makerTags, unsignedLong,
{0x1200, "0x1200", "0x1200", N_("Unknown"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, printValue},
{0x1201, "AdvancedFilter", N_("Advanced filter"), N_("Advanced filter setting"), IfdId::fujiId, SectionId::makerTags, unsignedLong,
-1, EXV_PRINT_TAG(fujiAdvancedFilter)},
{0x1210, "FinePixColor", N_("FinePix Color"), N_("Fuji FinePix color setting"), fujiId, makerTags, unsignedShort,
{0x1210, "FinePixColor", N_("FinePix Color"), N_("Fuji FinePix color setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(fujiFinePixColor)},
{0x1300, "BlurWarning", N_("Blur Warning"), N_("Blur warning status"), fujiId, makerTags, unsignedShort, -1,
{0x1300, "BlurWarning", N_("Blur Warning"), N_("Blur warning status"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiOffOn)},
{0x1301, "FocusWarning", N_("Focus Warning"), N_("Auto Focus warning status"), fujiId, makerTags, unsignedShort, -1,
{0x1301, "FocusWarning", N_("Focus Warning"), N_("Auto Focus warning status"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiOffOn)},
{0x1302, "ExposureWarning", N_("Exposure Warning"), N_("Auto exposure warning status"), fujiId, makerTags,
{0x1302, "ExposureWarning", N_("Exposure Warning"), N_("Auto exposure warning status"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1400, "DynamicRange", N_("Dynamic Range"), N_("Dynamic range"), fujiId, makerTags, unsignedShort, -1,
{0x1400, "DynamicRange", N_("Dynamic Range"), N_("Dynamic range"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiDynamicRange)},
{0x1401, "FilmMode", N_("Film Mode"), N_("Film mode"), fujiId, makerTags, unsignedShort, -1,
{0x1401, "FilmMode", N_("Film Mode"), N_("Film mode"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiFilmMode)},
{0x1402, "DynamicRangeSetting", N_("Dynamic Range Setting"), N_("Dynamic range settings"), fujiId, makerTags,
{0x1402, "DynamicRangeSetting", N_("Dynamic Range Setting"), N_("Dynamic range settings"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiDynamicRangeSetting)},
{0x1403, "DevelopmentDynamicRange", N_("Development Dynamic Range"), N_("Development dynamic range"), fujiId,
makerTags, unsignedShort, -1, printValue},
{0x1404, "MinFocalLength", N_("Minimum Focal Length"), N_("Minimum focal length"), fujiId, makerTags,
{0x1403, "DevelopmentDynamicRange", N_("Development Dynamic Range"), N_("Development dynamic range"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x1404, "MinFocalLength", N_("Minimum Focal Length"), N_("Minimum focal length"), IfdId::fujiId, SectionId::makerTags,
unsignedRational, -1, printValue},
{0x1405, "MaxFocalLength", N_("Maximum Focal Length"), N_("Maximum focal length"), fujiId, makerTags,
{0x1405, "MaxFocalLength", N_("Maximum Focal Length"), N_("Maximum focal length"), IfdId::fujiId, SectionId::makerTags,
unsignedRational, -1, printValue},
{0x1406, "MaxApertureAtMinFocal", N_("Maximum Aperture at Minimum Focal"), N_("Maximum aperture at minimum focal"),
fujiId, makerTags, unsignedRational, -1, printValue},
IfdId::fujiId, SectionId::makerTags, unsignedRational, -1, printValue},
{0x1407, "MaxApertureAtMaxFocal", N_("Maximum Aperture at Maximum Focal"), N_("Maximum aperture at maximum focal"),
fujiId, makerTags, unsignedRational, -1, printValue},
{0x140b, "AutoDynamicRange", N_("Auto Dynamic Range"), N_("Auto dynamic range"), fujiId, makerTags, unsignedShort,
IfdId::fujiId, SectionId::makerTags, unsignedRational, -1, printValue},
{0x140b, "AutoDynamicRange", N_("Auto Dynamic Range"), N_("Auto dynamic range"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, printValue},
{0x1422, "ImageStabilization", N_("Image Stabilization"), N_("Image stabilization"), fujiId, makerTags,
{0x1422, "ImageStabilization", N_("Image Stabilization"), N_("Image stabilization"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x1425, "SzeneRecognition", N_("Scene recognition"), N_("Scene recognition"), fujiId, makerTags, unsignedShort, -1,
{0x1425, "SzeneRecognition", N_("Scene recognition"), N_("Scene recognition"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiSceneRecognition)},
{0x1431, "Rating", N_("Rating"), N_("Rating"), fujiId, makerTags, unsignedLong, -1, printValue},
{0x1436, "ImageGeneration", N_("Image Generation"), N_("Image generation"), fujiId, makerTags, unsignedShort, -1,
{0x1431, "Rating", N_("Rating"), N_("Rating"), IfdId::fujiId, SectionId::makerTags, unsignedLong, -1, printValue},
{0x1436, "ImageGeneration", N_("Image Generation"), N_("Image generation"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiImageGeneration)},
{0x1438, "ImageNumber", N_("Image Number"), N_("Image Number"), fujiId, makerTags, unsignedShort, -1, printValue},
{0x1443, "DRangePriority", N_("D Range Priority"), N_("Dynamic range priority"), fujiId, makerTags, unsignedShort,
{0x1438, "ImageNumber", N_("Image Number"), N_("Image Number"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, printValue},
{0x1443, "DRangePriority", N_("D Range Priority"), N_("Dynamic range priority"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(fujiDRangePriority)},
{0x1444, "DRangePriorityFixed", N_("D Range Priority Fixed"), N_("Dynamic range priority fixed"), fujiId, makerTags,
{0x1444, "DRangePriorityFixed", N_("D Range Priority Fixed"), N_("Dynamic range priority fixed"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiDRangePriorityFixed)},
{0x1445, "DRangePriorityAuto", N_("D Range Priority Auto"), N_("Dynamic range priority auto"), fujiId, makerTags,
{0x1445, "DRangePriorityAuto", N_("D Range Priority Auto"), N_("Dynamic range priority auto"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiDRangePriorityAuto)},
{0x4005, "FaceElementSelected", N_("Face Element Selected"), N_("Face element selected"), fujiId, makerTags,
{0x4005, "FaceElementSelected", N_("Face Element Selected"), N_("Face element selected"), IfdId::fujiId, SectionId::makerTags,
asciiString, -1, printValue},
{0x4100, "FacesDetected", N_("Faces Detected"), N_("Faces detected"), fujiId, makerTags, asciiString, -1,
{0x4100, "FacesDetected", N_("Faces Detected"), N_("Faces detected"), IfdId::fujiId, SectionId::makerTags, asciiString, -1,
printValue},
{0x4103, "FacePositions", N_("Face Positions"),
N_("Left, top, right and bottom coordinates in full-sized image for each face detected"), fujiId, makerTags,
N_("Left, top, right and bottom coordinates in full-sized image for each face detected"), IfdId::fujiId, SectionId::makerTags,
asciiString, -1, printValue},
{0x4200, "NumberFaceElements", N_("Number of Face Elements"), N_("Number of face elements"), fujiId, makerTags,
{0x4200, "NumberFaceElements", N_("Number of Face Elements"), N_("Number of face elements"), IfdId::fujiId, SectionId::makerTags,
asciiString, -1, printValue},
{0x4201, "FaceElementTypes", N_("Face Element Types"), N_("Type of every face element"), fujiId, makerTags,
{0x4201, "FaceElementTypes", N_("Face Element Types"), N_("Type of every face element"), IfdId::fujiId, SectionId::makerTags,
asciiString, -1, printFujiFaceElementTypes},
{0x4203, "FaceElementPositions", N_("Face Element Positions"),
N_("Left, top, right and bottom coordinates in full-sized image for each face element)"), fujiId, makerTags,
N_("Left, top, right and bottom coordinates in full-sized image for each face element)"), IfdId::fujiId, SectionId::makerTags,
asciiString, -1, printValue},
{0x4282, "FaceRecInfo", N_("Face Recognition Information"), N_("Face Recognition Information"), fujiId, makerTags,
{0x4282, "FaceRecInfo", N_("Face Recognition Information"), N_("Face Recognition Information"), IfdId::fujiId, SectionId::makerTags,
asciiString, -1, printValue},
{0x8000, "FileSource", N_("File Source"), N_("File source"), fujiId, makerTags, asciiString, -1, printValue},
{0x8002, "OrderNumber", N_("Order Number"), N_("Order number"), fujiId, makerTags, unsignedLong, -1, printValue},
{0x8003, "FrameNumber", N_("Frame Number"), N_("Frame number"), fujiId, makerTags, unsignedShort, -1, printValue},
{0x8000, "FileSource", N_("File Source"), N_("File source"), IfdId::fujiId, SectionId::makerTags, asciiString, -1, printValue},
{0x8002, "OrderNumber", N_("Order Number"), N_("Order number"), IfdId::fujiId, SectionId::makerTags, unsignedLong, -1, printValue},
{0x8003, "FrameNumber", N_("Frame Number"), N_("Frame number"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, printValue},
// #1402
{0xf000, "FujiIFD", N_("FujiIFD"), N_("Fujifilm IFD"), fujiId, makerTags, undefined, -1, printValue},
{0xf001, "RawImageFullWidth", N_("Raw Image Full Width"), N_("Raw Image Full Width"), fujiId, makerTags, undefined,
{0xf000, "FujiIFD", N_("FujiIFD"), N_("Fujifilm IFD"), IfdId::fujiId, SectionId::makerTags, undefined, -1, printValue},
{0xf001, "RawImageFullWidth", N_("Raw Image Full Width"), N_("Raw Image Full Width"), IfdId::fujiId, SectionId::makerTags, undefined,
-1, printValue},
{0xf002, "RawImageFullHeight", N_("Raw Image Full Height"), N_("Raw Image Full Height"), fujiId, makerTags,
undefined, -1, printValue},
{0xf003, "BitsPerSample", N_("Bits Per Sample"), N_("Bits Per Sample"), fujiId, makerTags, undefined, -1,
{0x1001, N_("Sharpness"), N_("Sharpness"), N_("Sharpness setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiSharpness)},
{0x1002, "WhiteBalance", N_("White Balance"), N_("White balance setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiWhiteBalance)},
{0x1003, "Color", N_("Color"), N_("Chroma saturation setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, EXV_PRINT_TAG(fujiColor)},
{0x1004, "Tone", N_("Tone"), N_("Tone (contrast) setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiTone)},
{0x1010, "FlashMode", N_("Flash Mode"), N_("Flash firing mode setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiFlashMode)},
{0x1011, "FlashStrength", N_("Flash Strength"), N_("Flash firing strength compensation setting"), IfdId::fujiId,
SectionId::makerTags, signedRational, -1, printValue},
{0x1020, "Macro", N_("Macro"), N_("Macro mode setting"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiOffOn)},
{0x1021, "FocusMode", N_("Focus Mode"), N_("Focusing mode setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiFocusMode)},
{0x1022, "0x1022", "0x1022", N_("Unknown"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, printValue},
{0x1030, "SlowSync", N_("Slow Sync"), N_("Slow synchro mode setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1031, "PictureMode", N_("Picture Mode"), N_("Picture mode setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiPictureMode)},
{0x1032, "0x1032", "0x1032", N_("Unknown"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, printValue},
{0x1040, "ShadowTone", N_("Shadow Tone"), N_("Shadow tone"), IfdId::fujiId, SectionId::makerTags, signedLong, -1,
EXV_PRINT_TAG(fujiSHTone)},
{0x1041, "HighlightTone", N_("Highlight Tone"), N_("Highlight tone"), IfdId::fujiId, SectionId::makerTags,
signedLong, -1, EXV_PRINT_TAG(fujiSHTone)},
{0x104d, "CropMode", N_("Crop Mode"), N_("Crop mode"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiCropMode)},
{0x1100, "Continuous", N_("Continuous"), N_("Continuous shooting or auto bracketing setting"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiContinuous)},
{0x1101, "SequenceNumber", N_("Sequence Number"), N_("Sequence number"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, printValue},
{0x1200, "0x1200", "0x1200", N_("Unknown"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1, printValue},
{0x1210, "FinePixColor", N_("FinePix Color"), N_("Fuji FinePix color setting"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiFinePixColor)},
{0x1300, "BlurWarning", N_("Blur Warning"), N_("Blur warning status"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1301, "FocusWarning", N_("Focus Warning"), N_("Auto Focus warning status"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1302, "ExposureWarning", N_("Exposure Warning"), N_("Auto exposure warning status"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiOffOn)},
{0x1400, "DynamicRange", N_("Dynamic Range"), N_("Dynamic range"), IfdId::fujiId, SectionId::makerTags,
unsignedShort, -1, EXV_PRINT_TAG(fujiDynamicRange)},
{0x1401, "FilmMode", N_("Film Mode"), N_("Film mode"), IfdId::fujiId, SectionId::makerTags, unsignedShort, -1,
EXV_PRINT_TAG(fujiFilmMode)},
{0x1402, "DynamicRangeSetting", N_("Dynamic Range Setting"), N_("Dynamic range settings"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiDynamicRangeSetting)},
{0x1403, "DevelopmentDynamicRange", N_("Development Dynamic Range"), N_("Development dynamic range"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, printValue},
{0x1404, "MinFocalLength", N_("Minimum Focal Length"), N_("Minimum focal length"), IfdId::fujiId,
SectionId::makerTags, unsignedRational, -1, printValue},
{0x1405, "MaxFocalLength", N_("Maximum Focal Length"), N_("Maximum focal length"), IfdId::fujiId,
SectionId::makerTags, unsignedRational, -1, printValue},
{0x1406, "MaxApertureAtMinFocal", N_("Maximum Aperture at Minimum Focal"), N_("Maximum aperture at minimum focal"),
IfdId::fujiId, SectionId::makerTags, unsignedRational, -1, printValue},
{0x1407, "MaxApertureAtMaxFocal", N_("Maximum Aperture at Maximum Focal"), N_("Maximum aperture at maximum focal"),
IfdId::fujiId, SectionId::makerTags, unsignedRational, -1, printValue},
{0x1431, "Rating", N_("Rating"), N_("Rating"), IfdId::fujiId, SectionId::makerTags, unsignedLong, -1, printValue},
{0x1443, "DRangePriority", N_("D Range Priority"), N_("Dynamic range priority"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiDRangePriority)},
{0x1444, "DRangePriorityFixed", N_("D Range Priority Fixed"), N_("Dynamic range priority fixed"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiDRangePriorityFixed)},
{0x1445, "DRangePriorityAuto", N_("D Range Priority Auto"), N_("Dynamic range priority auto"), IfdId::fujiId,
SectionId::makerTags, unsignedShort, -1, EXV_PRINT_TAG(fujiDRangePriorityAuto)},
{0x8000, "FileSource", N_("File Source"), N_("File source"), IfdId::fujiId, SectionId::makerTags, asciiString, -1,
printValue},
{0xf007, "StripOffsets", N_("Strip Offsets"), N_("Strip Offsets"), fujiId, makerTags, undefined, -1, printValue},
{0xf008, "StripByteCounts", N_("Strip Byte Counts"), N_("Strip Byte Counts"), fujiId, makerTags, undefined, -1,
{0x8002, "OrderNumber", N_("Order Number"), N_("Order number"), IfdId::fujiId, SectionId::makerTags, unsignedLong,
-1, printValue},
{0x8003, "FrameNumber", N_("Frame Number"), N_("Frame number"), IfdId::fujiId, SectionId::makerTags, unsignedShort,
-1, printValue},
// #1402
{0xf000, "FujiIFD", N_("FujiIFD"), N_("Fujifilm IFD"), IfdId::fujiId, SectionId::makerTags, undefined, -1,
printValue},
{0xf00a, "BlackLevel", N_("Black Level"), N_("Black Level"), fujiId, makerTags, undefined, -1, printValue},
{0xf00b, "GeometricDistortionParams", N_("Geometric Distortion Params"), N_("Geometric Distortion Params"), fujiId,
makerTags, undefined, -1, printValue},
{0xf00c, "WB_GRBLevelsStandard", N_("WB GRB Levels Standard"), N_("WB GRB Levels Standard"), fujiId, makerTags,
{0xf001, "RawImageFullWidth", N_("Raw Image Full Width"), N_("Raw Image Full Width"), IfdId::fujiId,
SectionId::makerTags, undefined, -1, printValue},
{0xf002, "RawImageFullHeight", N_("Raw Image Full Height"), N_("Raw Image Full Height"), IfdId::fujiId,
SectionId::makerTags, undefined, -1, printValue},
{0xf003, "BitsPerSample", N_("Bits Per Sample"), N_("Bits Per Sample"), IfdId::fujiId, SectionId::makerTags,
undefined, -1, printValue},
{0xf00d, "WB_GRBLevelsAuto", N_("WB GRB Levels Auto"), N_("WB GRB Levels Auto"), fujiId, makerTags, undefined, -1,
printValue},
{0xf00e, "WB_GRBLevels", N_("WB GRB Levels"), N_("WB GRB Levels"), fujiId, makerTags, undefined, -1, printValue},
{0xf00f, "ChromaticAberrationParams", N_("Chromatic Aberration Params"), N_("Chromatic Aberration Params"), fujiId,
makerTags, undefined, -1, printValue},
{0xf010, "VignettingParams", N_("Vignetting Params"), N_("Vignetting Params"), fujiId, makerTags, undefined, -1,
{0xf007, "StripOffsets", N_("Strip Offsets"), N_("Strip Offsets"), IfdId::fujiId, SectionId::makerTags, undefined,
-1, printValue},
{0xf008, "StripByteCounts", N_("Strip Byte Counts"), N_("Strip Byte Counts"), IfdId::fujiId, SectionId::makerTags,
undefined, -1, printValue},
{0xf00a, "BlackLevel", N_("Black Level"), N_("Black Level"), IfdId::fujiId, SectionId::makerTags, undefined, -1,
printValue},
{0xf00b, "GeometricDistortionParams", N_("Geometric Distortion Params"), N_("Geometric Distortion Params"),
IfdId::fujiId, SectionId::makerTags, undefined, -1, printValue},
{0xf00c, "WB_GRBLevelsStandard", N_("WB GRB Levels Standard"), N_("WB GRB Levels Standard"), IfdId::fujiId,
SectionId::makerTags, undefined, -1, printValue},
{0xf00d, "WB_GRBLevelsAuto", N_("WB GRB Levels Auto"), N_("WB GRB Levels Auto"), IfdId::fujiId,
SectionId::makerTags, undefined, -1, printValue},
{0xf00e, "WB_GRBLevels", N_("WB GRB Levels"), N_("WB GRB Levels"), IfdId::fujiId, SectionId::makerTags, undefined,
-1, printValue},
{0xf00f, "ChromaticAberrationParams", N_("Chromatic Aberration Params"), N_("Chromatic Aberration Params"),
IfdId::fujiId, SectionId::makerTags, undefined, -1, printValue},
{0xf010, "VignettingParams", N_("Vignetting Params"), N_("Vignetting Params"), IfdId::fujiId, SectionId::makerTags,
undefined, -1, printValue},
// End of list marker
{0xffff, "(UnknownFujiMakerNoteTag)", "(UnknownFujiMakerNoteTag)", N_("Unknown FujiMakerNote tag"), fujiId,
makerTags, asciiString, -1, printValue}};
{0xffff, "(UnknownFujiMakerNoteTag)", "(UnknownFujiMakerNoteTag)", N_("Unknown FujiMakerNote tag"), IfdId::fujiId,
SectionId::makerTags, asciiString, -1, printValue},
};
const TagInfo* FujiMakerNote::tagList() {
return tagInfo_;

@ -79,7 +79,7 @@ char from_hex(char ch) {
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}
std::string urlencode(std::string_view str) {
std::string urlencode(const std::string& str) {
std::string encoded;
encoded.reserve(str.size() * 3);
for (uint8_t c : str) {
@ -259,22 +259,20 @@ void Uri::Decode(Uri& uri) {
Uri Uri::Parse(const std::string& uri) {
Uri result;
using iterator_t = std::string::const_iterator;
if (!uri.length())
return result;
iterator_t uriEnd = uri.end();
auto uriEnd = uri.end();
// get query start
iterator_t queryStart = std::find(uri.begin(), uriEnd, '?');
auto queryStart = std::find(uri.begin(), uriEnd, '?');
// protocol
iterator_t protocolStart = uri.begin();
iterator_t protocolEnd = std::find(protocolStart, uriEnd, ':'); //"://");
auto protocolStart = uri.begin();
auto protocolEnd = std::find(protocolStart, uriEnd, ':'); //"://");
if (protocolEnd != uriEnd) {
std::string prot = &*(protocolEnd);
auto prot = std::string(protocolEnd, uriEnd);
if ((prot.length() > 3) && (prot.substr(0, 3) == "://")) {
result.Protocol = std::string(protocolStart, protocolEnd);
protocolEnd += 3; // ://
@ -284,11 +282,11 @@ Uri Uri::Parse(const std::string& uri) {
protocolEnd = uri.begin(); // no protocol
// username & password
iterator_t authStart = protocolEnd;
iterator_t authEnd = std::find(protocolEnd, uriEnd, '@');
auto authStart = protocolEnd;
auto authEnd = std::find(protocolEnd, uriEnd, '@');
if (authEnd != uriEnd) {
iterator_t userStart = authStart;
iterator_t userEnd = std::find(authStart, authEnd, ':');
auto userStart = authStart;
auto userEnd = std::find(authStart, authEnd, ':');
if (userEnd != authEnd) {
result.Username = std::string(userStart, userEnd);
++userEnd;
@ -302,19 +300,19 @@ Uri Uri::Parse(const std::string& uri) {
}
// host
iterator_t hostStart = authEnd;
iterator_t pathStart = std::find(hostStart, uriEnd, '/'); // get pathStart
auto hostStart = authEnd;
auto pathStart = std::find(hostStart, uriEnd, '/'); // get pathStart
iterator_t hostEnd = std::find(authEnd, (pathStart != uriEnd) ? pathStart : queryStart,
':'); // check for port
auto hostEnd = std::find(authEnd, (pathStart != uriEnd) ? pathStart : queryStart,
':'); // check for port
result.Host = std::string(hostStart, hostEnd);
// port
if ((hostEnd != uriEnd) && ((&*(hostEnd))[0] == ':')) // we have a port
if ((hostEnd != uriEnd) && (*hostEnd == ':')) // we have a port
{
++hostEnd;
iterator_t portEnd = (pathStart != uriEnd) ? pathStart : queryStart;
auto portEnd = (pathStart != uriEnd) ? pathStart : queryStart;
result.Port = std::string(hostEnd, portEnd);
}
if (!result.Port.length() && result.Protocol == "http")
@ -378,7 +376,7 @@ std::string getProcessPath() {
ret = std::filesystem::read_symlink("/proc/self/exe");
#endif
const size_t idxLastSeparator = ret.find_last_of(EXV_SEPARATOR_STR);
const size_t idxLastSeparator = ret.find_last_of(EXV_SEPARATOR_CHR);
return ret.substr(0, idxLastSeparator);
}
} // namespace Exiv2

@ -29,7 +29,7 @@ void GifImage::setIptcData(const IptcData& /*iptcData*/) {
throw(Error(ErrorCode::kerInvalidSettingForImage, "IPTC metadata", "GIF"));
}
void GifImage::setComment(std::string_view /*comment*/) {
void GifImage::setComment(const std::string&) {
// not supported
throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "GIF"));
}

@ -336,7 +336,7 @@ int Exiv2::http(Exiv2::Dictionary& request, Exiv2::Dictionary& response, std::st
if (n != FINISH || !OK(status)) {
snprintf(buffer, sizeof buffer, "wsa_error = %d,n = %d,sleep_ = %d status = %d", WSAGetLastError(), n,
int(sleep_.count()), status);
static_cast<int>(sleep_.count()), status);
error(errors, buffer, nullptr, nullptr, 0);
} else if (bSearching && OK(status)) {
if (end) {

@ -99,8 +99,6 @@ constexpr auto registry = std::array{
#ifdef EXV_ENABLE_BMFF
Registry{ImageType::bmff, newBmffInstance, isBmffType, amRead, amRead, amRead, amNone},
#endif // EXV_ENABLE_BMFF
// End of list marker
Registry{ImageType::none, nullptr, nullptr, amNone, amNone, amNone, amNone},
};
std::string pathOfFileUrl(const std::string& url) {
@ -116,17 +114,13 @@ std::string pathOfFileUrl(const std::string& url) {
namespace Exiv2 {
Image::Image(ImageType type, uint16_t supportedMetadata, BasicIo::UniquePtr io) :
io_(std::move(io)),
pixelWidth_(0),
pixelHeight_(0),
imageType_(type),
supportedMetadata_(supportedMetadata),
#ifdef EXV_HAVE_XMP_TOOLKIT
writeXmpFromPacket_(false),
writeXmpFromPacket_(false) {
#else
writeXmpFromPacket_(true),
writeXmpFromPacket_(true) {
#endif
byteOrder_(invalidByteOrder),
init_(true) {
}
void Image::printStructure(std::ostream&, PrintStructureOption, int /*depth*/) {
@ -190,17 +184,17 @@ uint64_t Image::byteSwap(uint64_t value, bool bSwap) {
uint32_t Image::byteSwap(uint32_t value, bool bSwap) {
uint32_t result = 0;
result |= (value & 0x000000FF) << 24;
result |= (value & 0x0000FF00) << 8;
result |= (value & 0x00FF0000) >> 8;
result |= (value & 0xFF000000) >> 24;
result |= (value & 0x000000FFU) << 24;
result |= (value & 0x0000FF00U) << 8;
result |= (value & 0x00FF0000U) >> 8;
result |= (value & 0xFF000000U) >> 24;
return bSwap ? result : value;
}
uint16_t Image::byteSwap(uint16_t value, bool bSwap) {
uint16_t result = 0;
result |= (value & 0x00FF) << 8;
result |= (value & 0xFF00) >> 8;
result |= (value & 0x00FFU) << 8;
result |= (value & 0xFF00U) >> 8;
return bSwap ? result : value;
}
@ -287,7 +281,7 @@ static bool typeValid(uint16_t type) {
return type >= 1 && type <= 13;
}
static std::set<long> visits; // #547
static std::set<size_t> visits; // #547
void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option, size_t start,
bool bSwap, char c, int depth) {
@ -370,7 +364,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
const bool bOffsetIsPointer = count_x_size > 4;
if (bOffsetIsPointer) { // read into buffer
const long restore = io.tell(); // save
const size_t restore = io.tell(); // save
io.seekOrThrow(offset, BasicIo::beg, ErrorCode::kerCorruptedMetadata); // position
io.readOrThrow(buf.data(), count_x_size, ErrorCode::kerCorruptedMetadata); // read
io.seekOrThrow(restore, BasicIo::beg, ErrorCode::kerCorruptedMetadata); // restore
@ -381,7 +375,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
const std::string offsetString = bOffsetIsPointer ? Internal::stringFormat("%10u", offset) : "";
out << Internal::indent(depth)
<< Internal::stringFormat("%8u | %#06x %-28s |%10s |%9u |%10s | ", address, tag, tagName(tag).c_str(),
<< Internal::stringFormat("%8zu | %#06x %-28s |%10s |%9u |%10s | ", address, tag, tagName(tag).c_str(),
typeName(type), count, offsetString.c_str());
if (isShortType(type)) {
for (size_t k = 0; k < kount; k++) {
@ -410,7 +404,7 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
if (option == kpsRecursive && (tag == 0x8769 /* ExifTag */ || tag == 0x014a /*SubIFDs*/ || type == tiffIfd)) {
for (size_t k = 0; k < count; k++) {
const long restore = io.tell();
const size_t restore = io.tell();
offset = byteSwap4(buf, k * size, bSwap);
printIFDStructure(io, out, option, offset, bSwap, c, depth);
io.seekOrThrow(restore, BasicIo::beg, ErrorCode::kerCorruptedMetadata);
@ -421,17 +415,17 @@ void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStruct
throw Error(ErrorCode::kerCorruptedMetadata);
}
const long restore = io.tell();
const size_t restore = io.tell();
io.seekOrThrow(offset, BasicIo::beg, ErrorCode::kerCorruptedMetadata); // position
std::vector<byte> bytes(count); // allocate memory
// TODO: once we have C++11 use bytes.data()
io.readOrThrow(&bytes[0], count, ErrorCode::kerCorruptedMetadata);
io.readOrThrow(bytes.data(), count, ErrorCode::kerCorruptedMetadata);
io.seekOrThrow(restore, BasicIo::beg, ErrorCode::kerCorruptedMetadata);
// TODO: once we have C++11 use bytes.data()
IptcData::printStructure(out, makeSliceUntil(&bytes[0], count), depth);
IptcData::printStructure(out, makeSliceUntil(bytes.data(), count), depth);
}
} else if (option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
const long restore = io.tell(); // save
const size_t restore = io.tell(); // save
uint32_t jump = 10;
byte bytes[20];
@ -597,7 +591,7 @@ void Image::clearComment() {
comment_.erase();
}
void Image::setComment(std::string_view comment) {
void Image::setComment(const std::string& comment) {
comment_ = comment;
}
@ -755,9 +749,9 @@ ImageType ImageFactory::getType(BasicIo& io) {
if (io.open() != 0)
return ImageType::none;
IoCloser closer(io);
for (unsigned int i = 0; registry[i].imageType_ != ImageType::none; ++i) {
if (registry[i].isThisType_(io, false)) {
return registry[i].imageType_;
for (const auto& r : registry) {
if (r.isThisType_(io, false)) {
return r.imageType_;
}
}
return ImageType::none;
@ -802,9 +796,9 @@ Image::UniquePtr ImageFactory::open(BasicIo::UniquePtr io) {
if (io->open() != 0) {
throw Error(ErrorCode::kerDataSourceOpenFailed, io->path(), strError());
}
for (unsigned int i = 0; registry[i].imageType_ != ImageType::none; ++i) {
if (registry[i].isThisType_(*io, false)) {
return registry[i].newInstance_(std::move(io), false);
for (const auto& r : registry) {
if (r.isThisType_(*io, false)) {
return r.newInstance_(std::move(io), false);
}
}
return nullptr;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save