[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:41:11 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=f8197d8

The following commit has been merged in the master branch:
commit f8197d846375a3ae8203e560f68faf02b77c5d84
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Thu Apr 1 16:20:54 2010 +0000

    #668: In TIFF and TIFF-like images, never modify 'image tags'. This patch implements the basic idea.
---
 src/actions.cpp           |  94 +----------------------
 src/error.cpp             |   2 +
 src/error.hpp             |   1 +
 src/exif.cpp              |   2 +-
 src/tags.cpp              |   8 +-
 src/tiffcomposite.cpp     | 184 ++++++++++++++++++++++++++++++++++++++++------
 src/tiffcomposite_int.hpp | 135 ++++++++++++++++++++++++++++++++--
 src/tifffwd_int.hpp       |   4 +
 src/tiffimage.cpp         | 132 +++++++++++++++++++++++++++++++--
 src/tiffimage_int.hpp     |  82 ++++++++++++++++++---
 src/tiffvisitor.cpp       | 118 ++++++++++++++++++++++++++++-
 src/tiffvisitor_int.hpp   |  80 +++++++++++++++++++-
 test/tiff-test.sh         |   2 +-
 13 files changed, 695 insertions(+), 149 deletions(-)

diff --git a/src/actions.cpp b/src/actions.cpp
index de8e94c..0c6bf59 100644
--- a/src/actions.cpp
+++ b/src/actions.cpp
@@ -129,12 +129,6 @@ namespace {
                  bool preserve);
 
     /*!
-      @brief Test to distinguish between Exif and other tags in TIFF-like files.
-             Only Exif tags are copyed, deleted, added.
-     */
-    bool isExifTag(const Exiv2::Exifdatum& ed);
-
-    /*!
       @brief Rename a file according to a timestamp value.
 
       @param path The original file path. Contains the new path on exit.
@@ -967,15 +961,7 @@ namespace Action {
         if (Params::instance().verbose_ && image->exifData().count() > 0) {
             std::cout << _("Erasing Exif data from the file") << std::endl;
         }
-        // Todo: ORF files are crippled after this. Find out exactly which tags are required
-        if (   0 == strcmp(image->mimeType().c_str(), "image/tiff")
-            || 0 == strcmp(image->mimeType().c_str(), "image/x-olympus-orf")) {
-            Exiv2::ExifData& ed = image->exifData();
-            ed.erase(std::remove_if(ed.begin(), ed.end(), isExifTag), ed.end());
-        }
-        else {
-            image->clearExifData();
-        }
+        image->clearExifData();
         return 0;
     }
 
@@ -1913,23 +1899,7 @@ namespace {
                 std::cout << _("Writing Exif data from") << " " << source
                           << " " << _("to") << " " << target << std::endl;
             }
-            if (   0 == strcmp(targetImage->mimeType().c_str(), "image/tiff")
-                || 0 == strcmp(targetImage->mimeType().c_str(), "image/x-olympus-orf")) {
-                Exiv2::ExifData& ted = targetImage->exifData();
-                if (!preserve) {
-                    targetImage->readMetadata();
-                    ted.erase(std::remove_if(ted.begin(), ted.end(), isExifTag), ted.end());
-                }
-                const Exiv2::ExifData& sed = sourceImage->exifData();
-                for (Exiv2::ExifData::const_iterator pos = sed.begin(); pos != sed.end(); ++pos) {
-                    if (isExifTag(*pos)) {
-                        ted[pos->key()] = pos->value();
-                    }
-                }
-            }
-            else {
-                targetImage->setExifData(sourceImage->exifData());
-            }
+            targetImage->setExifData(sourceImage->exifData());
         }
         if (   Params::instance().target_ & Params::ctIptc
             && !sourceImage->iptcData().empty()) {
@@ -1975,66 +1945,6 @@ namespace {
         }
     };
 
-    bool isExifTag(const Exiv2::Exifdatum& ed)
-    {
-        // A somewhat random list of IFD0 tags which are considered as "Exif tags"
-        static const String exifTags[] = {
-            { "Exif.Image.ProcessingSoftware"      },
-            { "Exif.Image.DocumentName"            },
-            { "Exif.Image.ImageDescription"        },
-            { "Exif.Image.Make"                    },
-            { "Exif.Image.Model"                   },
-            { "Exif.Image.Software"                },
-            { "Exif.Image.DateTime"                },
-            { "Exif.Image.HostComputer"            },
-            { "Exif.Image.Artist"                  },
-            { "Exif.Image.XMLPacket"               },
-            { "Exif.Image.Rating"                  },
-            { "Exif.Image.RatingPercent"           },
-            { "Exif.Image.CFARepeatPatternDim"     },
-            { "Exif.Image.CFAPattern"              },
-            { "Exif.Image.BatteryLevel"            },
-            { "Exif.Image.IPTCNAA"                 },
-            { "Exif.Image.Copyright"               },
-            { "Exif.Image.ImageResources"          },
-            { "Exif.Image.ExifTag"                 },
-            { "Exif.Image.InterColorProfile"       },
-            { "Exif.Image.GPSTag"                  },
-            { "Exif.Image.XPTitle"                 },
-            { "Exif.Image.XPComment"               },
-            { "Exif.Image.XPAuthor"                },
-            { "Exif.Image.XPKeywords"              },
-            { "Exif.Image.XPSubject"               },
-            { "Exif.Image.PrintImageMatching"      },
-            { "Exif.Image.UniqueCameraModel"       },
-            { "Exif.Image.LocalizedCameraModel"    },
-            { "Exif.Image.CFAPlaneColor"           },
-            { "Exif.Image.CFALayout"               },
-            { "Exif.Image.CameraSerialNumber"      },
-            { "Exif.Image.LensInfo"                },
-            { "Exif.Image.OriginalRawFileName"     },
-            { "Exif.Image.ActiveArea"              },
-            { "Exif.Image.MaskedAreas"             },
-            { "Exif.Image.AsShotICCProfile"        },
-            { "Exif.Image.AsShotPreProfileMatrix"  },
-            { "Exif.Image.CurrentICCProfile"       },
-            { "Exif.Image.CurrentPreProfileMatrix" }
-        };
-
-        static const Exiv2::IfdId exifIfds[] = {
-            Exiv2::exifIfdId,
-            Exiv2::gpsIfdId,
-            Exiv2::iopIfdId
-        };
-
-        if (   0 != Exiv2::find(exifIfds, ed.ifdId())
-            || Exiv2::ExifTags::isMakerIfd(ed.ifdId())
-            || 0 != Exiv2::find(exifTags, ed.key().c_str())) {
-            return true;
-        }
-        return false;
-    } // isExifTag
-
     int renameFile(std::string& newPath, const struct tm* tm)
     {
         std::string path = newPath;
diff --git a/src/error.cpp b/src/error.cpp
index b7ca49e..5110479 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -115,6 +115,7 @@ namespace Exiv2 {
     {
     }
 
+    //! @cond IGNORE
     template<>
     void BasicError<char>::setMsg()
     {
@@ -147,6 +148,7 @@ namespace Exiv2 {
         wmsg_ = s2ws(msg);
 #endif
     }
+    //! @endcond
 
 #ifdef EXV_UNICODE_PATH
     template<>
diff --git a/src/error.hpp b/src/error.hpp
index 15644b0..c323e1c 100644
--- a/src/error.hpp
+++ b/src/error.hpp
@@ -133,6 +133,7 @@ namespace Exiv2 {
     private:
         //! @name Manipulators
         //@{
+        //! Assemble the error message from the arguments
         EXIV2API void setMsg();
         //@}
 
diff --git a/src/exif.cpp b/src/exif.cpp
index 03c10df..5dcbe4e 100644
--- a/src/exif.cpp
+++ b/src/exif.cpp
@@ -710,7 +710,7 @@ namespace Exiv2 {
 
         // Encode and check if the result fits into a JPEG Exif APP1 segment
         MemIo mio1;
-        std::auto_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder));
+        std::auto_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder, 0x00000008, false));
         WriteMethod wm = TiffParserWorker::encode(mio1,
                                                   pData,
                                                   size,
diff --git a/src/tags.cpp b/src/tags.cpp
index 88c74f7..f96d686 100644
--- a/src/tags.cpp
+++ b/src/tags.cpp
@@ -467,7 +467,7 @@ namespace Exiv2 {
                 "left blank, it is treated as unknown. Ex.) \"Camera owner, John "
                 "Smith; Photographer, Michael Brown; Image creator, Ken James\""),
                 ifd0Id, otherTags, asciiString, printValue),
-        TagInfo(0x013c, "HostComputer", N_("Host computer"),
+        TagInfo(0x013c, "HostComputer", N_("Host Computer"),
                 N_("This tag records information about the host computer used "
                 "to generate the image."),
                 ifd0Id, otherTags, asciiString, printValue),
@@ -481,6 +481,12 @@ namespace Exiv2 {
                 "Normally this tag is not necessary, since colorspace is "
                 "specified in the colorspace information tag (<ColorSpace>)."),
                 ifd0Id, imgCharacter, unsignedRational, printValue),
+        TagInfo(0x0140, "ColorMap", N_("Color Map"),
+                N_("A color map for palette color images. This field defines "
+                   "a Red-Green-Blue color map (often called a lookup table) "
+                   "for palette-color images. In a palette-color image, a "
+                   "pixel value is used to index into an RGB lookup table."),
+                ifd0Id, imgCharacter, unsignedShort, printValue),
         TagInfo(0x0142, "TileWidth", N_("Tile Width"),
                 N_("The tile width in pixels. This is the number of columns in each tile."),
                 ifd0Id, recOffset, unsignedShort, printValue), // TIFF tag
diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp
index 074240c..cd063f8 100644
--- a/src/tiffcomposite.cpp
+++ b/src/tiffcomposite.cpp
@@ -307,14 +307,14 @@ namespace Exiv2 {
             delete *i;
         }
         delete pNext_;
-    } // TiffDirectory::~TiffDirectory
+    }
 
     TiffSubIfd::~TiffSubIfd()
     {
         for (Ifds::iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
             delete *i;
         }
-    } // TiffSubIfd::~TiffSubIfd
+    }
 
     TiffEntryBase::~TiffEntryBase()
     {
@@ -322,7 +322,7 @@ namespace Exiv2 {
             delete[] pData_;
         }
         delete pValue_;
-    } // TiffEntryBase::~TiffEntryBase
+    }
 
     TiffEntry::~TiffEntry()
     {
@@ -347,7 +347,7 @@ namespace Exiv2 {
     TiffMnEntry::~TiffMnEntry()
     {
         delete mn_;
-    } // TiffMnEntry::~TiffMnEntry
+    }
 
     TiffIfdMakernote::~TiffIfdMakernote()
     {
@@ -359,12 +359,113 @@ namespace Exiv2 {
         for (Components::iterator i = elements_.begin(); i != elements_.end(); ++i) {
             delete *i;
         }
-    } // TiffBinaryArray::~TiffBinaryArray
+    }
 
     TiffBinaryElement::~TiffBinaryElement()
     {
     }
 
+    TiffEntryBase::TiffEntryBase(const TiffEntryBase& rhs)
+        : TiffComponent(rhs),
+          tiffType_(rhs.tiffType_),
+          count_(rhs.count_),
+          offset_(rhs.offset_),
+          size_(rhs.size_),
+          pData_(rhs.pData_),
+          isMalloced_(rhs.isMalloced_),
+          idx_(rhs.idx_),
+          pValue_(rhs.pValue_ ? rhs.pValue_->clone().release() : 0)
+    {
+        if (rhs.isMalloced_) {
+            pData_ = new byte[rhs.size_];
+            memcpy(pData_, rhs.pData_, rhs.size_);
+        }
+    }
+
+    TiffDirectory::TiffDirectory(const TiffDirectory& rhs)
+        : TiffComponent(rhs),
+          hasNext_(rhs.hasNext_),
+          pNext_(0)
+    {
+    }
+
+    TiffSubIfd::TiffSubIfd(const TiffSubIfd& rhs)
+        : TiffEntryBase(rhs),
+          newGroup_(rhs.newGroup_)
+    {
+    }
+
+    TiffBinaryArray::TiffBinaryArray(const TiffBinaryArray& rhs)
+        : TiffEntryBase(rhs),
+          cfgSelFct_(rhs.cfgSelFct_),
+          arraySet_(rhs.arraySet_),
+          arrayCfg_(rhs.arrayCfg_),
+          arrayDef_(rhs.arrayDef_),
+          defSize_(rhs.defSize_),
+          setSize_(rhs.setSize_),
+          origData_(rhs.origData_),
+          origSize_(rhs.origSize_),
+          pRoot_(rhs.pRoot_)
+    {
+    }
+
+    TiffComponent::AutoPtr TiffComponent::clone() const
+    {
+        return AutoPtr(doClone());
+    }
+
+    TiffEntry* TiffEntry::doClone() const
+    {
+        return new TiffEntry(*this);
+    }
+
+    TiffDataEntry* TiffDataEntry::doClone() const
+    {
+        return new TiffDataEntry(*this);
+    }
+
+    TiffImageEntry* TiffImageEntry::doClone() const
+    {
+        return new TiffImageEntry(*this);
+    }
+
+    TiffSizeEntry* TiffSizeEntry::doClone() const
+    {
+        return new TiffSizeEntry(*this);
+    }
+
+    TiffDirectory* TiffDirectory::doClone() const
+    {
+        return new TiffDirectory(*this);
+    }
+
+    TiffSubIfd* TiffSubIfd::doClone() const
+    {
+        return new TiffSubIfd(*this);
+    }
+
+    TiffMnEntry* TiffMnEntry::doClone() const
+    {
+        assert(false); // Not implemented
+        return 0;
+    }
+
+    TiffIfdMakernote* TiffIfdMakernote::doClone() const
+    {
+        assert(false); // Not implemented
+        return 0;
+    }
+
+    TiffBinaryArray* TiffBinaryArray::doClone() const
+    {
+        return new TiffBinaryArray(*this);
+    }
+
+    TiffBinaryElement* TiffBinaryElement::doClone() const
+    {
+        return new TiffBinaryElement(*this);
+    }
+
     int TiffComponent::idx() const
     {
         return 0;
@@ -652,17 +753,26 @@ namespace Exiv2 {
         return sz;
     } // TiffBinaryArray::addElement
 
-    TiffComponent* TiffComponent::addPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot)
+    TiffComponent* TiffComponent::addPath(uint16_t tag,
+                                          TiffPath& tiffPath,
+                                          TiffComponent* const pRoot,
+                                          TiffComponent::AutoPtr object)
     {
-        return doAddPath(tag, tiffPath, pRoot);
+        return doAddPath(tag, tiffPath, pRoot, object);
     } // TiffComponent::addPath
 
-    TiffComponent* TiffComponent::doAddPath(uint16_t  /*tag*/, TiffPath& /*tiffPath*/, TiffComponent* const /*pRoot*/)
+    TiffComponent* TiffComponent::doAddPath(uint16_t  /*tag*/,
+                                            TiffPath& /*tiffPath*/,
+                                            TiffComponent* const /*pRoot*/,
+                                            TiffComponent::AutoPtr /*object*/)
     {
         return this;
     } // TiffComponent::doAddPath
 
