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

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:39:42 UTC 2017


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

The following commit has been merged in the master branch:
commit 009a214c9582b36f31383b8ce710a4b8bb470d8b
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Sat Aug 16 15:31:03 2008 +0000

    Improved handling of sub-IFDs when writing (relevant eg., for TIFF/EP and NEF formats).
---
 src/makernote2.cpp        |  20 +++---
 src/makernote2_int.hpp    |  16 +++--
 src/tags.cpp              |  20 ++++--
 src/tiffcomposite.cpp     | 157 +++++++++++++++++++++++++++++++---------------
 src/tiffcomposite_int.hpp |  94 ++++++++++++++-------------
 src/tiffimage.cpp         |  53 +++++++++++-----
 src/tiffvisitor.cpp       |  46 +-------------
 src/tiffvisitor_int.hpp   |  11 ----
 src/types.hpp             |   1 +
 9 files changed, 221 insertions(+), 197 deletions(-)

diff --git a/src/makernote2.cpp b/src/makernote2.cpp
index 6be8fee..5df6278 100644
--- a/src/makernote2.cpp
+++ b/src/makernote2.cpp
@@ -186,7 +186,7 @@ namespace Exiv2 {
                                        int32_t   offset,
                                        uint32_t  /*valueIdx*/,
                                        uint32_t  /*dataIdx*/,
-                                       uint32_t  imageIdx)
+                                       uint32_t& imageIdx)
     {
         if (this->byteOrder() != invalidByteOrder) {
             byteOrder = this->byteOrder();
@@ -203,19 +203,20 @@ namespace Exiv2 {
                                            ByteOrder /*byteOrder*/,
                                            int32_t   /*offset*/,
                                            uint32_t  /*dataIdx*/,
-                                           uint32_t  /*imageIdx*/) const
+                                           uint32_t& /*imageIdx*/) const
     {
         assert(false);
         return 0;
     } // TiffIfdMakernote::doWriteData
 
-    uint32_t TiffIfdMakernote::doWriteImage(Blob&     /*blob*/,
-                                            ByteOrder /*byteOrder*/,
-                                            int32_t   /*offset*/,
-                                            uint32_t  /*imageIdx*/) const
+    uint32_t TiffIfdMakernote::doWriteImage(Blob&     blob,
+                                            ByteOrder byteOrder) const
     {
-        assert(false);
-        return 0;
+        if (this->byteOrder() != invalidByteOrder) {
+            byteOrder = this->byteOrder();
+        }
+        uint32_t len = ifd_.writeImage(blob, byteOrder);
+        return len;
     } // TiffIfdMakernote::doWriteImage
 
     uint32_t TiffIfdMakernote::doSize() const
@@ -236,8 +237,7 @@ namespace Exiv2 {
 
     uint32_t TiffIfdMakernote::doSizeImage() const
     {
-        assert(false);
-        return 0;
+        return ifd_.sizeImage();
     } // TiffIfdMakernote::doSizeImage
 
     const byte OlympusMnHeader::signature_[] = {
diff --git a/src/makernote2_int.hpp b/src/makernote2_int.hpp
index 6bfbb58..720c03d 100644
--- a/src/makernote2_int.hpp
+++ b/src/makernote2_int.hpp
@@ -275,7 +275,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -287,15 +287,13 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const;
+                                     uint32_t& imageIdx) const;
         /*!
-          @brief This class does not really implement writeImage(), it only has
-                 write(). This method must not be called; it commits suicide.
+          @brief Implements writeImage(). Write the image data of the IFD of
+                 the Makernote. Return the number of bytes written.
          */
         virtual uint32_t doWriteImage(Blob&     blob,
-                                      ByteOrder byteOrder,
-                                      int32_t   offset,
-                                      uint32_t  imageIdx) const;
+                                      ByteOrder byteOrder) const;
         /*!
           @brief Implements size(). Return the size of the Makernote header,
                  TIFF directory, values and additional data.
@@ -313,8 +311,8 @@ namespace Exiv2 {
          */
         virtual uint32_t doSizeData() const;
         /*!
-          @brief This class does not really implement sizeData(), it only has
-                 size(). This method must not be called; it commits suicide.
+          @brief Implements sizeImage(). Return the total image data size of the
+                 makernote IFD.
          */
         virtual uint32_t doSizeImage() const;
         //@}
diff --git a/src/tags.cpp b/src/tags.cpp
index 6065a61..b7690a7 100644
--- a/src/tags.cpp
+++ b/src/tags.cpp
@@ -86,6 +86,10 @@ namespace Exiv2 {
         { gpsIfdId,          "GPSInfo",   "GPSInfo",      ExifTags::gpsTagList           },
         { iopIfdId,          "Iop",       "Iop",          ExifTags::iopTagList           },
         { ifd1Id,            "IFD1",      "Thumbnail",    ExifTags::ifdTagList           },
+        { subImage1Id,       "SubImage1", "SubImage1",    ExifTags::ifdTagList           },
+        { subImage2Id,       "SubImage2", "SubImage2",    ExifTags::ifdTagList           },
+        { subImage3Id,       "SubImage3", "SubImage3",    ExifTags::ifdTagList           },
+        { subImage4Id,       "SubImage4", "SubImage4",    ExifTags::ifdTagList           },
         { canonIfdId,        "Makernote", "Canon",        CanonMakerNote::tagList        },
         { canonCsIfdId,      "Makernote", "CanonCs",      CanonMakerNote::tagListCs      },
         { canonSiIfdId,      "Makernote", "CanonSi",      CanonMakerNote::tagListSi      },
@@ -1262,12 +1266,16 @@ namespace Exiv2 {
     {
         bool rc;
         switch (ifdId) {
-        case ifd0Id:    rc = true; break;
-        case exifIfdId: rc = true; break;
-        case gpsIfdId:  rc = true; break;
-        case iopIfdId:  rc = true; break;
-        case ifd1Id:    rc = true; break;
-        default:        rc = false; break;
+        case ifd0Id:
+        case exifIfdId:
+        case gpsIfdId:
+        case iopIfdId:
+        case ifd1Id:
+        case subImage1Id:
+        case subImage2Id:
+        case subImage3Id:
+        case subImage4Id: rc = true; break;
+        default:          rc = false; break;
         }
         return rc;
     } // ExifTags::isExifIfd
diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp
index 08f5a7c..3f55793 100644
--- a/src/tiffcomposite.cpp
+++ b/src/tiffcomposite.cpp
@@ -72,10 +72,10 @@ namespace Exiv2 {
         {   3, "Photo"        },
         {   4, "GPSInfo"      },
         {   5, "Iop"          },
-        {   6, "ImageSubIfd0" },
-        {   7, "ImageSubIfd1" },
-        {   8, "ImageSubIfd2" },
-        {   9, "ImageSubIfd3" },
+        {   6, "SubImage1"    },
+        {   7, "SubImage2"    },
+        {   8, "SubImage3"    },
+        {   9, "SubImage4"    },
         { 257, "Olympus"      },
         { 258, "Fujifilm"     },
         { 259, "Canon"        },
@@ -325,7 +325,7 @@ namespace Exiv2 {
                           << "Directory " << tiffGroupName(group())
                           << ", entry 0x" << std::setw(4)
                           << std::setfill('0') << std::hex << tag()
-                          << ": Strip " << i
+                          << ": Strip " << std::dec << i
                           << " is outside of the data area; ignored.
";
             }
 #endif
@@ -668,7 +668,7 @@ namespace Exiv2 {
                                   int32_t   offset,
                                   uint32_t  valueIdx,
                                   uint32_t  dataIdx,
-                                  uint32_t  imageIdx)
+                                  uint32_t& imageIdx)
     {
         return doWrite(blob, byteOrder, offset, valueIdx, dataIdx, imageIdx);
     } // TiffComponent::write
@@ -678,8 +678,10 @@ namespace Exiv2 {
                                     int32_t   offset,
                                     uint32_t  valueIdx,
                                     uint32_t  dataIdx,
-                                    uint32_t  imageIdx)
+                                    uint32_t& imageIdx)
     {
+        bool isRootDir = (imageIdx == uint32_t(-1));
+
         // Number of components to write
         const uint32_t compCount = count();
         if (compCount > 0xffff) throw Error(49, tiffGroupName(group()));
@@ -707,7 +709,7 @@ namespace Exiv2 {
                 sizeValue += sv;
             }
             // Also add the size of data, but only if needed
-            if (imageIdx == uint32_t(-1)) {
+            if (isRootDir) {
                 uint32_t sd = (*i)->sizeData();
                 sd += sd & 1;               // Align data to word boundary
                 sizeData += sd;
@@ -717,8 +719,9 @@ namespace Exiv2 {
         uint32_t idx = 0;                   // Current IFD index / bytes written
         valueIdx = sizeDir;                 // Offset to the current IFD value
         dataIdx  = sizeDir + sizeValue;     // Offset to the entry's data area
-        if (imageIdx == uint32_t(-1)) {     // Offset to the image data
-            imageIdx = dataIdx + sizeData + sizeNext;
+        if (isRootDir) {                    // Absolute offset to the image data
+            imageIdx = offset + dataIdx + sizeData + sizeNext;
+            imageIdx += imageIdx & 1;       // Align image data to word boundary
         }
 
         // 1st: Write the IFD, a) Number of directory entries
@@ -790,11 +793,9 @@ namespace Exiv2 {
             idx += pNext_->write(blob, byteOrder, offset + idx, uint32_t(-1), uint32_t(-1), imageIdx);
         }
 
-        // 5th: Write image data
-        imageIdx = idx;
-        for (Components::const_iterator i = components_.begin(); i != components_.end(); ++i) {
-            idx += (*i)->writeImage(blob, byteOrder, offset, imageIdx);
-            imageIdx += (*i)->sizeImage();
+        // 5th, at the root directory level only: write image data
+        if (isRootDir) {
+            idx += writeImage(blob, byteOrder);
         }
 
         return idx;
@@ -806,7 +807,7 @@ namespace Exiv2 {
                                           TiffComponent* pTiffComponent,
                                           uint32_t       valueIdx,
                                           uint32_t       dataIdx,
-                                          uint32_t       imageIdx) const
+                                          uint32_t&      imageIdx) const
     {
         assert(pTiffComponent);
         TiffEntryBase* pDirEntry = dynamic_cast<TiffEntryBase*>(pTiffComponent);
@@ -842,7 +843,7 @@ namespace Exiv2 {
                                     int32_t   /*offset*/,
                                     uint32_t  /*valueIdx*/,
                                     uint32_t  /*dataIdx*/,
-                                    uint32_t  /*imageIdx*/)
+                                    uint32_t& /*imageIdx*/)
     {
         if (!pValue_) return 0;
 
@@ -880,7 +881,7 @@ namespace Exiv2 {
                                     int32_t   offset,
                                     uint32_t  /*valueIdx*/,
                                     uint32_t  dataIdx,
-                                    uint32_t  /*imageIdx*/)
+                                    uint32_t& /*imageIdx*/)
     {
         if (!pValue()) return 0;
 
@@ -901,17 +902,23 @@ namespace Exiv2 {
 
     uint32_t TiffImageEntry::doWrite(Blob&     blob,
                                      ByteOrder byteOrder,
-                                     int32_t   offset,
+                                     int32_t   /*offset*/,
                                      uint32_t  /*valueIdx*/,
                                      uint32_t  /*dataIdx*/,
-                                     uint32_t  imageIdx)
+                                     uint32_t& imageIdx)
     {
+#ifdef DEBUG
+        std::cerr << "TiffImageEntry, tag 0x" << std::setw(4) 
+                  << std::setfill('0') << std::hex << tag() << std::dec
+                  << ": Writing offset " << imageIdx << "
";
+#endif
         DataBuf buf(strips_.size() * 4);
         uint32_t idx = 0;
         for (Strips::const_iterator i = strips_.begin(); i != strips_.end(); ++i) {
-            idx += writeOffset(buf.pData_ + idx, offset + imageIdx, tiffType(), byteOrder);
+            idx += writeOffset(buf.pData_ + idx, imageIdx, tiffType(), byteOrder);
             imageIdx += i->second;
         }
+        imageIdx += sizeImage() & 1;                // Align image data to word boundary
         append(blob, buf.pData_, buf.size_);
         return buf.size_;
     } // TiffImageEntry::doWrite
@@ -921,7 +928,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  /*valueIdx*/,
                                  uint32_t  dataIdx,
-                                 uint32_t  /*imageIdx*/)
+                                 uint32_t& /*imageIdx*/)
     {
         DataBuf buf(ifds_.size() * 4);
         uint32_t idx = 0;
@@ -938,7 +945,7 @@ namespace Exiv2 {
                                   int32_t   offset,
                                   uint32_t  valueIdx,
                                   uint32_t  dataIdx,
-                                  uint32_t  imageIdx)
+                                  uint32_t& imageIdx)
     {
         if (!mn_) {
             return TiffEntryBase::doWrite(blob, byteOrder, offset, valueIdx, dataIdx, imageIdx);
@@ -951,7 +958,7 @@ namespace Exiv2 {
                                      int32_t   offset,
                                      uint32_t  valueIdx,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx)
+                                     uint32_t& imageIdx)
     {
         const uint32_t cnt = count();
         if (cnt == 0) return 0;
@@ -1003,7 +1010,7 @@ namespace Exiv2 {
                                        int32_t   /*offset*/,
                                        uint32_t  /*valueIdx*/,
                                        uint32_t  /*dataIdx*/,
-                                       uint32_t  /*imageIdx*/)
+                                       uint32_t& /*imageIdx*/)
     {
         Value const* pv = pValue();
         if (!pv || pv->count() == 0) return 0;
@@ -1021,7 +1028,7 @@ namespace Exiv2 {
                                       ByteOrder byteOrder,
                                       int32_t   offset,
                                       uint32_t  dataIdx,
-                                      uint32_t  imageIdx) const
+                                      uint32_t& imageIdx) const
     {
         return doWriteData(blob, byteOrder, offset, dataIdx, imageIdx);
     } // TiffComponent::writeData
@@ -1030,7 +1037,7 @@ namespace Exiv2 {
                                         ByteOrder /*byteOrder*/,
                                         int32_t   /*offset*/,
                                         uint32_t  /*dataIdx*/,
-                                        uint32_t  /*imageIdx*/) const
+                                        uint32_t& /*imageIdx*/) const
     {
         // We don't expect this method to be called. This makes it obvious.
         assert(false);
@@ -1041,7 +1048,7 @@ namespace Exiv2 {
                                         ByteOrder /*byteOrder*/,
                                         int32_t   /*offset*/,
                                         uint32_t  /*dataIdx*/,
-                                        uint32_t  /*imageIdx*/) const
+                                        uint32_t& /*imageIdx*/) const
     {
         return 0;
     } // TiffEntryBase::doWriteData
@@ -1050,7 +1057,7 @@ namespace Exiv2 {
                                         ByteOrder /*byteOrder*/,
                                         int32_t   /*offset*/,
                                         uint32_t  /*dataIdx*/,
-                                        uint32_t  /*imageIdx*/) const
+                                        uint32_t& /*imageIdx*/) const
     {
         if (!pValue()) return 0;
 
@@ -1063,7 +1070,7 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const
+                                     uint32_t& imageIdx) const
     {
         uint32_t len = 0;
         for (Ifds::const_iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
@@ -1073,50 +1080,83 @@ namespace Exiv2 {
     } // TiffSubIfd::doWriteData
 
     uint32_t TiffComponent::writeImage(Blob&     blob,
-                                       ByteOrder byteOrder,
-                                       int32_t   offset,
-                                       uint32_t  imageIdx) const
+                                       ByteOrder byteOrder) const
     {
-        return doWriteImage(blob, byteOrder, offset, imageIdx);
+        return doWriteImage(blob, byteOrder);
     } // TiffComponent::writeImage
 
-    uint32_t TiffDirectory::doWriteImage(Blob&     /*blob*/,
-                                         ByteOrder /*byteOrder*/,
-                                         int32_t   /*offset*/,
-                                         uint32_t  /*imageIdx*/) const
+    uint32_t TiffDirectory::doWriteImage(Blob&     blob,
+                                         ByteOrder byteOrder) const
     {
-        // We don't expect this method to be called. This makes it obvious.
-        assert(false);
-        return 0;
+        uint32_t len = 0;
+        for (Components::const_iterator i = components_.begin(); i != components_.end(); ++i) {
+            len += (*i)->writeImage(blob, byteOrder);
+        }
+        if (pNext_) {
+            len += pNext_->writeImage(blob, byteOrder);
+        }
+        return len;
     } // TiffDirectory::doWriteImage
 
     uint32_t TiffEntryBase::doWriteImage(Blob&     /*blob*/,
-                                         ByteOrder /*byteOrder*/,
-                                         int32_t   /*offset*/,
-                                         uint32_t  /*imageIdx*/) const
+                                         ByteOrder /*byteOrder*/) const
     {
         return 0;
     } // TiffEntryBase::doWriteImage
 
+    uint32_t TiffSubIfd::doWriteImage(Blob&     blob,
+                                      ByteOrder byteOrder) const
+    {
+        uint32_t len = 0;
+        for (Ifds::const_iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
+            len  += (*i)->writeImage(blob, byteOrder);
+        }
+        return len;
+    } // TiffSubIfd::doWriteData
+
     uint32_t TiffImageEntry::doWriteImage(Blob&     blob,
-                                          ByteOrder /*byteOrder*/,
-                                          int32_t   /*offset*/,
-                                          uint32_t  /*imageIdx*/) const
+                                          ByteOrder /*byteOrder*/) const
     {
+        // Adjust blob capacity - speeds up copying of large data areas
+        uint32_t sz = sizeImage();
+        Blob::size_type size = blob.size();
+        if (blob.capacity() - size < sz) {
+            blob.reserve(size + sz + 65536);
+        }
+        // Align image data to word boundary
+        uint32_t align = 0;
+        if ((blob.size() & 1) == 1) {
+            blob.push_back(0x0);
+            align = 1;
+        }
+
         uint32_t len = pValue()->sizeDataArea();
         if (len > 0) {
+#ifdef DEBUG
+            std::cerr << "TiffImageEntry, tag 0x" << std::setw(4) 
+                      << std::setfill('0') << std::hex << tag() << std::dec
+                      << ": Writing data area, blob-size = " << blob.size();
+#endif
             DataBuf buf = pValue()->dataArea();
             append(blob, buf.pData_, buf.size_);
         }
         else {
+#ifdef DEBUG
+            std::cerr << "TiffImageEntry, tag 0x" << std::setw(4) 
+                      << std::setfill('0') << std::hex << tag() << std::dec
+                      << ": Writing data area, blob-size = " << blob.size();
+#endif
             len = 0;
             for (Strips::const_iterator i = strips_.begin(); i != strips_.end(); ++i) {
                 append(blob, i->first, i->second);
                 len += i->second;
             }
         }
-        return len;
-    } // TiffImageEntry::doWriteData
+#ifdef DEBUG
+        std::cerr << ", len = " << len << " bytes
";
+#endif
+        return len + align;
+    } // TiffImageEntry::doWriteImage
 
     uint32_t TiffComponent::size() const
     {
@@ -1216,10 +1256,25 @@ namespace Exiv2 {
 
     uint32_t TiffDirectory::doSizeImage() const
     {
-        assert(false);
-        return 0;
+        uint32_t len = 0;
+        for (Components::const_iterator i = components_.begin(); i != components_.end(); ++i) {
+            len += (*i)->sizeImage();
+        }
+        if (pNext_) {
+            len += pNext_->sizeImage();
+        }
+        return len;
     } // TiffDirectory::doSizeImage
 
+    uint32_t TiffSubIfd::doSizeImage() const
+    {
+        uint32_t len = 0;
+        for (Ifds::const_iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
+            len += (*i)->sizeImage();
+        }
+        return len;
+    } // TiffSubIfd::doSizeImage
+
     uint32_t TiffEntryBase::doSizeImage() const
     {
         return 0;
diff --git a/src/tiffcomposite_int.hpp b/src/tiffcomposite_int.hpp
index a7e7a5e..ca9935b 100644
--- a/src/tiffcomposite_int.hpp
+++ b/src/tiffcomposite_int.hpp
@@ -84,10 +84,10 @@ namespace Exiv2 {
         const uint16_t exif    =   3; //!< Exif IFD
         const uint16_t gps     =   4; //!< GPS IFD
         const uint16_t iop     =   5; //!< Interoperability IFD
-        const uint16_t sub0_0  =   6; //!< Tiff SubIFD 0 in IFD0
-        const uint16_t sub0_1  =   7; //!< Tiff SubIFD 1 in IFD0
-        const uint16_t sub0_2  =   8; //!< Tiff SubIFD 2 in IFD0
-        const uint16_t sub0_3  =   9; //!< Tiff SubIFD 3 in IFD0
+        const uint16_t subimg1 =   6; //!< 1st TIFF SubIFD in IFD0
+        const uint16_t subimg2 =   7; //!< 2nd TIFF SubIFD in IFD0
+        const uint16_t subimg3 =   8; //!< 3rd TIFF SubIFD in IFD0
+        const uint16_t subimg4 =   9; //!< 4th TIFF SubIFD in IFD0
         const uint16_t mn      = 256; //!< Makernote
         const uint16_t ignr    = 511; //!< Read but do not decode
     }
@@ -198,7 +198,7 @@ namespace Exiv2 {
                        int32_t   offset,
                        uint32_t  valueIdx,
                        uint32_t  dataIdx,
-                       uint32_t  imageIdx);
+                       uint32_t& imageIdx);
         //@}
 
         //! @name Write support (Accessors)
@@ -212,16 +212,14 @@ namespace Exiv2 {
                            ByteOrder byteOrder,
                            int32_t   offset,
                            uint32_t  dataIdx,
-                           uint32_t  imageIdx) const;
+                           uint32_t& imageIdx) const;
         /*!
           @brief Write the image data of this component to a binary image.
-                 Return the number of bytes written. Components derived from
-                 TiffEntryBase implement this method if needed.
+                 Return the number of bytes written. TIFF components implement
+                 this method if needed.
          */
         uint32_t writeImage(Blob&     blob,
-                            ByteOrder byteOrder,
-                            int32_t   offset,
-                            uint32_t  imageIdx) const;
+                            ByteOrder byteOrder) const;
         /*!
           @brief Return the size in bytes of the IFD value of this component
                  when written to a binary image.
@@ -239,10 +237,10 @@ namespace Exiv2 {
          */
         uint32_t sizeData() const;
         /*!
-          @brief Return the size in bytes of the image data of this component when
-                 written to a binary image.  This is a support function for
-                 write(). Components derived from TiffEntryBase implement this
-                 method corresponding to their implementation of writeImage().
+          @brief Return the size in bytes of the image data of this component
+                 when written to a binary image.  This is a support function for
+                 write(). TIFF components implement this method corresponding to
+                 their implementation of writeImage().
          */
         uint32_t sizeImage() const;
         //@}
@@ -269,7 +267,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx) =0;
+                                 uint32_t& imageIdx) =0;
         //@}
 
         //! @name Write support (Accessors)
@@ -279,12 +277,10 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const =0;
+                                     uint32_t& imageIdx) const =0;
         //! Implements writeImage().
         virtual uint32_t doWriteImage(Blob&     blob,
-                                      ByteOrder byteOrder,
-                                      int32_t   offset,
-                                      uint32_t  imageIdx) const =0;
+                                      ByteOrder byteOrder) const =0;
         //! Implements size().
         virtual uint32_t doSize() const =0;
         //! Implements count().
