diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index b38fc745c..67b856092 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1098,6 +1098,7 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con return IMIO_SUCCESS; } + int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool uncompressed) const { if (getWidth() < 1 || getHeight() < 1) { @@ -1168,6 +1169,31 @@ int ImageIO::saveTIFF (const Glib::ustring &fname, int bps, bool isFloat, bool u } }();*/ + // somehow Exiv2 (tested with 0.27.3) doesn't seem to be able to update + // XResolution and YResolution, so we do it ourselves here.... + constexpr float default_resolution = 300.f; + float x_res = default_resolution; + float y_res = default_resolution; + int res_unit = RESUNIT_INCH; + if (!metadataInfo.filename().empty()) { + auto exif = metadataInfo.getOutputExifData(); + auto it = exif.findKey(Exiv2::ExifKey("Exif.Image.XResolution")); + if (it != exif.end()) { + x_res = it->toFloat(); + } + it = exif.findKey(Exiv2::ExifKey("Exif.Image.YResolution")); + if (it != exif.end()) { + y_res = it->toFloat(); + } + it = exif.findKey(Exiv2::ExifKey("Exif.Image.ResolutionUnit")); + if (it != exif.end()) { + res_unit = it->toLong(); + } + } + TIFFSetField(out, TIFFTAG_XRESOLUTION, x_res); + TIFFSetField(out, TIFFTAG_YRESOLUTION, y_res); + TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, res_unit); + if (!uncompressed) { TIFFSetField (out, TIFFTAG_PREDICTOR, (bps == 16 || bps == 32) && isFloat ? PREDICTOR_FLOATINGPOINT : PREDICTOR_HORIZONTAL); } diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index c0bdcfa29..b6476f92a 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -390,7 +390,12 @@ void Exiv2Metadata::import_exif_pairs(Exiv2::ExifData &out) const for (auto &p : *exif_) { try { out[p.first] = p.second; - } catch (std::exception &exc) {} + } catch (std::exception &exc) { + if (settings->verbose) { + std::cout << "Error setting " << p.first << " to " << p.second + << ": " << exc.what() << std::endl; + } + } } } @@ -408,7 +413,12 @@ void Exiv2Metadata::import_iptc_pairs(Exiv2::IptcData &out) const out.add(d); } } - } catch (std::exception &exc) {} + } catch (std::exception &exc) { + if (settings->verbose) { + std::cout << "Error setting " << p.first + << ": " << exc.what() << std::endl; + } + } } } @@ -515,4 +525,30 @@ void Exiv2Metadata::cleanup() Exiv2::XmpParser::terminate(); } + +Exiv2::ExifData Exiv2Metadata::getOutputExifData() const +{ + Exiv2::ExifData exif = exifData(); + try { + auto xmp = getXmpSidecar(src_); + Exiv2::moveXmpToExif(xmp, exif); + } catch (std::exception &exc) { + if (settings->verbose) { + std::cerr << "Error loading metadata from XMP sidecar: " + << exc.what() << std::endl; + } + } + remove_unwanted(exif); + import_exif_pairs(exif); + for (auto it = exif.begin(); it != exif.end(); ) { + if (it->count() > 0) { + ++it; + } else { + it = exif.erase(it); + } + } + return exif; +} + + } // namespace rtengine diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 9de285111..cd27aada5 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -60,6 +60,8 @@ public: void getDimensions(int &w, int &h) const; + Exiv2::ExifData getOutputExifData() const; + static Glib::ustring xmpSidecarPath(const Glib::ustring& path); static Exiv2::XmpData getXmpSidecar(const Glib::ustring& path);