-    TiffComponent* TiffDirectory::doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot)
+    TiffComponent* TiffDirectory::doAddPath(uint16_t tag,
+                                            TiffPath& tiffPath,
+                                            TiffComponent* const pRoot,
+                                            TiffComponent::AutoPtr object)
     {
         assert(tiffPath.size() > 1);
         tiffPath.pop();
@@ -688,7 +798,13 @@ namespace Exiv2 {
             }
         }
         if (tc == 0) {
-            TiffComponent::AutoPtr atc = TiffCreator::create(tpi.extendedTag(), tpi.group());
+            TiffComponent::AutoPtr atc;
+            if (object.get() != 0) {
+                atc = object;
+            }
+            else {
+                atc = TiffCreator::create(tpi.extendedTag(), tpi.group());
+            }
             assert(atc.get() != 0);
 
             // Prevent dangling sub-IFD tags: Do not add a sub-IFD component without children.
@@ -702,10 +818,13 @@ namespace Exiv2 {
                 tc = this->addChild(atc);
             }
         }
-        return tc->addPath(tag, tiffPath, pRoot);
+        return tc->addPath(tag, tiffPath, pRoot, object);
     } // TiffDirectory::doAddPath
 
-    TiffComponent* TiffSubIfd::doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot)
+    TiffComponent* TiffSubIfd::doAddPath(uint16_t tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object)
     {
         assert(!tiffPath.empty());
         const TiffPathItem tpi1 = tiffPath.top();
@@ -725,14 +844,22 @@ namespace Exiv2 {
             }
         }
         if (tc == 0) {
-            TiffComponent::AutoPtr atc(new TiffDirectory(tpi1.tag(), tpi2.group()));
-            tc = addChild(atc);
+            if (object.get() != 0) {
+                tc = addChild(object);
+            }
+            else {
+                TiffComponent::AutoPtr atc(new TiffDirectory(tpi1.tag(), tpi2.group()));
+                tc = addChild(atc);
+            }
             setCount(static_cast<uint32_t>(ifds_.size()));
         }