@@ -460,7 +456,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -472,15 +468,13 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const;
+                                     uint32_t& imageIdx) const;
         /*!
           @brief Implements writeImage(). Standard TIFF entries have no image data:
                  write nothing and return 0.
          */
         virtual uint32_t doWriteImage(Blob&     blob,
-                                      ByteOrder byteOrder,
-                                      int32_t   offset,
-                                      uint32_t  imageIdx) const;
+                                      ByteOrder byteOrder) const;
         //! Implements size(). Return the size of a standard TIFF entry
         virtual uint32_t doSize() const;
         //! Implements sizeData(). Return 0.
@@ -648,7 +642,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -660,7 +654,7 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const;
+                                     uint32_t& imageIdx) const;
         // Using doWriteImage from base class
         // Using doSize() from base class
         //! Implements sizeData(). Return the size of the data area.
@@ -726,7 +720,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -736,9 +730,7 @@ namespace Exiv2 {
                  Return the number of bytes written.
          */
         virtual uint32_t doWriteImage(Blob&     blob,
-                                      ByteOrder byteOrder,
-                                      int32_t   offset,
-                                      uint32_t  imageIdx) const;
+                                      ByteOrder byteOrder) const;
         //! Implements size(). Return the size of the strip pointers.
         virtual uint32_t doSize() const;
         // Using doSizeData from base class
