Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/tiffimage_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>(exifData), iptcData, xmpData, parsedTree.get(), false, primaryGroups,
pHeader, findEncoderFct);
parsedTree->accept(encoder);
if (!encoder.dirty())
writeMethod = wmNonIntrusive;
Expand All @@ -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>(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();
Expand Down
82 changes: 42 additions & 40 deletions src/tiffvisitor_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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> 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),
Expand All @@ -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_) {
Expand All @@ -471,26 +471,28 @@ 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.
// If there is new IPTC data and Exif.Image.ImageResources does
// 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) {
Expand All @@ -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
Expand All @@ -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()) {
Expand All @@ -544,7 +546,7 @@ void TiffEncoder::encodeXmp() {
auto value = Value::create(unsignedByte);
value->read(reinterpret_cast<const byte*>(xmpPacket.data()), xmpPacket.size(), invalidByteOrder);
Exifdatum xmpDatum(xmpKey, value.get());
exifData_.add(xmpDatum);
exifData_->add(xmpDatum);
}
#endif
} // TiffEncoder::encodeXmp
Expand All @@ -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) {
Expand Down Expand Up @@ -617,33 +619,33 @@ 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()) {
object->setByteOrder(bo);
setDirty();
}
if (del_)
exifData_.erase(pos);
exifData_->erase(pos);
}
if (del_) {
// Remove remaining synthesized tags
static constexpr auto synthesizedTags = std::array{
"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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 4 additions & 6 deletions src/tiffvisitor_int.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#define TIFFVISITOR_INT_HPP_

// *****************************************************************************
// included header files
#include "exif.hpp"

#include "tiffcomposite_int.hpp"

Expand Down Expand Up @@ -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> 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
Expand Down Expand Up @@ -497,7 +495,7 @@ class TiffEncoder : public TiffVisitor {
//@}

// DATA
ExifData exifData_; //!< Copy of the Exif data to encode
std::unique_ptr<ExifData> 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
Expand Down
Loading