-        return tc->addPath(tag, tiffPath, pRoot);
+        return tc->addPath(tag, tiffPath, pRoot, object);
     } // TiffSubIfd::doAddPath
 
-    TiffComponent* TiffMnEntry::doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot)
+    TiffComponent* TiffMnEntry::doAddPath(uint16_t tag,
+                                          TiffPath& tiffPath,
+                                          TiffComponent* const pRoot,
+                                          TiffComponent::AutoPtr object)
     {
         assert(!tiffPath.empty());
         const TiffPathItem tpi1 = tiffPath.top();
@@ -748,15 +875,21 @@ namespace Exiv2 {
             mn_ = TiffMnCreator::create(tpi1.tag(), tpi1.group(), mnGroup_);
             assert(mn_);
         }
-        return mn_->addPath(tag, tiffPath, pRoot);
+        return mn_->addPath(tag, tiffPath, pRoot, object);
     } // TiffMnEntry::doAddPath
 
-    TiffComponent* TiffIfdMakernote::doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot)
+    TiffComponent* TiffIfdMakernote::doAddPath(uint16_t tag,
+                                               TiffPath& tiffPath,
+                                               TiffComponent* const pRoot,
+                                               TiffComponent::AutoPtr object)
     {
-        return ifd_.addPath(tag, tiffPath, pRoot);
+        return ifd_.addPath(tag, tiffPath, pRoot, object);
     }
 