@@ -838,7 +830,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -850,15 +842,15 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const;
+                                     uint32_t& imageIdx) const;
         /*!
-          @brief This class does not really implement writeImage(), it only has
-                 write(). This method must not be called; it commits suicide.
+          @brief Implements writeImage(). Write the image data of the TIFF
+                 directory to the blob by forwarding the call to each component
+                 as well as the next-IFD, if there is any. Return the number of
+                 bytes written.
          */
         virtual uint32_t doWriteImage(Blob&     blob,
-                                      ByteOrder byteOrder,
-                                      int32_t   offset,
-                                      uint32_t  imageIdx) const;
+                                      ByteOrder byteOrder) const;
         /*!
           @brief Implements size(). Return the size of the TIFF directory,
                  values and additional data, including the next-IFD, if any.
@@ -875,8 +867,8 @@ namespace Exiv2 {
          */
         virtual uint32_t doSizeData() const;
         /*!
-          @brief This class does not really implement sizeImage(), it only has
-                 size(). This method must not be called; it commits suicide.
+          @brief Implements sizeImage(). Return the sum of the image sizes of 
+                 all components plus that of the next-IFD, if there is any.
          */
         virtual uint32_t doSizeImage() const;
         //@}
@@ -891,7 +883,7 @@ namespace Exiv2 {
                                TiffComponent* pTiffComponent,
                                uint32_t       valueIdx,
                                uint32_t       dataIdx,
-                               uint32_t       imageIdx) const;
+                               uint32_t&      imageIdx) const;
         //@}
 
     private:
