diff --git a/CMakeLists.txt b/CMakeLists.txt index 717d859..be33a09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,93 +1,94 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.7) project(krename VERSION "5.0.60") set(QT5_MIN_VERSION "5.7.0") set(KF5_MIN_VERSION "5.18.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules) include(KDEInstallDirs) include(ECMInstallIcons) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(FeatureSummary) find_package(Qt5 ${QT5_MIN_VERSION} REQUIRED COMPONENTS Core Widgets ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Completion Config CoreAddons Crash I18n IconThemes ItemViews JobWidgets JS KIO Service WidgetsAddons XmlGui ) add_definitions( -DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x050700 -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_NO_URL_CAST_FROM_STRING -DQT_STRICT_ITERATORS ) # Find KArchive find_package(KF5Archive) set_package_properties(KF5Archive PROPERTIES PURPOSE "Needed for ODF plugin" TYPE OPTIONAL) # Find taglib set(TAGLIB_MIN_VERSION "1.5") find_package(Taglib ${TAGLIB_MIN_VERSION}) set_package_properties(Taglib PROPERTIES DESCRIPTION "Read and write tags in audio files" URL "https://taglib.github.io/" TYPE OPTIONAL) # Find exiv2 -find_package(Exiv2 0.13) # AccessMode was added in 0.13 -set_package_properties(Exiv2 PROPERTIES - DESCRIPTION "A library to access image metadata" - URL "http://www.exiv2.org" - TYPE OPTIONAL) +find_package(LibExiv2 0.13) # AccessMode was added in 0.13 +set_package_properties(LibExiv2 PROPERTIES TYPE OPTIONAL) + +if (LibExiv2_VERSION VERSION_GREATER_EQUAL "0.27") + set(HAVE_LIBEXIV2_0_27 TRUE) +endif() # Find podofo find_package(PoDoFo) set_package_properties(PoDoFo PROPERTIES DESCRIPTION "A library to access PDF metadata" URL "http://podofo.sourceforge.net/" TYPE OPTIONAL) # Find freetype find_package(Freetype) set_package_properties(Freetype PROPERTIES DESCRIPTION "A library to access font metadata" URL "http://www.freetype.org" TYPE OPTIONAL) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) set(HAVE_TAGLIB TAGLIB_FOUND) -set(HAVE_EXIV2 EXIV2_FOUND) +set(HAVE_EXIV2 LibExiv2_FOUND) set(HAVE_PODOFO PoDoFo_FOUND) set(HAVE_KARCHIVE KF5Archive_FOUND) set(HAVE_FREETYPE FREETYPE_FOUND) configure_file(config-krename.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krename.h) # Directories add_subdirectory(src) add_subdirectory(autotests) diff --git a/cmake/modules/FindExiv2.cmake b/cmake/modules/FindExiv2.cmake deleted file mode 100644 index dd9af86..0000000 --- a/cmake/modules/FindExiv2.cmake +++ /dev/null @@ -1,79 +0,0 @@ -# - Try to find the Exiv2 library -# -# EXIV2_MIN_VERSION - You can set this variable to the minimum version you need -# before doing FIND_PACKAGE(Exiv2). The default is 0.12. -# -# Once done this will define -# -# EXIV2_FOUND - system has libexiv2 -# EXIV2_INCLUDE_DIR - the libexiv2 include directory -# EXIV2_LIBRARIES - Link these to use libexiv2 -# EXIV2_DEFINITIONS - Compiler switches required for using libexiv2 -# -# The minimum required version of Exiv2 can be specified using the -# standard syntax, e.g. find_package(Exiv2 0.17) -# -# For compatibility, also the variable EXIV2_MIN_VERSION can be set to the minimum version -# you need before doing FIND_PACKAGE(Exiv2). The default is 0.12. - -# Copyright (c) 2010, Alexander Neundorf, -# Copyright (c) 2008, Gilles Caulier, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -# Support EXIV2_MIN_VERSION for compatibility: -if(NOT Exiv2_FIND_VERSION) - set(Exiv2_FIND_VERSION "${EXIV2_MIN_VERSION}") -endif(NOT Exiv2_FIND_VERSION) - -# the minimum version of exiv2 we require -if(NOT Exiv2_FIND_VERSION) - set(Exiv2_FIND_VERSION "0.12") -endif(NOT Exiv2_FIND_VERSION) - - -if (NOT WIN32) - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - find_package(PkgConfig) - pkg_check_modules(PC_EXIV2 QUIET exiv2) - set(EXIV2_DEFINITIONS ${PC_EXIV2_CFLAGS_OTHER}) -endif (NOT WIN32) - - -find_path(EXIV2_INCLUDE_DIR NAMES exiv2/exif.hpp - HINTS - ${PC_EXIV2_INCLUDEDIR} - ${PC_EXIV2_INCLUDE_DIRS} - ) - -find_library(EXIV2_LIBRARY NAMES exiv2 libexiv2 - HINTS - ${PC_EXIV2_LIBDIR} - ${PC_EXIV2_LIBRARY_DIRS} - ) - - -# Get the version number from exiv2/version.hpp and store it in the cache: -if(EXIV2_INCLUDE_DIR AND NOT EXIV2_VERSION) - file(READ ${EXIV2_INCLUDE_DIR}/exiv2/version.hpp EXIV2_VERSION_CONTENT) - string(REGEX MATCH "#define EXIV2_MAJOR_VERSION +\\( *([0-9]+) *\\)" _dummy "${EXIV2_VERSION_CONTENT}") - set(EXIV2_VERSION_MAJOR "${CMAKE_MATCH_1}") - - string(REGEX MATCH "#define EXIV2_MINOR_VERSION +\\( *([0-9]+) *\\)" _dummy "${EXIV2_VERSION_CONTENT}") - set(EXIV2_VERSION_MINOR "${CMAKE_MATCH_1}") - - string(REGEX MATCH "#define EXIV2_PATCH_VERSION +\\( *([0-9]+) *\\)" _dummy "${EXIV2_VERSION_CONTENT}") - set(EXIV2_VERSION_PATCH "${CMAKE_MATCH_1}") - - set(EXIV2_VERSION "${EXIV2_VERSION_MAJOR}.${EXIV2_VERSION_MINOR}.${EXIV2_VERSION_PATCH}" CACHE STRING "Version number of Exiv2" FORCE) -endif(EXIV2_INCLUDE_DIR AND NOT EXIV2_VERSION) - -set(EXIV2_LIBRARIES "${EXIV2_LIBRARY}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Exiv2 REQUIRED_VARS EXIV2_LIBRARY EXIV2_INCLUDE_DIR - VERSION_VAR EXIV2_VERSION) - -mark_as_advanced(EXIV2_INCLUDE_DIR EXIV2_LIBRARY) diff --git a/cmake/modules/FindLibExiv2.cmake b/cmake/modules/FindLibExiv2.cmake new file mode 100644 index 0000000..935cee2 --- /dev/null +++ b/cmake/modules/FindLibExiv2.cmake @@ -0,0 +1,115 @@ +#.rst: +# FindLibExiv2 +# ------------ +# +# Try to find the Exiv2 library. +# +# This will define the following variables: +# +# ``LibExiv2_FOUND`` +# System has LibExiv2. +# +# ``LibExiv2_VERSION`` +# The version of LibExiv2. +# +# ``LibExiv2_INCLUDE_DIRS`` +# This should be passed to target_include_directories() if +# the target is not used for linking. +# +# ``LibExiv2_LIBRARIES`` +# The LibExiv2 library. +# This can be passed to target_link_libraries() instead of +# the ``LibExiv2::LibExiv2`` target +# +# If ``LibExiv2_FOUND`` is TRUE, the following imported target +# will be available: +# +# ``LibExiv2::LibExiv2`` +# The Exiv2 library +# +# Since 5.53.0. +# +#============================================================================= +# Copyright (c) 2018, Christophe Giboudeaux, +# Copyright (c) 2010, Alexander Neundorf, +# Copyright (c) 2008, Gilles Caulier, +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +find_package(PkgConfig QUIET) +pkg_check_modules(PC_EXIV2 QUIET exiv2) + +find_path(LibExiv2_INCLUDE_DIRS NAMES exiv2/exif.hpp + HINTS ${PC_EXIV2_INCLUDEDIR} +) + +find_library(LibExiv2_LIBRARIES NAMES exiv2 libexiv2 + HINTS ${PC_EXIV2_LIBRARY_DIRS} +) + +set(LibExiv2_VERSION ${PC_EXIV2_VERSION}) + +if(NOT LibExiv2_VERSION AND DEFINED LibExiv2_INCLUDE_DIRS) + # With exiv >= 0.27, the version #defines are in exv_conf.h instead of version.hpp + foreach(_exiv2_version_file "version.hpp" "exv_conf.h") + if(EXISTS "${LibExiv2_INCLUDE_DIRS}/exiv2/${_exiv2_version_file}") + file(READ "${LibExiv2_INCLUDE_DIRS}/exiv2/${_exiv2_version_file}" _exiv_version_file_content) + string(REGEX MATCH "#define EXIV2_MAJOR_VERSION[ ]+\\([0-9]+\\)" EXIV2_MAJOR_VERSION_MATCH ${_exiv_version_file_content}) + string(REGEX MATCH "#define EXIV2_MINOR_VERSION[ ]+\\([0-9]+\\)" EXIV2_MINOR_VERSION_MATCH ${_exiv_version_file_content}) + string(REGEX MATCH "#define EXIV2_PATCH_VERSION[ ]+\\([0-9]+\\)" EXIV2_PATCH_VERSION_MATCH ${_exiv_version_file_content}) + if(EXIV2_MAJOR_VERSION_MATCH) + string(REGEX REPLACE ".*_MAJOR_VERSION[ ]+\\((.*)\\)" "\\1" EXIV2_MAJOR_VERSION ${EXIV2_MAJOR_VERSION_MATCH}) + string(REGEX REPLACE ".*_MINOR_VERSION[ ]+\\((.*)\\)" "\\1" EXIV2_MINOR_VERSION ${EXIV2_MINOR_VERSION_MATCH}) + string(REGEX REPLACE ".*_PATCH_VERSION[ ]+\\((.*)\\)" "\\1" EXIV2_PATCH_VERSION ${EXIV2_PATCH_VERSION_MATCH}) + endif() + endif() + endforeach() + + set(LibExiv2_VERSION "${EXIV2_MAJOR_VERSION}.${EXIV2_MINOR_VERSION}.${EXIV2_PATCH_VERSION}") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibExiv2 + FOUND_VAR LibExiv2_FOUND + REQUIRED_VARS LibExiv2_LIBRARIES LibExiv2_INCLUDE_DIRS + VERSION_VAR LibExiv2_VERSION +) + +mark_as_advanced(LibExiv2_INCLUDE_DIRS LibExiv2_LIBRARIES) + +if(LibExiv2_FOUND AND NOT TARGET LibExiv2::LibExiv2) + add_library(LibExiv2::LibExiv2 UNKNOWN IMPORTED) + set_target_properties(LibExiv2::LibExiv2 PROPERTIES + IMPORTED_LOCATION "${LibExiv2_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${LibExiv2_INCLUDE_DIRS}" + ) +endif() + +include(FeatureSummary) +set_package_properties(LibExiv2 PROPERTIES + URL "http://www.exiv2.org" + DESCRIPTION "Image metadata support" +) diff --git a/config-krename.h.cmake b/config-krename.h.cmake index 862e40b..de25e6f 100644 --- a/config-krename.h.cmake +++ b/config-krename.h.cmake @@ -1,18 +1,21 @@ /* config.h. Generated by cmake from config.h.cmake */ /* have TagLib */ #cmakedefine01 HAVE_TAGLIB /* have Exiv2 */ #cmakedefine01 HAVE_EXIV2 +/* Defined if we have libexiv2 >= 0.27 */ +#cmakedefine01 HAVE_LIBEXIV2_0_27 + /* have PoDoFo */ #cmakedefine01 HAVE_PODOFO /* have KArchive */ #cmakedefine01 HAVE_KARCHIVE /* have Freetype */ #cmakedefine01 HAVE_FREETYPE #define VERSION "${krename_VERSION}" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1811fb0..3f262b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,167 +1,167 @@ add_subdirectory(pics) add_subdirectory(servicemenus) include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) if(TAGLIB_FOUND) include_directories(${TAGLIB_INCLUDES}) endif() if(EXIV2_FOUND) include_directories(${EXIV2_INCLUDE_DIR}) endif() if(PoDoFo_FOUND) include_directories(${PoDoFo_INCLUDE_DIRS}) add_definitions(${PoDoFo_DEFINITIONS}) endif() if(FREETYPE_FOUND) include_directories(${FREETYPE_INCLUDE_DIRS}) endif() -add_definitions(${TAGLIB_CFLAGS} ${EXIV2_CFLAGS}) +add_definitions(${TAGLIB_CFLAGS}) # Exiv2 needs exceptions kde_enable_exceptions() ########### next target ############### set(krename_SRCS main.cpp batchrenamer.cpp customdialog.cpp datetimeplugin.cpp dirsortplugin.cpp exthistorycombo.cpp filedialogextwidget.cpp fileplugin.cpp increasecounterplugin.cpp krenamefile.cpp krenameimpl.cpp krenamelistview.cpp krenamemodel.cpp krenametest.cpp krenametokensorter.cpp krenamewindow.cpp modeltest.cpp numberdialog.cpp insertpartfilenamedlg.cpp threadedlister.cpp plugin.cpp pluginloader.cpp permissionsplugin.cpp previewlist.cpp progressdialog.cpp replacedialog.cpp richtextitemdelegate.cpp scriptplugin.cpp startupinfo.cpp systemplugin.cpp tokenhelpdialog.cpp tokensortmodedialog.cpp translitplugin.cpp snumplugin.cpp ) -if(EXIV2_FOUND) +if(LibExiv2_FOUND) set(krename_SRCS ${krename_SRCS} exiv2plugin.cpp ) endif() if(TAGLIB_FOUND) set(krename_SRCS ${krename_SRCS} taglibplugin.cpp ) endif() if(PoDoFo_FOUND) set(krename_SRCS ${krename_SRCS} podofoplugin.cpp ) endif() if(FREETYPE_FOUND) set(krename_SRCS ${krename_SRCS} fontplugin.cpp ) endif() if(KF5Archive_FOUND) set(krename_SRCS ${krename_SRCS} odfplugin.cpp ) endif() ki18n_wrap_ui(krename_SRCS customfilenamedlg.ui datetimepluginwidget.ui dirsortpluginwidget.ui increasecounterpluginwidget.ui guimodeselector.ui partfilenamewidget.ui krenamefiles.ui krenamedestination.ui krenamefilename.ui krenameplugins.ui numberwidget.ui permissionspluginwidget.ui progressdialog.ui replacewidget.ui replaceitemdlg.ui scriptpluginwidget.ui scriptplugindialog.ui startupinfowidget.ui tokenhelpwidget.ui tokensortmodedialog.ui ) add_executable(krename ${krename_SRCS}) target_link_libraries(krename KF5::Crash KF5::KIOCore KF5::KIOFileWidgets KF5::I18n KF5::JSApi KF5::IconThemes Qt5::Widgets ) if(TAGLIB_FOUND) target_link_libraries(krename ${TAGLIB_LIBRARIES} ) endif() -if(EXIV2_FOUND) +if(LibExiv2_FOUND) target_link_libraries(krename - ${EXIV2_LIBRARIES} + LibExiv2::LibExiv2 ) endif() if(PoDoFo_FOUND) target_link_libraries(krename ${PoDoFo_LIBRARIES} ) endif() if(KF5Archive_FOUND) target_link_libraries(krename Qt5::Xml KF5::Archive ) endif() if(FREETYPE_FOUND) target_link_libraries(krename ${FREETYPE_LIBRARIES} ) endif() # Others Files to install install(TARGETS krename DESTINATION ${KDE_INSTALL_BINDIR}) install(PROGRAMS org.kde.krename.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES org.kde.krename.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) diff --git a/src/exiv2plugin.cpp b/src/exiv2plugin.cpp index 39ac9e7..8c5c1cf 100644 --- a/src/exiv2plugin.cpp +++ b/src/exiv2plugin.cpp @@ -1,433 +1,439 @@ /*************************************************************************** exiv2plugin.cpp - description ------------------- begin : Thu Oct 9th 2008 copyright : (C) 2008 by Dominik Seichter email : domseichter@web.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "exiv2plugin.h" +#include "../config-krename.h" + #include #include #include #include #include -#include +#ifdef HAVE_LIBEXIV2_0_27 + #include +#else + #include +#endif #include #include "batchrenamer.h" #include "tokenhelpdialog.h" using namespace Exiv2; static const char *exifTags[] = { "Exif.Image.ImageWidth", "Exif.Image.ImageLength", "Exif.Image.BitsPerSample", "Exif.Image.Compression", "Exif.Image.PhotometricInterpretation", "Exif.Image.Orientation", "Exif.Image.SamplesPerPixel", "Exif.Image.PlanarConfiguration", "Exif.Image.YCbCrSubSampling", "Exif.Image.YCbCrPositioning", "Exif.Image.XResolution", "Exif.Image.YResolution", "Exif.Image.ResolutionUnit", "Exif.Image.TransferFunction", "Exif.Image.WhitePoint", "Exif.Image.PrimaryChromaticities", "Exif.Image.YCbCrCoefficients", "Exif.Image.ReferenceBlackWhite", "Exif.Image.DateTime", "Exif.Image.ImageDescription", "Exif.Image.Make", "Exif.Image.Model", "Exif.Image.Software", "Exif.Image.Artist", "Exif.Image.Copyright", "Exif.Photo.ExifVersion", "Exif.Photo.FlashpixVersion", "Exif.Photo.ColorSpace", "Exif.Photo.ComponentsConfiguration", "Exif.Photo.CompressedBitsPerPixel", "Exif.Photo.PixelXDimension", "Exif.Photo.PixelYDimension", "Exif.Photo.UserComment", "Exif.Photo.RelatedSoundFile", "Exif.Photo.DateTimeOriginal", "Exif.Photo.DateTimeDigitized", "Exif.Photo.ExposureTime", "Exif.Photo.FNumber", "Exif.Photo.ExposureProgram", "Exif.Photo.SpectralSensitivity", "Exif.Photo.ISOSpeedRatings", "Exif.Photo.OECF", "Exif.Photo.ShutterSpeedValue", "Exif.Photo.ApertureValue", "Exif.Photo.BrightnessValue", "Exif.Photo.ExposureBiasValue", "Exif.Photo.MaxApertureValue", "Exif.Photo.SubjectDistance", "Exif.Photo.MeteringMode", "Exif.Photo.LightSource", "Exif.Photo.Flash", "Exif.Photo.FocalLength", "Exif.Photo.SubjectArea", "Exif.Photo.FlashEnergy", "Exif.Photo.SpatialFrequencyResponse", "Exif.Photo.FocalPlaneXResolution", "Exif.Photo.FocalPlaneYResolution", "Exif.Photo.FocalPlaneResolutionUnit", "Exif.Photo.SubjectLocation", "Exif.Photo.ExposureIndex", "Exif.Photo.SensingMethod", "Exif.Photo.FileSource", "Exif.Photo.SceneType", "Exif.Photo.CFAPattern", "Exif.Photo.CustomRendered", "Exif.Photo.ExposureMode", "Exif.Photo.WhiteBalance", "Exif.Photo.DigitalZoomRatio", "Exif.Photo.FocalLengthIn35mmFilm", "Exif.Photo.SceneCaptureType", "Exif.Photo.GainControl", "Exif.Photo.Contrast", "Exif.Photo.Saturation", "Exif.Photo.Sharpness", "Exif.Photo.DeviceSettingDescription", "Exif.Photo.SubjectDistanceRange", "Exif.Photo.ImageUniqueID", "Exif.GPSInfo.GPSVersionID", "Exif.GPSInfo.GPSLatitude", "Exif.GPSInfo.GPSLongitude", "Exif.GPSInfo.GPSAltitudeRef", "Exif.GPSInfo.GPSAltitude", "Exif.GPSInfo.GPSTimeStamp", "Exif.GPSInfo.GPSSatellites", "Exif.GPSInfo.GPSStatus", "Exif.GPSInfo.GPSMeasureMode", "Exif.GPSInfo.GPSDOP", "Exif.GPSInfo.GPSSpeedRef", "Exif.GPSInfo.GPSSpeed", "Exif.GPSInfo.GPSTrackRef", "Exif.GPSInfo.GPSTrack", "Exif.GPSInfo.GPSImgDirectionRef", "Exif.GPSInfo.GPSImgDirection", "Exif.GPSInfo.GPSMapDatum", "Exif.GPSInfo.GPSDestLatitude", "Exif.GPSInfo.GPSDestLongitude", "Exif.GPSInfo.GPSDestBearingRef", "Exif.GPSInfo.GPSDestBearing", "Exif.GPSInfo.GPSDestDistanceRef", "Exif.GPSInfo.GPSDestDistance", "Exif.GPSInfo.GPSProcessingMethod", "Exif.GPSInfo.GPSAreaInformation", "Exif.GPSInfo.GPSDifferential", nullptr }; static const char *xmpTags[] = { "Xmp.tiff.ImageWidth", "Xmp.tiff.ImageLength", "Xmp.tiff.BitsPerSample", "Xmp.tiff.Compression", "Xmp.tiff.PhotometricInterpretation", "Xmp.tiff.Orientation", "Xmp.tiff.SamplesPerPixe", "Xmp.tiff.PlanarConfiguration", "Xmp.tiff.YCbCrSubSampling", "Xmp.tiff.YCbCrPositioning", "Xmp.tiff.XResolution", "Xmp.tiff.YResolution", "Xmp.tiff.ResolutionUnit", "Xmp.tiff.TransferFunction", "Xmp.tiff.WhitePoint", "Xmp.tiff.PrimaryChromaticities", "Xmp.tiff.YCbCrCoefficients", "Xmp.tiff.ReferenceBlackWhite", "Xmp.tiff.DateTime", "Xmp.dc.description", "Xmp.tiff.Make", "Xmp.tiff.Model", "Xmp.tiff.Software", "Xmp.dc.creator", "Xmp.dc.rights", "Xmp.exif.ExifVersion", "Xmp.exif.FlashpixVersion", "Xmp.exif.ColorSpace", "Xmp.exif.ComponentsConfiguration", "Xmp.exif.CompressedBitsPerPixel", "Xmp.exif.PixelXDimension", "Xmp.exif.PixelYDimension", "Xmp.exif.UserComment", "Xmp.exif.RelatedSoundFile", "Xmp.exif.DateTimeOriginal", "Xmp.exif.DateTimeDigitized", "Xmp.exif.ExposureTime", "Xmp.exif.FNumber", "Xmp.exif.ExposureProgram", "Xmp.exif.SpectralSensitivity", "Xmp.exif.ISOSpeedRatings", "Xmp.exif.OECF", "Xmp.exif.ShutterSpeedValue", "Xmp.exif.ApertureValue", "Xmp.exif.BrightnessValue", "Xmp.exif.ExposureBiasValue", "Xmp.exif.MaxApertureValue", "Xmp.exif.SubjectDistance", "Xmp.exif.MeteringMode", "Xmp.exif.LightSource", "Xmp.exif.Flash", "Xmp.exif.FocalLength", "Xmp.exif.SubjectArea", "Xmp.exif.FlashEnergy", "Xmp.exif.SpatialFrequencyResponse", "Xmp.exif.FocalPlaneXResolution", "Xmp.exif.FocalPlaneYResolution", "Xmp.exif.FocalPlaneResolutionUnit", "Xmp.exif.SubjectLocation", "Xmp.exif.ExposureIndex", "Xmp.exif.SensingMethod", "Xmp.exif.FileSource", "Xmp.exif.SceneType", "Xmp.exif.CFAPattern", "Xmp.exif.CustomRendered", "Xmp.exif.ExposureMode", "Xmp.exif.WhiteBalance", "Xmp.exif.DigitalZoomRatio", "Xmp.exif.FocalLengthIn35mmFilm", "Xmp.exif.SceneCaptureType", "Xmp.exif.GainControl", "Xmp.exif.Contrast", "Xmp.exif.Saturation", "Xmp.exif.Sharpness", "Xmp.exif.DeviceSettingDescription", "Xmp.exif.SubjectDistanceRange", "Xmp.exif.ImageUniqueID", "Xmp.exif.GPSVersionID", "Xmp.exif.GPSLatitude", "Xmp.exif.GPSLongitude", "Xmp.exif.GPSAltitudeRef", "Xmp.exif.GPSAltitude", "Xmp.exif.GPSTimeStamp", "Xmp.exif.GPSSatellites", "Xmp.exif.GPSStatus", "Xmp.exif.GPSMeasureMode", "Xmp.exif.GPSDOP", "Xmp.exif.GPSSpeedRef", "Xmp.exif.GPSSpeed", "Xmp.exif.GPSTrackRef", "Xmp.exif.GPSTrack", "Xmp.exif.GPSImgDirectionRef", "Xmp.exif.GPSImgDirection", "Xmp.exif.GPSMapDatum", "Xmp.exif.GPSDestLatitude", "Xmp.exif.GPSDestLongitude", "Xmp.exif.GPSDestBearingRef", "Xmp.exif.GPSDestBearing", "Xmp.exif.GPSDestDistanceRef", "Xmp.exif.GPSDestDistance", "Xmp.exif.GPSProcessingMethod", "Xmp.exif.GPSAreaInformation", "Xmp.exif.GPSDifferential", "Xmp.dc.title", "Xmp.photoshop.Urgency", "Xmp.photoshop.Category", "Xmp.photoshop.SupplementalCategory", "Xmp.dc.subject", "Xmp.iptc.Location", "Xmp.photoshop.Instruction", "Xmp.photoshop.DateCreated", "Xmp.dc.creator", "Xmp.photoshop.AuthorsPosition", "Xmp.photoshop.City", "Xmp.photoshop.State", "Xmp.iptc.CountryCode", "Xmp.photoshop.Country", "Xmp.photoshop.TransmissionReference", "Xmp.photoshop.Headline", "Xmp.photoshop.Credit", "Xmp.photoshop.Source", "Xmp.dc.rights", "Xmp.dc.description", "Xmp.photoshop.CaptionWriter", nullptr }; static const char *iptcTags[] = { "Iptc.Application2.ObjectName", "Iptc.Application2.Urgency", "Iptc.Application2.Category", "Iptc.Application2.SuppCategory", "Iptc.Application2.Keywords", "Iptc.Application2.LocationName", "Iptc.Application2.SpecialInstructions", "Iptc.Application2.DateCreated", "Iptc.Application2.Byline", "Iptc.Application2.BylineTitle", "Iptc.Application2.City", "Iptc.Application2.ProvinceState", "Iptc.Application2.CountryCode", "Iptc.Application2.CountryName", "Iptc.Application2.TransmissionReference", "Iptc.Application2.Headline", "Iptc.Application2.Credit", "Iptc.Application2.Source", "Iptc.Application2.Copyright", "Iptc.Application2.Caption", "Iptc.Application2.Writer", nullptr }; Exiv2Plugin::Exiv2Plugin(PluginLoader *loader) : FilePlugin(loader) { const QString prefix("exif"); const char **token; this->addSupportedToken("exifComment"); //this->addSupportedToken("exifWidth"); //this->addSupportedToken("exifHeight"); m_help.append("[exifComment]" + TokenHelpDialog::getTokenSeparator() + i18n("Insert the comment of an image")); //m_help.append( "[exifWidth]" + TokenHelpDialog::getTokenSeparator() + i18n("Insert the width in pixel of an image") ); //m_help.append( "[exifHeight]" + TokenHelpDialog::getTokenSeparator() + i18n("Insert the height in pixel of an image") ); // Add exif taks token = exifTags; while (*token) { ExifKey key(*token); QString help; try { help = QString::fromUtf8(key.tagLabel().c_str()); } catch (std::exception e) { help = ""; // exiv2 throws sometimes exceptions // because it tries to create std::string from NULL pointers } QString cur(*token); this->addSupportedToken(prefix + cur); m_help.append(QString("[") + prefix + cur + QString("]") + TokenHelpDialog::getTokenSeparator() + help); m_mapRealKeys[QString(prefix + cur).toLower()] = cur; ++token; } // Add exif taks token = xmpTags; while (*token) { XmpKey key(*token); QString help; try { help = QString::fromUtf8(key.tagLabel().c_str()); } catch (std::exception e) { help = ""; // exiv2 throws sometimes exceptions // because it tries to create std::string from NULL pointers } QString cur(*token); this->addSupportedToken(prefix + cur); m_help.append(QString("[") + prefix + cur + QString("]") + TokenHelpDialog::getTokenSeparator() + help); m_mapRealKeys[QString(prefix + cur).toLower()] = cur; ++token; } // Add exif taks token = iptcTags; while (*token) { IptcKey key(*token); QString help; try { help = QString::fromUtf8(key.tagLabel().c_str()); } catch (std::exception e) { help = ""; // exiv2 throws sometimes exceptions // because it tries to create std::string from NULL pointers } QString cur(*token); this->addSupportedToken(prefix + cur); m_help.append(QString("[") + prefix + cur + QString("]") + TokenHelpDialog::getTokenSeparator() + help); m_mapRealKeys[QString(prefix + cur).toLower()] = cur; ++token; } m_name = i18n("Exiv2 (JPEG/TIFF Exif) Plugin"); m_comment = i18n("This plugin supports reading tags from " "JPEG and TIFF files."); m_icon = "image-x-generic"; } QString Exiv2Plugin::processFile(BatchRenamer *b, int index, const QString &filenameOrToken, EPluginType) { QString token(filenameOrToken.toLower()); QString filename = (*b->files())[index].srcUrl().path(); if (!this->supports(token)) { return QString(""); } //const QByteArray asc = filename.toAscii(); // Use toUtf8 so that unicode filenames will work const QByteArray asc = filename.toUtf8(); std::string strFilename(asc.constData(), asc.length()); try { Image::AutoPtr image = Exiv2::ImageFactory::open(strFilename); if (image.get() != nullptr && image->good()) { image->readMetadata(); if (token == "exifcomment") { return QString::fromUtf8(image->comment().c_str()); } /* else if( token =="exifwidth" ) return QString::number( image->pixelWidth() ); else if( token =="exifheight" ) return QString::number( image->pixelHeight() ); */ if (token.startsWith(QLatin1String("exifexif."))) { ExifKey key(m_mapRealKeys[token].toLatin1().data()); ExifData::const_iterator it = image->exifData().findKey(key); if (it != image->exifData().end()) { std::string val = (*it).toString(); return QString::fromUtf8(val.c_str()); } } else if (token.startsWith(QLatin1String("exifxmp."))) { XmpKey key(m_mapRealKeys[token].toLatin1().data()); XmpData::const_iterator it = image->xmpData().findKey(key); if (it != image->xmpData().end()) { std::string val = (*it).toString(); return QString::fromUtf8(val.c_str()); } } else if (token.startsWith(QLatin1String("exifiptc."))) { IptcKey key(m_mapRealKeys[token].toLatin1().data()); IptcData::const_iterator it = image->iptcData().findKey(key); if (it != image->iptcData().end()) { std::string val = (*it).toString(); return QString::fromUtf8(val.c_str()); } } } } catch (std::exception &err) { return QString::fromUtf8(err.what()); } return QString(""); }