-    TiffComponent* TiffBinaryArray::doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot)
+    TiffComponent* TiffBinaryArray::doAddPath(uint16_t tag,
+                                              TiffPath& tiffPath,
+                                              TiffComponent* const pRoot,
+                                              TiffComponent::AutoPtr object)
     {
         pRoot_ = pRoot;
         if (tiffPath.size() == 1) {
@@ -780,14 +913,19 @@ namespace Exiv2 {
             }
         }
         if (tc == 0) {
-            TiffComponent::AutoPtr atc = TiffCreator::create(tpi.extendedTag(), tpi.group());
+            TiffComponent::AutoPtr atc;
+            if (object.get() != 0) {
+                atc = object;
+            }
+            else {
+                atc = TiffCreator::create(tpi.extendedTag(), tpi.group());
+            }
             assert(atc.get() != 0);
-
             assert(tpi.extendedTag() != Tag::next);
             tc = addChild(atc);
             setCount(static_cast<uint32_t>(elements_.size()));
         }
-        return tc->addPath(tag, tiffPath, pRoot);
+        return tc->addPath(tag, tiffPath, pRoot, object);
     } // TiffBinaryArray::doAddPath
 
     TiffComponent* TiffComponent::addChild(TiffComponent::AutoPtr tiffComponent)
diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp
index 5cfc7f8..e6fad18 100644
--- a/src/tiffcomposite_int.hpp
+++ b/src/tiffcomposite_int.hpp
@@ -230,10 +230,15 @@ namespace Exiv2 {
           @param tag      The tag of the new entry
           @param tiffPath A path from the TIFF root element to a TIFF entry.
           @param pRoot    Pointer to the root component of the TIFF composite.
+          @param object   TIFF component to add. If 0, the correct entry will be
+                          created.
 
           @return A pointer to the newly added TIFF entry.
          */
-        TiffComponent* addPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        TiffComponent* addPath(uint16_t tag,
+                               TiffPath& tiffPath,
+                               TiffComponent* const pRoot,
+                               AutoPtr object =AutoPtr(0));
         /*!
           @brief Add a child to the component. Default is to do nothing.
           @param tiffComponent Auto pointer to the component to add.
@@ -291,6 +296,12 @@ namespace Exiv2 {
         //! Return a pointer to the start of the binary representation of the component
         byte* start()                         const { return pStart_; }
         /*!
+          @brief Return an auto-pointer to a copy of itself (deep copy, but
+                 without any children). The caller owns this copy and the
+                 auto-pointer ensures that it will be deleted.
+         */
+        AutoPtr clone() const;
+        /*!
           @brief Write the IFD data of this component to a binary image.
                  Return the number of bytes written. Components derived from
                  TiffEntryBase implement this method if needed.
@@ -342,7 +353,10 @@ namespace Exiv2 {
         //! @name Protected Manipulators
         //@{
         //! Implements addPath(). The default implementation does nothing.
-        virtual TiffComponent* doAddPath(uint16_t  tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        virtual TiffComponent* doAddPath(uint16_t  tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object);
         //! Implements addChild(). The default implementation does nothing.
         virtual TiffComponent* doAddChild(AutoPtr tiffComponent);
         //! Implements addNext(). The default implementation does nothing.
@@ -360,6 +374,8 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        //! Internal virtual copy constructor, implements clone().
+        virtual TiffComponent* doClone() const =0;
         //! Implements writeData().
         virtual uint32_t doWriteData(IoWrapper& ioWrapper,
                                      ByteOrder byteOrder,
@@ -437,7 +453,7 @@ namespace Exiv2 {
     public:
         //! @name Creators
         //@{
-        //! Default constructor
+        //! Default constructor.
         TiffEntryBase(uint16_t tag, uint16_t group, TiffType tiffType =ttUndefined);
         //! Virtual destructor.
         virtual ~TiffEntryBase();
@@ -496,6 +512,12 @@ namespace Exiv2 {
         //@}
 
     protected:
+        //! @name Protected Creators
+        //@{
+        //! Copy constructor (used to implement clone()).
+        TiffEntryBase(const TiffEntryBase& rhs);
+        //@}
+
         //! @name Protected Manipulators
         //@{
         //! Implements encode().
@@ -551,6 +573,12 @@ namespace Exiv2 {
                                     ByteOrder byteOrder);
 
     private:
+        //! @name NOT implemented
+        //@{
+        //! Assignment operator.
+        TiffEntryBase& operator=(const TiffEntryBase& rhs);
+        //@}
+
         // DATA
         TiffType tiffType_;   //!< Field TIFF type
         uint32_t count_;      //!< The number of values of the indicated type
@@ -587,6 +615,11 @@ namespace Exiv2 {
         virtual void doEncode(TiffEncoder& encoder, const Exifdatum* datum);
         //@}
 
+        //! @name Protected Accessors
+        //@{
+        virtual TiffEntry* doClone() const;
+        //@}
+
     }; // class TiffEntry
 
     /*!
@@ -699,6 +732,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffDataEntry* doClone() const;
         /*!
           @brief Implements writeData(). Write the data area to the \em ioWrapper.
                  Return the number of bytes written.
@@ -774,6 +808,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffImageEntry* doClone() const;
         /*!
           @brief Implements writeData(). Write the image data area to the \em ioWrapper.
                  Return the number of bytes written.
@@ -842,6 +877,11 @@ namespace Exiv2 {
         virtual void doEncode(TiffEncoder& encoder, const Exifdatum* datum);
         //@}
 
+        //! @name Protected Accessors
+        //@{
+        virtual TiffSizeEntry* doClone() const;
+        //@}
+
     private:
         // DATA
         const uint16_t dtTag_;        //!< Tag of the entry with the data area
@@ -872,9 +912,18 @@ namespace Exiv2 {
         //@}
 
     protected:
+        //! @name Protected Creators
+        //@{
+        //! Copy constructor (used to implement clone()).
+        TiffDirectory(const TiffDirectory& rhs);
+        //@}
+
         //! @name Protected Manipulators
         //@{
-        virtual TiffComponent* doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        virtual TiffComponent* doAddPath(uint16_t tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object);
         virtual TiffComponent* doAddChild(TiffComponent::AutoPtr tiffComponent);
         virtual TiffComponent* doAddNext(TiffComponent::AutoPtr tiffComponent);
         virtual void doAccept(TiffVisitor& visitor);
@@ -893,6 +942,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffDirectory* doClone() const;
         /*!
           @brief This class does not really implement writeData(), it only has
                  write(). This method must not be called; it commits suicide.
@@ -933,6 +983,12 @@ namespace Exiv2 {
         //@}
 
     private:
+        //! @name NOT implemented
+        //@{
+        //! Assignment operator.
+        TiffDirectory& operator=(const TiffDirectory& rhs);
+        //@}
+
         //! @name Private Accessors
         //@{
         //! Write a binary directory entry for a TIFF component.
@@ -972,9 +1028,18 @@ namespace Exiv2 {
         //@}
 
     protected:
+        //! @name Protected Creators
+        //@{
+        //! Copy constructor (used to implement clone()).
+        TiffSubIfd(const TiffSubIfd& rhs);
+        //@}
+
         //! @name Protected Manipulators
         //@{
-        virtual TiffComponent* doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        virtual TiffComponent* doAddPath(uint16_t tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object);
         virtual TiffComponent* doAddChild(TiffComponent::AutoPtr tiffComponent);
         virtual void doAccept(TiffVisitor& visitor);
         virtual void doEncode(TiffEncoder& encoder, const Exifdatum* datum);
@@ -993,6 +1058,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffSubIfd* doClone() const;
         /*!
           @brief Implements writeData(). Write the sub-IFDs to the \em ioWrapper.
                  Return the number of bytes written.
@@ -1017,6 +1083,12 @@ namespace Exiv2 {
         //@}
 
     private:
+        //! @name NOT implemented
+        //@{
+        //! Assignment operator.
+        TiffSubIfd& operator=(const TiffSubIfd& rhs);
+        //@}
+
         //! A collection of TIFF directories (IFDs)
         typedef std::vector<TiffDirectory*> Ifds;
 
@@ -1049,7 +1121,10 @@ namespace Exiv2 {
     protected:
         //! @name Protected Manipulators
         //@{
-        virtual TiffComponent* doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        virtual TiffComponent* doAddPath(uint16_t tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object);
         virtual TiffComponent* doAddChild(TiffComponent::AutoPtr tiffComponent);
         virtual TiffComponent* doAddNext(TiffComponent::AutoPtr tiffComponent);
         virtual void doAccept(TiffVisitor& visitor);
@@ -1068,6 +1143,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffMnEntry* doClone() const;
         //! Implements count(). Return number of components in the entry.
         virtual uint32_t doCount() const;
         // Using doWriteData from base class
@@ -1082,6 +1158,14 @@ namespace Exiv2 {
         //@}
 
     private:
+        //! @name NOT implemented
+        //@{
+        //! Copy constructor.
+        TiffMnEntry(const TiffMnEntry& rhs);
+        //! Assignment operator.
+        TiffMnEntry& operator=(const TiffMnEntry& rhs);
+        //@}
+
         // DATA
         uint16_t       mnGroup_;             //!< New group for concrete mn
         TiffComponent* mn_;                  //!< The Makernote
@@ -1169,7 +1253,10 @@ namespace Exiv2 {
     protected:
         //! @name Protected Manipulators
         //@{
-        virtual TiffComponent* doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        virtual TiffComponent* doAddPath(uint16_t tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object);
         virtual TiffComponent* doAddChild(TiffComponent::AutoPtr tiffComponent);
         virtual TiffComponent* doAddNext(TiffComponent::AutoPtr tiffComponent);
         virtual void doAccept(TiffVisitor& visitor);
@@ -1188,6 +1275,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffIfdMakernote* doClone() const;
         /*!
           @brief This class does not really implement writeData(), it only has
                  write(). This method must not be called; it commits suicide.
@@ -1227,6 +1315,20 @@ namespace Exiv2 {
         //@}
 
     private:
+        /*!
+          @name NOT implemented
+
+          Implementing the copy constructor and assignment operator will require
+          cloning the header, i.e., clone() functionality on the MnHeader
+          hierarchy.
+         */
+        //@{
+        //! Copy constructor.
+        TiffIfdMakernote(const TiffIfdMakernote& rhs);
+        //! Assignment operator.
+        TiffIfdMakernote& operator=(const TiffIfdMakernote& rhs);
+        //@}
+
         // DATA
         MnHeader*     pHeader_;                 //!< Makernote header
         TiffDirectory ifd_;                     //!< Makernote IFD
@@ -1350,12 +1452,21 @@ namespace Exiv2 {
         //@}
 
     protected:
+        //! @name Protected Creators
+        //@{
+        //! Copy constructor (used to implement clone()).
+        TiffBinaryArray(const TiffBinaryArray& rhs);
+        //@}
+
         //! @name Protected Manipulators
         //@{
         /*!
           @brief Implements addPath(). Todo: Document it!
          */
-        virtual TiffComponent* doAddPath(uint16_t tag, TiffPath& tiffPath, TiffComponent* const pRoot);
+        virtual TiffComponent* doAddPath(uint16_t tag,
+                                         TiffPath& tiffPath,
+                                         TiffComponent* const pRoot,
+                                         TiffComponent::AutoPtr object);
         /*!
           @brief Implements addChild(). Todo: Document it!
          */
@@ -1375,6 +1486,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffBinaryArray* doClone() const;
         //! Implements count(). Todo: Document it!
         virtual uint32_t doCount() const;
         // Using doWriteData from base class
@@ -1388,6 +1500,12 @@ namespace Exiv2 {
         //@}
 
     private:
+        //! @name NOT implemented
+        //@{
+        //! Assignment operator.
+        TiffBinaryArray& operator=(const TiffBinaryArray& rhs);
+        //@}
+
         // DATA
         const CfgSelFct cfgSelFct_; //!< Pointer to a function to determine which cfg to use (may be 0)
         const ArraySet* arraySet_;  //!< Pointer to the array set, if any (may be 0)
@@ -1457,6 +1575,7 @@ namespace Exiv2 {
 
         //! @name Protected Accessors
         //@{
+        virtual TiffBinaryElement* doClone() const;
         /*!
           @brief Implements count(). Returns the count from the element definition.
          */
diff --git a/src/tifffwd_int.hpp b/src/tifffwd_int.hpp
index 7889a4e..76bb9ad 100644
--- a/src/tifffwd_int.hpp
+++ b/src/tifffwd_int.hpp
@@ -36,6 +36,7 @@
 // + standard includes
 #include <memory>
 #include <stack>
+#include <vector>
 
 // *****************************************************************************
 // Exiv2 namespace extensions
@@ -109,6 +110,9 @@ namespace Exiv2 {
     //! Stack to hold a path from the TIFF root element to a TIFF entry
     typedef std::stack<TiffPathItem> TiffPath;
 
+    //! Type for a list of primary image groups
+    typedef std::vector<uint16_t> PrimaryGroups;
+
 }}                                      // namespace Internal, Exiv2
 
 #endif                                  // #ifndef TIFFFWD_INT_HPP_
diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp
index 3ce8ef9..fe1f862 100644
--- a/src/tiffimage.cpp
+++ b/src/tiffimage.cpp
@@ -1406,28 +1406,38 @@ namespace Exiv2 {
         assert(pHeader);
         assert(pHeader->byteOrder() != invalidByteOrder);
         WriteMethod writeMethod = wmIntrusive;
-        TiffComponent::AutoPtr createdTree;
         TiffComponent::AutoPtr parsedTree = parse(pData, size, root, pHeader);
+        PrimaryGroups primaryGroups;
+        findPrimaryGroups(primaryGroups, parsedTree.get());
         if (0 != parsedTree.get()) {
             // Attempt to update existing TIFF components based on metadata entries
             TiffEncoder encoder(exifData,
                                 iptcData,
                                 xmpData,
                                 parsedTree.get(),
-                                pHeader->byteOrder(),
+                                false,
+                                &primaryGroups,
+                                pHeader,
                                 findEncoderFct);
             parsedTree->accept(encoder);
             if (!encoder.dirty()) writeMethod = wmNonIntrusive;
         }
         if (writeMethod == wmIntrusive) {
-            createdTree = TiffCreator::create(root, Group::none);
+            TiffComponent::AutoPtr createdTree = TiffCreator::create(root, Group::none);
+            if (0 != parsedTree.get()) {
+                // Copy image tags from the original image to the composite
+                TiffCopier copier(createdTree.get(), root, pHeader, &primaryGroups);
+                parsedTree->accept(copier);
+            }
+            // Add entries from metadata to composite
             TiffEncoder encoder(exifData,
                                 iptcData,
                                 xmpData,
                                 createdTree.get(),
-                                pHeader->byteOrder(),
+                                parsedTree.get() == 0,
+                                &primaryGroups,
+                                pHeader,
                                 findEncoderFct);
-            // Add entries from metadata to composite
             encoder.add(createdTree.get(), parsedTree.get(), root);
             // Write binary representation from the composite tree
             DataBuf header = pHeader->write();
@@ -1478,6 +1488,41 @@ namespace Exiv2 {
 
     } // TiffParserWorker::parse
 
+    void TiffParserWorker::findPrimaryGroups(PrimaryGroups& primaryGroups,
+                                             TiffComponent* pSourceDir)
+    {
+        if (0 == pSourceDir) return;
+
+        const uint16_t imageGroups[] = {
+            Group::ifd0,
+            Group::ifd1,
+            Group::ifd2,
+            Group::ifd3,
+            Group::subimg1,
+            Group::subimg2,
+            Group::subimg3,
+            Group::subimg4,
+            Group::subimg5,
+            Group::subimg6,
+            Group::subimg7,
+            Group::subimg8,
+            Group::subimg9
+        };
+
+        for (unsigned int i = 0; i < EXV_COUNTOF(imageGroups); ++i) {
+            TiffFinder finder(0x00fe, imageGroups[i]);
+            pSourceDir->accept(finder);
+            TiffEntryBase* te = dynamic_cast<TiffEntryBase*>(finder.result());
+            if (   te
+                && te->pValue()->typeId() == unsignedLong
+                && te->pValue()->count() == 1
+                && (te->pValue()->toLong() & 1) == 0) {
+                primaryGroups.push_back(te->group());
+            }
+        }
+
+    } // TiffParserWorker::findPrimaryGroups
+
     TiffHeaderBase::TiffHeaderBase(uint16_t  tag,
                                    uint32_t  size,
                                    ByteOrder byteOrder,
@@ -1578,8 +1623,16 @@ namespace Exiv2 {
         return tag_;
     }
 
-    TiffHeader::TiffHeader(ByteOrder byteOrder, uint32_t offset)
-        : TiffHeaderBase(42, 8, byteOrder, offset)
+    bool TiffHeaderBase::isImageTag(uint16_t /*tag*/,
+                                    uint16_t /*group*/,
+                                    const PrimaryGroups* /*primaryGroups*/) const
+    {
+        return false;
+    }
+
+    TiffHeader::TiffHeader(ByteOrder byteOrder, uint32_t offset, bool hasImageTags)
+        : TiffHeaderBase(42, 8, byteOrder, offset),
+          hasImageTags_(hasImageTags)
     {
     }
 
@@ -1587,4 +1640,69 @@ namespace Exiv2 {
     {
     }
 
+    //! List of TIFF image tags
+    extern const TiffImgTagStruct tiffImageTags[] = {
+        { 0x0100, Group::ifd0 }, // Exif.Image.ImageWidth
+        { 0x0101, Group::ifd0 }, // Exif.Image.ImageLength
+        { 0x0102, Group::ifd0 }, // Exif.Image.BitsPerSample
+        { 0x0103, Group::ifd0 }, // Exif.Image.Compression
+        { 0x0106, Group::ifd0 }, // Exif.Image.PhotometricInterpretation
+        { 0x0111, Group::ifd0 }, // Exif.Image.StripOffsets
+        { 0x0115, Group::ifd0 }, // Exif.Image.SamplesPerPixel
+        { 0x0116, Group::ifd0 }, // Exif.Image.RowsPerStrip 
+        { 0x0117, Group::ifd0 }, // Exif.Image.StripByteCounts
+        { 0x011a, Group::ifd0 }, // Exif.Image.XResolution
+        { 0x011b, Group::ifd0 }, // Exif.Image.YResolution
+        { 0x0128, Group::ifd0 }, // Exif.Image.ResolutionUnit
+        { 0x0140, Group::ifd0 }  // Exif.Image.ColorMap
+    };
+
+    bool TiffHeader::isImageTag(      uint16_t       tag,
+                                      uint16_t       group,
+                                const PrimaryGroups* pPrimaryGroups) const
+    {
+        if (!hasImageTags_) {
+#ifdef DEBUG
+            std::cerr << "No image tags in this image
";
+#endif
+            return false;
+        }
+#ifdef DEBUG
+        ExifKey key(tag, tiffGroupName(group));
+#endif
+        // If there are primary groups and none matches group, we're done
+        if (   pPrimaryGroups != 0
+            && !pPrimaryGroups->empty()
+            && std::find(pPrimaryGroups->begin(), pPrimaryGroups->end(), group)
+               == pPrimaryGroups->end()) {
+#ifdef DEBUG
+            std::cerr << "Not an image tag: " << key << " (1)
";
+#endif
+            return false;
+        }
+        // All tags of marked primary groups other than IFD0 are considered
+        // image tags. That should take care of NEFs until we know better.
+        if (   pPrimaryGroups != 0
+            && !pPrimaryGroups->empty()
+            && group != Group::ifd0) {
+#ifdef DEBUG
+            ExifKey key(tag, tiffGroupName(group));
+            std::cerr << "Image tag: " << key << " (2)
";
+#endif
+            return true;
+        }
+        // If tag, group is one of the image tags listed above -> bingo!
+        if (find(tiffImageTags, TiffImgTagStruct::Key(tag, group))) {
+#ifdef DEBUG
+            ExifKey key(tag, tiffGroupName(group));
+            std::cerr << "Image tag: " << key << " (3)
";
+#endif
+            return true;
+        }
+#ifdef DEBUG
+        std::cerr << "Not an image tag: " << key << " (4)
";
+#endif
+        return false;
+    }
+
 }}                                       // namespace Internal, Exiv2
diff --git a/src/tiffimage_int.hpp b/src/tiffimage_int.hpp
index f3b3b6d..727b2d9 100644
--- a/src/tiffimage_int.hpp
+++ b/src/tiffimage_int.hpp
@@ -109,8 +109,25 @@ namespace Exiv2 {
         virtual uint32_t offset() const;
         //! Return the size (in bytes) of the image header.
         virtual uint32_t size() const;
-        //! Return the tag value (magic number) which identifies the buffer as TIFF data
+        //! Return the tag value (magic number) which identifies the buffer as TIFF data.
         virtual uint16_t tag() const;
+        /*!
+          @brief Return 
-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list