@@ -941,7 +933,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -953,13 +945,19 @@ namespace Exiv2 {
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  dataIdx,
-                                     uint32_t  imageIdx) const;
-        // Using doWriteImage from base class
+                                     uint32_t& imageIdx) const;
+        /*!
+          @brief Implements writeImage(). Write the image data of each sub-IFD to
+                 the blob. Return the number of bytes written.
+         */
+        virtual uint32_t doWriteImage(Blob&     blob,
+                                      ByteOrder byteOrder) const;
         //! Implements size(). Return the size of the sub-Ifd pointers.
         uint32_t doSize() const;
         //! Implements sizeData(). Return the sum of the sizes of all sub-IFDs.
         virtual uint32_t doSizeData() const;
-        // Using doSizeImage from base class
+        //! Implements sizeImage(). Return the sum of the image sizes of all sub-IFDs.
+        virtual uint32_t doSizeImage() const;
         //@}
 
     private:
@@ -1020,7 +1018,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -1096,7 +1094,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         //! @name Write support (Accessors)
         //@{
@@ -1163,7 +1161,7 @@ namespace Exiv2 {
                                  int32_t   offset,
                                  uint32_t  valueIdx,
                                  uint32_t  dataIdx,
-                                 uint32_t  imageIdx);
+                                 uint32_t& imageIdx);
         //@}
         // Using doWriteData from base class
         // Using doWriteImage from base class
diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp
index 13ba804..fb3b231 100644
--- a/src/tiffimage.cpp
+++ b/src/tiffimage.cpp
@@ -288,22 +288,43 @@ namespace Exiv2 {
         {    0x8825, Group::ifd0,      Group::gps,       Tag::root, Group::none,      newTiffSubIfd },
         {    0x0111, Group::ifd0,      Group::ifd0,      Tag::root, Group::none,      newTiffImageData<0x0117, Group::ifd0> },
         {    0x0117, Group::ifd0,      Group::ifd0,      Tag::root, Group::none,      newTiffImageSize<0x0111, Group::ifd0> },
-        // SubIfd found in NEF images (up to 3 sub directories seen, groups sub0_0, sub0_1, sub0_2)
-        {    0x014a, Group::ifd0,      Group::sub0_0,    Tag::root, Group::none,      newTiffSubIfd },
+        {    0x0201, Group::ifd0,      Group::ifd0,      Tag::root, Group::ifd0,      newTiffImageData<0x0202, Group::ifd0> },
+        {    0x0202, Group::ifd0,      Group::ifd0,      Tag::root, Group::ifd0,      newTiffImageSize<0x0201, Group::ifd0> },
+        {    0x014a, Group::ifd0,      Group::subimg1,   Tag::root, Group::none,      newTiffSubIfd },
         { Tag::next, Group::ifd0,      Group::ifd1,      Tag::root, Group::none,      newTiffDirectory },
         {  Tag::all, Group::ifd0,      Group::ifd0,      Tag::root, Group::none,      newTiffEntry },
 
-        // Subdir sub0_0
-        { Tag::next, Group::sub0_0,    Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
-        {  Tag::all, Group::sub0_0,    Group::sub0_0,    0x014a,    Group::ifd0,      newTiffEntry },
-
-        // Subdir sub0_1
-        { Tag::next, Group::sub0_1,    Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
-        {  Tag::all, Group::sub0_1,    Group::sub0_1,    0x014a,    Group::ifd0,      newTiffEntry },
-
-        // Subdir sub0_2
-        { Tag::next, Group::sub0_2,    Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
-        {  Tag::all, Group::sub0_2,    Group::sub0_2,    0x014a,    Group::ifd0,      newTiffEntry },
+        // Subdir subimg1
+        {    0x0111, Group::subimg1,   Group::subimg1,   0x014a,    Group::ifd0,      newTiffImageData<0x0117, Group::subimg1> },
+        {    0x0117, Group::subimg1,   Group::subimg1,   0x014a,    Group::ifd0,      newTiffImageSize<0x0111, Group::subimg1> },
+        {    0x0201, Group::subimg1,   Group::subimg1,   0x014a,    Group::ifd0,      newTiffImageData<0x0202, Group::subimg1> },
+        {    0x0202, Group::subimg1,   Group::subimg1,   0x014a,    Group::ifd0,      newTiffImageSize<0x0201, Group::subimg1> },
+        { Tag::next, Group::subimg1,   Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
+        {  Tag::all, Group::subimg1,   Group::subimg1,   0x014a,    Group::ifd0,      newTiffEntry },
+
+        // Subdir subimg2
+        {    0x0111, Group::subimg2,   Group::subimg2,   0x014a,    Group::ifd0,      newTiffImageData<0x0117, Group::subimg2> },
+        {    0x0117, Group::subimg2,   Group::subimg2,   0x014a,    Group::ifd0,      newTiffImageSize<0x0111, Group::subimg2> },
+        {    0x0201, Group::subimg2,   Group::subimg2,   0x014a,    Group::ifd0,      newTiffImageData<0x0202, Group::subimg2> },
+        {    0x0202, Group::subimg2,   Group::subimg2,   0x014a,    Group::ifd0,      newTiffImageSize<0x0201, Group::subimg2> },
+        { Tag::next, Group::subimg2,   Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
+        {  Tag::all, Group::subimg2,   Group::subimg2,   0x014a,    Group::ifd0,      newTiffEntry },
+
+        // Subdir subimg3
+        {    0x0111, Group::subimg3,   Group::subimg3,   0x014a,    Group::ifd0,      newTiffImageData<0x0117, Group::subimg3> },
+        {    0x0117, Group::subimg3,   Group::subimg3,   0x014a,    Group::ifd0,      newTiffImageSize<0x0111, Group::subimg3> },
+        {    0x0201, Group::subimg3,   Group::subimg3,   0x014a,    Group::ifd0,      newTiffImageData<0x0202, Group::subimg3> },
+        {    0x0202, Group::subimg3,   Group::subimg3,   0x014a,    Group::ifd0,      newTiffImageSize<0x0201, Group::subimg3> },
+        { Tag::next, Group::subimg3,   Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
+        {  Tag::all, Group::subimg3,   Group::subimg3,   0x014a,    Group::ifd0,      newTiffEntry },
+
+        // Subdir subimg4
+        {    0x0111, Group::subimg4,   Group::subimg4,   0x014a,    Group::ifd0,      newTiffImageData<0x0117, Group::subimg4> },
+        {    0x0117, Group::subimg4,   Group::subimg4,   0x014a,    Group::ifd0,      newTiffImageSize<0x0111, Group::subimg4> },
+        {    0x0201, Group::subimg4,   Group::subimg4,   0x014a,    Group::ifd0,      newTiffImageData<0x0202, Group::subimg4> },
+        {    0x0202, Group::subimg4,   Group::subimg4,   0x014a,    Group::ifd0,      newTiffImageSize<0x0201, Group::subimg4> },
+        { Tag::next, Group::subimg4,   Group::ignr,      0x014a,    Group::ifd0,      newTiffDirectory },
+        {  Tag::all, Group::subimg4,   Group::subimg4,   0x014a,    Group::ifd0,      newTiffEntry },
 
         // Exif subdir
         {    0xa005, Group::exif,      Group::iop,       0x8769,    Group::ifd0,      newTiffSubIfd },
@@ -418,9 +439,6 @@ namespace Exiv2 {
     const TiffMappingInfo TiffMapping::tiffMappingInfo_[] = {
         { "*",       Tag::all, Group::ignr,    0, 0 }, // Do not decode tags with group == Group::ignr
         { "OLYMPUS",   0x0100, Group::olympmn, &TiffDecoder::decodeOlympThumb,   &TiffEncoder::encodeOlympThumb     },
-        { "*",         0x014a, Group::ifd0,    0, 0 }, // Todo: Controversial, causes problems with Exiftool
-        { "*",       Tag::all, Group::sub0_0,  &TiffDecoder::decodeSubIfd,       0 /*Todo*/                         },
-        { "*",       Tag::all, Group::sub0_1,  &TiffDecoder::decodeSubIfd,       0 /*Todo*/                         },
         { "*",         0x02bc, Group::ifd0,    &TiffDecoder::decodeXmp,          0 /*done before the tree is traversed*/ },
         { "*",         0x83bb, Group::ifd0,    &TiffDecoder::decodeIptc,         0 /*done before the tree is traversed*/ },
         { "*",         0x8649, Group::ifd0,    &TiffDecoder::decodeIptc,         0 /*done before the tree is traversed*/ },
@@ -578,7 +596,8 @@ namespace Exiv2 {
             encoder.add(createdTree.get(), parsedTree.get(), createFct);
             // Write binary representation from the composite tree
             uint32_t offset = pHeader->write(blob);
-            uint32_t len = createdTree->write(blob, pHeader->byteOrder(), offset, uint32_t(-1), uint32_t(-1), uint32_t(-1));
+            uint32_t imageIdx(-1);
+            uint32_t len = createdTree->write(blob, pHeader->byteOrder(), offset, uint32_t(-1), uint32_t(-1), imageIdx);
             // Avoid writing just the header if there is no IFD data
             if (len == 0) blob.clear();
 #ifdef DEBUG
diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp
index 34f99fc..6113f1a 100644
--- a/src/tiffvisitor.cpp
+++ b/src/tiffvisitor.cpp
@@ -325,25 +325,6 @@ namespace Exiv2 {
         }
     } // TiffMetadataDecoder::decodeIptc
 
-    void TiffDecoder::decodeSubIfd(const TiffEntryBase* object)
-    {
-        assert(object);
-
-        // Only applicable if ifd0 NewSubfileType is Thumbnail/Preview image
-        GroupType::const_iterator i = groupType_.find(Group::ifd0);
-        if (i == groupType_.end() || (i->second & 1) == 0) return;
-
-        // Only applicable if subIFD NewSubfileType is Primary image
-        i = groupType_.find(object->group());
-        if (i == groupType_.end() || (i->second & 1) == 1) return;
-
-        // Todo: ExifKey should have an appropriate c'tor, it should not be
-        //       necessary to use groupName here
-        ExifKey key(object->tag(), tiffGroupName(Group::ifd0));
-        setExifTag(key, object->pValue(), pvHigh);
-
-    }
-
     void TiffDecoder::decodeTiffEntry(const TiffEntryBase* object)
     {
         assert(object != 0);
@@ -371,35 +352,10 @@ namespace Exiv2 {
         // Todo: ExifKey should have an appropriate c'tor, it should not be
         //       necessary to use groupName here
         ExifKey key(object->tag(), tiffGroupName(object->group()));
-        setExifTag(key, object->pValue(), pvNormal);
+        exifData_.add(key, object->pValue());
 
     } // TiffDecoder::decodeTiffEntry
 
-    void TiffDecoder::setExifTag(const ExifKey& key, const Value* pValue, Prio prio)
-    {
-        bool isRegPrioTag = (priorityKeys_.find(key.key()) != priorityKeys_.end());
-
-        switch (prio) {
-        case pvNormal:
-            // If key is not registered as high prio tag, add it
-            if (!isRegPrioTag) exifData_.add(key, pValue);
-            break;
-        case pvHigh:
-            // Register the key as a high prio tag, erase low prio tags, add this
-            if (!isRegPrioTag) {
-                priorityKeys_.insert(key.key());
-                ExifData::iterator pos = exifData_.findKey(key);
-                while (pos != exifData_.end()) {
-                    exifData_.erase(pos);
-                    pos = exifData_.findKey(key);
-                }
-            }
-            exifData_.add(key, pValue);
-            break;
-        }
-
-    } // TiffDecoder::setExifTag
-
     void TiffDecoder::visitArrayEntry(TiffArrayEntry* /*object*/)
     {
         // Nothing to do
diff --git a/src/tiffvisitor_int.hpp b/src/tiffvisitor_int.hpp
index 4f21da8..a39ad79 100644
--- a/src/tiffvisitor_int.hpp
+++ b/src/tiffvisitor_int.hpp
@@ -263,8 +263,6 @@ namespace Exiv2 {
         void decodeStdTiffEntry(const TiffEntryBase* object);
         //! Decode Olympus Thumbnail from the TIFF makernote into IFD1
         void decodeOlympThumb(const TiffEntryBase* object);
-        //! Decode SubIFD contents to Image group if it contains primary image data
-        void decodeSubIfd(const TiffEntryBase* object);
         //! Decode IPTC data from an IPTCNAA tag or Photoshop ImageResources
         void decodeIptc(const TiffEntryBase* object);
         //! Decode XMP packet from an XMLPacket tag
@@ -272,13 +270,8 @@ namespace Exiv2 {
         //@}
 
     private:
-        //! Tag priorities
-        enum Prio { pvNormal, pvHigh };
-
         //! @name Manipulators
         //@{
-        //! Set an Exif tag in the image.
-        void setExifTag(const ExifKey& key, const Value* pValue, Prio prio);
         /*!
           @brief Get the data for a \em tag and \em group, either from the
                  \em object provided, if it matches or from the matching element
@@ -309,10 +302,6 @@ namespace Exiv2 {
 
         bool decodedIptc_;           //!< Indicates if IPTC has been decoded yet
 
-        //! Type used as the container for "priority keys"
-        typedef std::set<std::string> PriorityKeys;
-        PriorityKeys priorityKeys_;  //!< Priority keys
-
     }; // class TiffDecoder
 
     /*!
diff --git a/src/types.hpp b/src/types.hpp
index 2eb5984..2ffc5ea 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -135,6 +135,7 @@ namespace Exiv2 {
     //! Type to specify the IFD to which a metadata belongs
     enum IfdId { ifdIdNotSet,
                  ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id,
+                 subImage1Id, subImage2Id, subImage3Id, subImage4Id,
                  canonIfdId, canonCsIfdId, canonSiIfdId, canonCfIfdId,
                  canonPiIfdId, canonPaIfdId,
                  fujiIfdId,

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list