From 0ac49e4d9a111ac03b275ef0718a0ed44162ca43 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 13 May 2023 15:31:14 -0700 Subject: [PATCH] Support Exiv2 >= v0.28.0 The various Datum classes no longer have the toLong method and must be replaced with toInt64. ErrorCode is an enum class instead of an enum. Error classes are reduced to Exiv2::Error. --- rtengine/imagedata.cc | 65 ++++++++++++++++++++++++++----------------- rtengine/imageio.cc | 15 +++++++++- rtengine/metadata.cc | 36 ++++++++++++++++++++---- 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 71d5c5693..4ff918c21 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -50,6 +50,19 @@ const std::string& validateUft8(const std::string& str, const std::string& on_er return on_error; } +template +auto to_long(const Iterator &iter, Integer n = Integer{0}) -> decltype( +#if EXIV2_TEST_VERSION(0,28,0) + iter->toInt64() +) { + return iter->toInt64(n); +#else + iter->toLong() +) { + return iter->toLong(n); +#endif +} + } namespace rtengine { @@ -269,7 +282,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : const int length = 12; if (pos->count() >= index + length) { for (int i = 0; i < length; ++i) { - serial += static_cast(pos->toLong(index + i)); + serial += static_cast(to_long(pos, index + i)); } serial = validateUft8(serial); } @@ -313,7 +326,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : "Rotate 270 CW", "Unknown" }; - auto idx = pos->toLong(); + auto idx = to_long(pos); if (idx >= 0 && idx < long(ormap.size())) { orientation = ormap[idx]; } @@ -322,14 +335,14 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : if (!make.compare(0, 5, "NIKON")) { if (find_exif_tag("Exif.NikonLd4.LensID")) { - if (!pos->toLong()) { // No data, look in LensIDNumber. + if (!to_long(pos)) { // No data, look in LensIDNumber. const auto p = pos; if (!find_exif_tag("Exif.NikonLd4.LensIDNumber")) { pos = p; // Tag not found, so reset pos. } } lens = pos->print(&exif); - if (lens == std::to_string(pos->toLong())) { // Not known to Exiv2. + if (lens == std::to_string(to_long(pos))) { // Not known to Exiv2. lens.clear(); } else { lens = validateUft8(lens); @@ -347,9 +360,9 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : (!find_exif_tag("Exif.Image.Model") || (pos->toString().compare(0, 4, "ILCE") && pos->toString().compare(0, 3, "NEX"))) && // LensID exists. - find_exif_tag("Exif.Sony2.LensID") && pos->toLong()) { + find_exif_tag("Exif.Sony2.LensID") && to_long(pos)) { lens = pos->print(&exif); - if (lens == std::to_string(pos->toLong())) { // Not known to Exiv2. + if (lens == std::to_string(to_long(pos))) { // Not known to Exiv2. lens.clear(); } else { lens = validateUft8(lens); @@ -363,7 +376,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : auto p = pos; if (find_exif_tag("Exif.CanonFi.RFLensType") && find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); - } else if (p->count() == 1 && lens == std::to_string(p->toLong())) { + } else if (p->count() == 1 && lens == std::to_string(to_long(p))) { if (find_exif_tag("Exif.Canon.LensModel")) { lens = validateUft8(pos->print(&exif)); } else if (find_exif_tag("Exif.Photo.LensModel")) { @@ -421,11 +434,11 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } if (find_exif_tag("Exif.Image.Rating")) { - rating = pos->toLong(); + rating = to_long(pos); } else { auto it = meta.xmpData().findKey(Exiv2::XmpKey("Xmp.xmp.Rating")); if (it != meta.xmpData().end() && it->size()) { - rating = it->toLong(); + rating = to_long(it); } } @@ -501,8 +514,8 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : || find_exif_tag("Exif.PentaxDng.Quality") ) && ( - pos->toLong() == 7 - || pos->toLong() == 8 + to_long(pos) == 7 + || to_long(pos) == 8 ) ) { isPixelShift = true; @@ -513,23 +526,23 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } if (make == "SONY") { - if (find_exif_tag("Exif.SubImage1.BitsPerSample") && pos->toLong() == 14) { - if (find_exif_tag("Exif.SubImage1.SamplesPerPixel") && pos->toLong() == 4 && - find_exif_tag("Exif.SubImage1.PhotometricInterpretation") && pos->toLong() == 32892 && - find_exif_tag("Exif.SubImage1.Compression") && pos->toLong() == 1) { + if (find_exif_tag("Exif.SubImage1.BitsPerSample") && to_long(pos) == 14) { + if (find_exif_tag("Exif.SubImage1.SamplesPerPixel") && to_long(pos) == 4 && + find_exif_tag("Exif.SubImage1.PhotometricInterpretation") && to_long(pos) == 32892 && + find_exif_tag("Exif.SubImage1.Compression") && to_long(pos) == 1) { isPixelShift = true; } - } else if (bps != exif.end() && bps->toLong() == 14 && - spp != exif.end() && spp->toLong() == 4 && - c != exif.end() && c->toLong() == 1 && + } else if (bps != exif.end() && to_long(bps) == 14 && + spp != exif.end() && to_long(spp) == 4 && + c != exif.end() && to_long(c) == 1 && find_exif_tag("Exif.Image.Software") && pos->toString() == "make_arq") { isPixelShift = true; } } else if (make == "FUJIFILM") { - if (bps != exif.end() && bps->toLong() == 16 && - spp != exif.end() && spp->toLong() == 4 && - c != exif.end() && c->toLong() == 1 && + if (bps != exif.end() && to_long(bps) == 16 && + spp != exif.end() && to_long(spp) == 4 && + c != exif.end() && to_long(c) == 1 && find_exif_tag("Exif.Image.Software") && pos->toString() == "make_arq") { isPixelShift = true; @@ -548,22 +561,22 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : { sampleformat = SAMPLEFORMAT_UINT; } else { - sampleformat = sf->toLong(); + sampleformat = to_long(sf); } if (bps == exif.end() || spp == exif.end() || pi == exif.end()) { return; } - bitspersample = bps->toLong(); - samplesperpixel = spp->toLong(); + bitspersample = to_long(bps); + samplesperpixel = to_long(spp); - photometric = pi->toLong(); + photometric = to_long(pi); if (photometric == PHOTOMETRIC_LOGLUV) { if (c == exif.end()) { compression = COMPRESSION_NONE; } else { - compression = c->toLong(); + compression = to_long(c); } } diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 0388467be..1c8e9016d 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -86,6 +86,19 @@ FILE* g_fopen_withBinaryAndLock(const Glib::ustring& fname) return f; } +template +auto to_long(const Iterator &iter, Integer n = Integer{0}) -> decltype( +#if EXIV2_TEST_VERSION(0,28,0) + iter->toInt64() +) { + return iter->toInt64(n); +#else + iter->toLong() +) { + return iter->toLong(n); +#endif +} + } void ImageIO::setMetadata(Exiv2Metadata info) @@ -1185,7 +1198,7 @@ int ImageIO::saveTIFF ( } it = exif.findKey(Exiv2::ExifKey("Exif.Image.ResolutionUnit")); if (it != exif.end()) { - res_unit = it->toLong(); + res_unit = to_long(it); } } TIFFSetField(out, TIFFTAG_XRESOLUTION, x_res); diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 28a9c1742..0a55c1424 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -31,6 +31,13 @@ #include "../rtgui/pathutils.h" +#if EXIV2_TEST_VERSION(0,28,0) +using Exiv2Error = Exiv2::Error; +#else +using Exiv2Error = Exiv2::AnyError; +#endif + + namespace rtengine { extern const Settings *settings; @@ -39,9 +46,13 @@ std::unique_ptr Exiv2Metadata::cache_(nullptr); namespace { -class Error: public Exiv2::AnyError { +class Error: public Exiv2Error { public: - Error(const std::string &msg): msg_(msg) {} + Error(const std::string &msg): +#if EXIV2_TEST_VERSION(0,28,0) + Exiv2Error(Exiv2::ErrorCode::kerGeneralError), +#endif + msg_(msg) {} const char *what() const throw() { return msg_.c_str(); } int code() const throw() { return 0; } @@ -71,7 +82,7 @@ std::unique_ptr open_exiv2(const Glib::ustring& fname, image->readMetadata(); if (!image->good() || (check_exif && image->exifData().empty())) { #if EXIV2_TEST_VERSION(0,27,0) - auto error_code = Exiv2::kerErrorMessage; + auto error_code = Exiv2::ErrorCode::kerErrorMessage; #else auto error_code = 1; #endif @@ -95,6 +106,19 @@ void clear_metadata_key(Data &data, const Key &key) } } +template +auto to_long(const Iterator &iter, Integer n = Integer{0}) -> decltype( +#if EXIV2_TEST_VERSION(0,28,0) + iter->toInt64() +) { + return iter->toInt64(n); +#else + iter->toLong() +) { + return iter->toLong(n); +#endif +} + } // namespace @@ -297,7 +321,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag dst->writeMetadata(); return; } catch (Exiv2::Error &exc) { - if (exc.code() == 37) { + if (exc.code() == Exiv2::ErrorCode::kerTooLargeJpegSegment) { std::string msg = exc.what(); if (msg.find("XMP") != std::string::npos && !dst->xmpData().empty()) { @@ -519,8 +543,8 @@ void Exiv2Metadata::getDimensions(int &w, int &h) const auto itw = exif.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth")); auto ith = exif.findKey(Exiv2::ExifKey("Exif.Image.ImageLength")); if (itw != exif.end() && ith != exif.end()) { - w = itw->toLong(); - h = ith->toLong(); + w = to_long(itw); + h = to_long(ith); } else { w = h = -1; }