git repos / SagoImageBrowser

commit fc05db7c

Poul Sander · 2026-07-08 18:21
fc05db7cd4feea0326457bf46a24e601b1490c3d patch · browse files
parent b09b1f5cc39fb11acfb2141fe905788d8facdbc1

Use the system exiv2 version. Compatible with both 0.27 and 0.28

Changed files

M CMakeLists.txt before
M README.md before
M extra/docker/Dockerfile before
M src/exifreader.cpp before
diff --git a/CMakeLists.txt b/CMakeLists.txt index e1fc74e..3d34706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -7,23 +7,16 @@ set(CMAKE_AUTOMOC ON)
include(GNUInstallDirs)
find_package(Qt6 REQUIRED COMPONENTS Widgets LinguistTools)
-include(FetchContent)
-# Build exiv2lib as a static library so it is linked into the executable
-set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "")
-set(EXIV2_BUILD_SAMPLES OFF CACHE INTERNAL "")
-set(EXIV2_BUILD_EXIV2_COMMAND OFF CACHE INTERNAL "")
-set(EXIV2_BUILD_UNIT_TESTS OFF CACHE INTERNAL "")
-set(EXIV2_BUILD_DOC OFF CACHE INTERNAL "")
-set(EXIV2_ENABLE_INIH OFF CACHE INTERNAL "")
-FetchContent_Declare(
- exiv2
- GIT_REPOSITORY https://github.com/Exiv2/exiv2.git
- GIT_TAG v0.28.8
-)
-FetchContent_MakeAvailable(exiv2)
-# Exiv2 0.28.8 generates this header in the build root but doesn't add it to include paths
-target_include_directories(exiv2lib INTERFACE $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>)
+# Use the system-provided exiv2 (both 0.27 and 0.28 are supported)
+find_package(exiv2 REQUIRED CONFIG)
+
+# 0.28 exports Exiv2::exiv2lib; 0.27 configs may export the unnamespaced target
+if(TARGET Exiv2::exiv2lib)
+ set(EXIV2_TARGET Exiv2::exiv2lib)
+else()
+ set(EXIV2_TARGET exiv2lib)
+endif()
qt_add_executable(SagoImageBrowser
src/main.cpp
@@ -53,11 +46,11 @@ qt_add_executable(SagoImageBrowser
set_source_files_properties(extra/icons/sago_image_browser.svg PROPERTIES QT_RESOURCE_ALIAS sago_image_browser.svg)
qt_add_resources(SagoImageBrowser "icons" PREFIX "/icons" FILES extra/icons/sago_image_browser.svg)
-target_link_libraries(SagoImageBrowser PRIVATE Qt6::Widgets exiv2lib)
+target_link_libraries(SagoImageBrowser PRIVATE Qt6::Widgets ${EXIV2_TARGET})
add_executable(test_exifreader test/test_exifreader.cpp src/exifreader.cpp)
target_include_directories(test_exifreader PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
-target_link_libraries(test_exifreader PRIVATE Qt6::Widgets exiv2lib)
+target_link_libraries(test_exifreader PRIVATE Qt6::Widgets ${EXIV2_TARGET})
qt_add_translations(SagoImageBrowser
TS_FILES translations/da.ts
diff --git a/README.md b/README.md index 280acd9..96e4578 100644 --- a/README.md +++ b/README.md
@@ -25,21 +25,20 @@ A Qt6-based image browser application for viewing and managing image collections
- C++17 or later
- CMake 3.21+
- Qt6 (Widgets and LinguistTools components)
-- Git and a network connection — Exiv2 (v0.28.8) is fetched and statically linked
- at configure time via CMake `FetchContent`
+- Exiv2 development files (0.27 or 0.28) installed on the system, e.g. `libexiv2-dev`
## Building
### Prerequisites
-Install Qt6 development files:
+Install the Qt6 and Exiv2 development files:
```bash
# On Ubuntu/Debian
-sudo apt-get install qt6-base-dev qt6-tools-dev
+sudo apt-get install qt6-base-dev qt6-tools-dev libexiv2-dev
# On macOS with Homebrew
-brew install qt6
+brew install qt6 exiv2
```
### Build Steps
diff --git a/extra/docker/Dockerfile b/extra/docker/Dockerfile index 9c24b31..d3579f3 100644 --- a/extra/docker/Dockerfile +++ b/extra/docker/Dockerfile
@@ -7,8 +7,6 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install --no-install-recommends -y \
build-essential \
cmake \
- git \
- ca-certificates \
pkg-config \
qt6-base-dev \
qt6-tools-dev \
@@ -16,9 +14,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
libqt6core6 \
libqt6gui6 \
libqt6widgets6 \
- zlib1g-dev \
- libexpat1-dev \
- libbrotli-dev \
+ libexiv2-dev \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir -p /staging/sago_image_browser
diff --git a/src/exifreader.cpp b/src/exifreader.cpp index dad65b3..085f678 100644 --- a/src/exifreader.cpp +++ b/src/exifreader.cpp
@@ -32,6 +32,13 @@ SOFTWARE.
#include <exiv2/exiv2.hpp>
+// exiv2 0.28 returns a std::unique_ptr (Image::UniquePtr); 0.27 uses Image::AutoPtr
+#if EXIV2_VERSION >= EXIV2_MAKE_VERSION(0,28,0)
+using Exiv2ImagePtr = Exiv2::Image::UniquePtr;
+#else
+using Exiv2ImagePtr = Exiv2::Image::AutoPtr;
+#endif
+
#include <sys/stat.h>
#include <fcntl.h>
#include <filesystem>
@@ -189,8 +196,7 @@ ExifData ExifReader::read(const QByteArray &path)
// EXIF tags via exiv2
try {
- std::unique_ptr<Exiv2::Image> image =
- Exiv2::ImageFactory::open(path.toStdString());
+ Exiv2ImagePtr image = Exiv2::ImageFactory::open(path.toStdString());
image->readMetadata();
const Exiv2::ExifData &exif = image->exifData();
@@ -246,8 +252,7 @@ bool ExifReader::saveCaption(const QByteArray &path,
const ExifData &oldData)
{
try {
- std::unique_ptr<Exiv2::Image> image =
- Exiv2::ImageFactory::open(path.toStdString());
+ Exiv2ImagePtr image = Exiv2::ImageFactory::open(path.toStdString());
image->readMetadata();
// Erase all existing Caption-Abstract entries then add the new one
@@ -279,15 +284,18 @@ bool ExifReader::saveCaption(const QByteArray &path,
bool ExifReader::rotate(const QByteArray &path, bool clockwise)
{
try {
- std::unique_ptr<Exiv2::Image> image =
- Exiv2::ImageFactory::open(path.toStdString());
+ Exiv2ImagePtr image = Exiv2::ImageFactory::open(path.toStdString());
image->readMetadata();
Exiv2::ExifData &exif = image->exifData();
int current = 1; // EXIF default when the tag is absent
auto it = exif.findKey(Exiv2::ExifKey("Exif.Image.Orientation"));
if (it != exif.end())
+#if EXIV2_VERSION >= EXIV2_MAKE_VERSION(0,28,0)
current = static_cast<int>(it->toInt64());
+#else
+ current = static_cast<int>(it->toLong());
+#endif
const int updated = clockwise ? orientationRotatedClockwise(current)
: orientationRotatedCounterClockwise(current);