diff --git a/src/tiffimage_int.cpp b/src/tiffimage_int.cpp index 60bc023959..a268e8de34 100644 --- a/src/tiffimage_int.cpp +++ b/src/tiffimage_int.cpp @@ -2071,7 +2071,8 @@ WriteMethod TiffParserWorker::encode(BasicIo& io, const byte* pData, size_t size auto primaryGroups = findPrimaryGroups(parsedTree); if (parsedTree) { // Attempt to update existing TIFF components based on metadata entries - TiffEncoder encoder(exifData, iptcData, xmpData, parsedTree.get(), false, primaryGroups, pHeader, findEncoderFct); + TiffEncoder encoder(std::make_unique(exifData), iptcData, xmpData, parsedTree.get(), false, primaryGroups, + pHeader, findEncoderFct); parsedTree->accept(encoder); if (!encoder.dirty()) writeMethod = wmNonIntrusive; @@ -2084,8 +2085,8 @@ WriteMethod TiffParserWorker::encode(BasicIo& io, const byte* pData, size_t size parsedTree->accept(copier); } // Add entries from metadata to composite - TiffEncoder encoder(exifData, iptcData, xmpData, createdTree.get(), !parsedTree, std::move(primaryGroups), pHeader, - findEncoderFct); + TiffEncoder encoder(std::make_unique(exifData), iptcData, xmpData, createdTree.get(), !parsedTree, + std::move(primaryGroups), pHeader, findEncoderFct); encoder.add(createdTree.get(), std::move(parsedTree), root); // Write binary representation from the composite tree DataBuf header = pHeader->write(); diff --git a/src/tiffvisitor_int.cpp b/src/tiffvisitor_int.cpp index 9f3b769917..e916d0016a 100644 --- a/src/tiffvisitor_int.cpp +++ b/src/tiffvisitor_int.cpp @@ -440,9 +440,9 @@ void TiffDecoder::visitBinaryElement(TiffBinaryElement* object) { decodeTiffEntry(object); } -TiffEncoder::TiffEncoder(ExifData exifData, const IptcData& iptcData, const XmpData& xmpData, TiffComponent* pRoot, - bool isNewImage, PrimaryGroups pPrimaryGroups, const TiffHeaderBase* pHeader, - FindEncoderFct findEncoderFct) : +TiffEncoder::TiffEncoder(std::unique_ptr exifData, const IptcData& iptcData, const XmpData& xmpData, + TiffComponent* pRoot, bool isNewImage, PrimaryGroups pPrimaryGroups, + const TiffHeaderBase* pHeader, FindEncoderFct findEncoderFct) : exifData_(std::move(exifData)), iptcData_(iptcData), xmpData_(xmpData), @@ -458,7 +458,7 @@ TiffEncoder::TiffEncoder(ExifData exifData, const IptcData& iptcData, const XmpD // Find camera make ExifKey key("Exif.Image.Make"); - if (auto pos = exifData_.findKey(key); pos != exifData_.end()) { + if (auto pos = exifData_->findKey(key); pos != exifData_->end()) { make_ = pos->toString(); } if (make_.empty() && pRoot_) { @@ -471,6 +471,8 @@ TiffEncoder::TiffEncoder(ExifData exifData, const IptcData& iptcData, const XmpD } } +TiffEncoder::~TiffEncoder() = default; + void TiffEncoder::encodeIptc() { // Update IPTCNAA Exif tag, if it exists. Delete the tag if there // is no IPTC data anymore. @@ -478,19 +480,19 @@ void TiffEncoder::encodeIptc() { // not exist, create a new IPTCNAA Exif tag. bool del = false; ExifKey iptcNaaKey("Exif.Image.IPTCNAA"); - auto pos = exifData_.findKey(iptcNaaKey); - if (pos != exifData_.end()) { + auto pos = exifData_->findKey(iptcNaaKey); + if (pos != exifData_->end()) { iptcNaaKey.setIdx(pos->idx()); - exifData_.erase(pos); + exifData_->erase(pos); del = true; } DataBuf rawIptc = IptcParser::encode(iptcData_); ExifKey irbKey("Exif.Image.ImageResources"); - pos = exifData_.findKey(irbKey); - if (pos != exifData_.end()) { + pos = exifData_->findKey(irbKey); + if (pos != exifData_->end()) { irbKey.setIdx(pos->idx()); } - if (!rawIptc.empty() && (del || pos == exifData_.end())) { + if (!rawIptc.empty() && (del || pos == exifData_->end())) { auto value = Value::create(unsignedLong); DataBuf buf; if (rawIptc.size() % 4 != 0) { @@ -502,21 +504,21 @@ void TiffEncoder::encodeIptc() { } value->read(buf.data(), buf.size(), byteOrder_); Exifdatum iptcDatum(iptcNaaKey, value.get()); - exifData_.add(iptcDatum); - pos = exifData_.findKey(irbKey); // needed after add() + exifData_->add(iptcDatum); + pos = exifData_->findKey(irbKey); // needed after add() } // Also update IPTC IRB in Exif.Image.ImageResources if it exists, // but don't create it if not. - if (pos != exifData_.end()) { + if (pos != exifData_->end()) { DataBuf irbBuf(pos->value().size()); pos->value().copy(irbBuf.data(), invalidByteOrder); irbBuf = Photoshop::setIptcIrb(irbBuf.c_data(), irbBuf.size(), iptcData_); - exifData_.erase(pos); + exifData_->erase(pos); if (!irbBuf.empty()) { auto value = Value::create(unsignedByte); value->read(irbBuf.data(), irbBuf.size(), invalidByteOrder); Exifdatum iptcDatum(irbKey, value.get()); - exifData_.add(iptcDatum); + exifData_->add(iptcDatum); } } } // TiffEncoder::encodeIptc @@ -525,9 +527,9 @@ void TiffEncoder::encodeXmp() { #ifdef EXV_HAVE_XMP_TOOLKIT ExifKey xmpKey("Exif.Image.XMLPacket"); // Remove any existing XMP Exif tag - if (auto pos = exifData_.findKey(xmpKey); pos != exifData_.end()) { + if (auto pos = exifData_->findKey(xmpKey); pos != exifData_->end()) { xmpKey.setIdx(pos->idx()); - exifData_.erase(pos); + exifData_->erase(pos); } std::string xmpPacket; if (xmpData_.usePacket()) { @@ -544,7 +546,7 @@ void TiffEncoder::encodeXmp() { auto value = Value::create(unsignedByte); value->read(reinterpret_cast(xmpPacket.data()), xmpPacket.size(), invalidByteOrder); Exifdatum xmpDatum(xmpKey, value.get()); - exifData_.add(xmpDatum); + exifData_->add(xmpDatum); } #endif } // TiffEncoder::encodeXmp @@ -555,7 +557,7 @@ void TiffEncoder::setDirty(bool flag) { } bool TiffEncoder::dirty() const { - return dirty_ || !exifData_.empty(); + return dirty_ || !exifData_->empty(); } void TiffEncoder::visitEntry(TiffEntry* object) { @@ -617,15 +619,15 @@ void TiffEncoder::visitMnEntry(TiffMnEntry* object) { } else if (del_) { // The makernote is made up of decoded tags, delete binary tag ExifKey key(object->tag(), groupName(object->group())); - auto pos = exifData_.findKey(key); - if (pos != exifData_.end()) - exifData_.erase(pos); + auto pos = exifData_->findKey(key); + if (pos != exifData_->end()) + exifData_->erase(pos); } } void TiffEncoder::visitIfdMakernote(TiffIfdMakernote* object) { - auto pos = exifData_.findKey(ExifKey("Exif.MakerNote.ByteOrder")); - if (pos != exifData_.end()) { + auto pos = exifData_->findKey(ExifKey("Exif.MakerNote.ByteOrder")); + if (pos != exifData_->end()) { // Set Makernote byte order ByteOrder bo = stringToByteOrder(pos->toString()); if (bo != invalidByteOrder && bo != object->byteOrder()) { @@ -633,7 +635,7 @@ void TiffEncoder::visitIfdMakernote(TiffIfdMakernote* object) { setDirty(); } if (del_) - exifData_.erase(pos); + exifData_->erase(pos); } if (del_) { // Remove remaining synthesized tags @@ -641,9 +643,9 @@ void TiffEncoder::visitIfdMakernote(TiffIfdMakernote* object) { "Exif.MakerNote.Offset", }; for (auto synthesizedTag : synthesizedTags) { - pos = exifData_.findKey(ExifKey(synthesizedTag)); - if (pos != exifData_.end()) - exifData_.erase(pos); + pos = exifData_->findKey(ExifKey(synthesizedTag)); + if (pos != exifData_->end()) + exifData_->erase(pos); } } // Modify encoder for Makernote peculiarities, byte order @@ -704,18 +706,18 @@ bool TiffEncoder::isImageTag(uint16_t tag, IfdId group) const { } void TiffEncoder::encodeTiffComponent(TiffEntryBase* object, const Exifdatum* datum) { - auto pos = exifData_.end(); + auto pos = exifData_->end(); const Exifdatum* ed = datum; if (!ed) { // Non-intrusive writing: find matching tag ExifKey key(object->tag(), groupName(object->group())); - pos = exifData_.findKey(key); - if (pos != exifData_.end()) { + pos = exifData_->findKey(key); + if (pos != exifData_->end()) { ed = &(*pos); if (object->idx() != pos->idx()) { // Try to find exact match (in case of duplicate tags) - auto pos2 = std::find_if(exifData_.begin(), exifData_.end(), FindExifdatum2(object->group(), object->idx())); - if (pos2 != exifData_.end() && pos2->key() == key.key()) { + auto pos2 = std::find_if(exifData_->begin(), exifData_->end(), FindExifdatum2(object->group(), object->idx())); + if (pos2 != exifData_->end() && pos2->key() == key.key()) { ed = &(*pos2); pos = pos2; // make sure we delete the correct tag below } @@ -743,8 +745,8 @@ void TiffEncoder::encodeTiffComponent(TiffEntryBase* object, const Exifdatum* da object->encode(*this, ed); } } - if (del_ && pos != exifData_.end()) { - exifData_.erase(pos); + if (del_ && pos != exifData_->end()) { + exifData_->erase(pos); } #ifdef EXIV2_DEBUG_MESSAGES std::cerr << "\n"; @@ -809,9 +811,9 @@ void TiffEncoder::encodeImageEntry(TiffImageEntry* object, const Exifdatum* datu #endif // Set pseudo strips (without a data pointer) from the size tag ExifKey key(object->szTag(), groupName(object->szGroup())); - auto pos = exifData_.findKey(key); + auto pos = exifData_->findKey(key); const byte* zero = nullptr; - if (pos == exifData_.end()) { + if (pos == exifData_->end()) { #ifndef SUPPRESS_WARNINGS EXV_ERROR << "Size tag " << key << " not found. Writing only one strip.\n"; #endif @@ -920,8 +922,8 @@ void TiffEncoder::add(TiffComponent* pRootDir, TiffComponent::UniquePtr pSourceD // iterate over all remaining entries. del_ = false; - auto posBo = exifData_.end(); - for (auto i = exifData_.begin(); i != exifData_.end(); ++i) { + auto posBo = exifData_->end(); + for (auto i = exifData_->begin(); i != exifData_->end(); ++i) { IfdId group = groupId(i->groupName()); // Skip synthesized info tags if (group == IfdId::mnId) { @@ -958,7 +960,7 @@ void TiffEncoder::add(TiffComponent* pRootDir, TiffComponent::UniquePtr pSourceD visit/encodeIfdMakernote is not called in this case and there can't be an Exif tag which corresponds to this component. */ - if (posBo == exifData_.end()) + if (posBo == exifData_->end()) return; TiffFinder finder(0x927c, IfdId::exifId); diff --git a/src/tiffvisitor_int.hpp b/src/tiffvisitor_int.hpp index 1a814553fb..7e3b80e111 100644 --- a/src/tiffvisitor_int.hpp +++ b/src/tiffvisitor_int.hpp @@ -4,8 +4,6 @@ #define TIFFVISITOR_INT_HPP_ // ***************************************************************************** -// included header files -#include "exif.hpp" #include "tiffcomposite_int.hpp" @@ -337,13 +335,13 @@ class TiffEncoder : public TiffVisitor { to, the image with the metadata to encode and a function to find special encoders. */ - TiffEncoder(ExifData exifData, const IptcData& iptcData, const XmpData& xmpData, TiffComponent* pRoot, - bool isNewImage, PrimaryGroups pPrimaryGroups, const TiffHeaderBase* pHeader, + TiffEncoder(std::unique_ptr exifData, const IptcData& iptcData, const XmpData& xmpData, + TiffComponent* pRoot, bool isNewImage, PrimaryGroups pPrimaryGroups, const TiffHeaderBase* pHeader, FindEncoderFct findEncoderFct); TiffEncoder(const TiffEncoder&) = delete; TiffEncoder& operator=(const TiffEncoder&) = delete; //! Virtual destructor - ~TiffEncoder() override = default; + ~TiffEncoder() override; //@} //! @name Manipulators @@ -497,7 +495,7 @@ class TiffEncoder : public TiffVisitor { //@} // DATA - ExifData exifData_; //!< Copy of the Exif data to encode + std::unique_ptr exifData_; //!< Copy of the Exif data to encode const IptcData& iptcData_; //!< IPTC data to encode, just a reference const XmpData& xmpData_; //!< XMP data to encode, just a reference bool del_{true}; //!< Indicates if Exif data entries should be deleted after encoding