[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a
Maximiliano Curia
maxy at moszumanska.debian.org
Thu Jul 13 17:40:07 UTC 2017
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=8e905ca
The following commit has been merged in the master branch:
commit 8e905cacc34f92e83730d9c6fd15a26a30717478
Author: Andreas Huggel <ahuggel at gmx.net>
Date: Sun Nov 16 02:35:53 2008 +0000
Fixed duplicate makernote issue, introduced logic to try and fit Exif data for JPEG in a 64kB block.
---
src/exif.cpp | 192 ++++++++++++++++++++++++++++++++++++++++++++++----
src/tiffcomposite.cpp | 10 +--
2 files changed, 185 insertions(+), 17 deletions(-)
diff --git a/src/exif.cpp b/src/exif.cpp
index 3c78fc2..9d6cd7a 100644
--- a/src/exif.cpp
+++ b/src/exif.cpp
@@ -141,6 +141,12 @@ namespace {
}; // class JpegThumbnail
+ //! Helper function to sum all components of the value of a metadatum
+ long sumToLong(const Exiv2::Exifdatum& md);
+
+ //! Helper function to delete all tags of a specific IFD from the metadata.
+ void eraseIfd(Exiv2::ExifData& ed, const char* ifdItem);
+
}
// *****************************************************************************
@@ -438,6 +444,14 @@ namespace Exiv2 {
return bo;
} // ExifParser::decode
+ //! @cond IGNORE
+ enum Ptt { pttLen, pttTag, pttIfd };
+ struct PreviewTags {
+ Ptt ptt_;
+ const char* key_;
+ };
+ //! @endcond
+
WriteMethod ExifParser::encode(
Blob& blob,
const byte* pData,
@@ -446,27 +460,153 @@ namespace Exiv2 {
const ExifData& exifData
)
{
- static const char* filteredTags[] = {
+ ExifData ed = exifData;
+ ed.sortByKey();
+
+ // Delete IFD0 tags that are "not recorded" in compressed images
+ // Reference: Exif 2.2 specs, 4.6.8 Tag Support Levels, section A
+ static const char* filteredIfd0Tags[] = {
+ "Exif.Image.PhotometricInterpretation",
"Exif.Image.StripOffsets",
"Exif.Image.RowsPerStrip",
- "Exif.Image.StripByteCounts"
+ "Exif.Image.StripByteCounts",
+ "Exif.Image.JPEGInterchangeFormat",
+ "Exif.Image.JPEGInterchangeFormatLength",
+ "Exif.Image.SubIFDs"
};
+ for (unsigned int i = 0; i < EXV_COUNTOF(filteredIfd0Tags); ++i) {
+ ExifData::iterator pos = ed.findKey(ExifKey(filteredIfd0Tags[i]));
+ if (pos != ed.end()) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Exif tag " << pos->key() << " not encoded
";
+#endif
+ ed.erase(pos);
+ }
+ }
- ExifData ed = exifData;
- for (unsigned int i = 0; i < EXV_COUNTOF(filteredTags); ++i) {
- ExifData::iterator pos = ed.findKey(ExifKey(filteredTags[i]));
- if (pos != ed.end()) ed.erase(pos);
+ // Delete IFDs which do not occur in JPEGs
+ static const char* filteredIfds[] = {
+ "SubImage1",
+ "SubImage2",
+ "SubImage3",
+ "SubImage4",
+ "Image2"
+ };
+ for (unsigned int i = 0; i < EXV_COUNTOF(filteredIfds); ++i) {
+ eraseIfd(ed, filteredIfds[i]);
}
+ // IPTC and XMP are stored elsewhere, not in the Exif APP1 segment.
const IptcData iptcData;
const XmpData xmpData;
- return TiffParser::encode(blob,
- pData,
- size,
- byteOrder,
- ed,
- iptcData,
- xmpData);
+
+ // Encode and check if the results fits into a JPEG Exif APP1 segment
+ WriteMethod wm = TiffParser::encode(blob,
+ pData,
+ size,
+ byteOrder,
+ ed,
+ iptcData,
+ xmpData);
+ if (blob.size() <= 65527) return wm;
+
+ // If it doesn't fit, remove additional tags
+ blob.clear();
+
+ // Delete preview tags if the preview is larger than 32kB.
+ // Todo: Enhance preview classes to be able to write and delete previews and use that instead.
+ // Table must be sorted by preview, the first tag in each group is the size
+ static const PreviewTags filteredPvTags[] = {
+ { pttLen, "Exif.Minolta.ThumbnailLength" },
+ { pttTag, "Exif.Minolta.ThumbnailOffset" },
+ { pttLen, "Exif.Minolta.Thumbnail" },
+ { pttLen, "Exif.NikonPreview.JPEGInterchangeFormatLength" },
+ { pttIfd, "NikonPreview" },
+ { pttLen, "Exif.Olympus.ThumbnailLength" },
+ { pttTag, "Exif.Olympus.ThumbnailOffset" },
+ { pttTag, "Exif.Olympus.ThumbnailImage" },
+ { pttTag, "Exif.Olympus.Thumbnail" },
+ { pttLen, "Exif.Olympus2.ThumbnailLength" },
+ { pttTag, "Exif.Olympus2.ThumbnailOffset" },
+ { pttLen, "Exif.Olympus2.ThumbnailImage" },
+ { pttLen, "Exif.Olympus2.Thumbnail" },
+ { pttLen, "Exif.OlympusCs.PreviewImageLength" },
+ { pttTag, "Exif.OlympusCs.PreviewImageStart" },
+ { pttTag, "Exif.OlympusCs.PreviewImageValid" },
+ { pttLen, "Exif.Pentax.PreviewLength" },
+ { pttTag, "Exif.Pentax.PreviewOffset" },
+ { pttTag, "Exif.Pentax.PreviewResolution" },
+ { pttLen, "Exif.Thumbnail.StripByteCounts" },
+ { pttIfd, "Thumbnail" },
+ { pttLen, "Exif.Thumbnail.JPEGInterchangeFormatLength" },
+ { pttIfd, "Thumbnail" }
+ };
+ bool delTags = false;
+ ExifData::iterator pos;
+ for (unsigned int i = 0; i < EXV_COUNTOF(filteredPvTags); ++i) {
+ switch (filteredPvTags[i].ptt_) {
+ case pttLen:
+ delTags = false;
+ pos = ed.findKey(ExifKey(filteredPvTags[i].key_));
+ if (pos != ed.end() && sumToLong(*pos) > 32768) {
+ delTags = true;
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Exif tag " << pos->key() << " not encoded
";
+#endif
+ ed.erase(pos);
+ }
+ break;
+ case pttTag:
+ if (delTags) {
+ pos = ed.findKey(ExifKey(filteredPvTags[i].key_));
+ if (pos != ed.end()) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Exif tag " << pos->key() << " not encoded
";
+#endif
+ ed.erase(pos);
+ }
+ }
+ break;
+ case pttIfd:
+ if (delTags) {
+ eraseIfd(ed, filteredPvTags[i].key_);
+ }
+ break;
+ }
+ }
+
+ // Delete unknown tags larger than 4kB.
+ for (ExifData::iterator pos = ed.begin(); pos != ed.end(); ) {
+ if ( pos->size() > 4096
+ && pos->tagName().substr(0, 2) == "0x") {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Exif tag " << pos->key() << " not encoded
";
+#endif
+ pos = ed.erase(pos);
+ }
+ else {
+ ++pos;
+ }
+ }
+
+ // Encode the remaining Exif tags again, don't care if it fits this time
+ wm = TiffParser::encode(blob,
+ pData,
+ size,
+ byteOrder,
+ ed,
+ iptcData,
+ xmpData);
+#ifdef DEBUG
+ if (wm == wmIntrusive) {
+ std::cerr << "SIZE OF EXIF DATA IS " << std::dec << blob.size() << " BYTES
";
+ }
+ else {
+ std::cerr << "SIZE DOESN'T MATTER, NON-INTRUSIVE WRITING USED
";
+ }
+#endif
+ return wm;
+
} // ExifParser::encode
} // namespace Exiv2
@@ -546,5 +686,31 @@ namespace {
if (format == exifData.end()) return Exiv2::DataBuf();
return format->dataArea();
}
+
+ long sumToLong(const Exiv2::Exifdatum& md)
+ {
+ long sum = 0;
+ for (int i = 0; i < md.count(); ++i) {
+ sum += md.toLong(i);
+ }
+ return sum;
+ }
+
+ void eraseIfd(Exiv2::ExifData& ed, const char* ifdItem)
+ {
+ // Prerequisite: Exif metadata must be sorted by IFD
+ Exiv2::ExifData::iterator pos;
+ for (pos = ed.begin(); pos != ed.end(); ++pos) {
+ if (0 == strcmp(pos->ifdItem().c_str(), ifdItem)) {
+#ifndef SUPPRESS_WARNINGS
+ std::cerr << "Warning: Exif IFD " << ifdItem << " not encoded
";
+#endif
+ break;
+ }
+ }
+ while (pos != ed.end() && 0 == strcmp(pos->ifdItem().c_str(), ifdItem)) {
+ pos = ed.erase(pos);
+ }
+ }
//! @endcond
}
diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp
index 7282429..9b64dd6 100644
--- a/src/tiffcomposite.cpp
+++ b/src/tiffcomposite.cpp
@@ -382,10 +382,12 @@ namespace Exiv2 {
// Prevent dangling subIFD tags: Do not add a subIFD tag if it has no child
if (tiffPath.size() == 1 && ts->newTiffCompFct_ == newTiffSubIfd) return 0;
TiffComponent* tc = 0;
- // To allow duplicate entries, we only check if the new component already
- // exists if there is still at least one composite tag on the stack
- // Todo: Find a generic way to require subIFDs to be unique tags
- if (tiffPath.size() > 1 || ts->newTiffCompFct_ == newTiffSubIfd) {
+ // Allow duplicate entries but not for subIFDs and the MakerNote tag. So we
+ // only check if the new component already exists if there is still at least
+ // one composite tag on the stack, or it is a subIFD or the MakerNote tag.
+ if ( tiffPath.size() > 1
+ || ts->newTiffCompFct_ == newTiffSubIfd
+ || (ts->extendedTag_ == 0x927c && ts->group_ == Group::exif)) {
if (ts->extendedTag_ == Tag::next) {
tc = pNext_;
}
--
exiv2 packaging
More information about the pkg-kde-commits
mailing list