[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:25 UTC 2017


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

The following commit has been merged in the master branch:
commit 0da1d88115460122bf97ef4f0079b06713cde319
Author: Andreas Huggel <ahuggel at gmx.net>
Date:   Sat Mar 28 11:18:55 2009 +0000

    #606: Added Michael Ulbrich's patch for Exif and IPTC write-support.
---
 src/psdimage.cpp | 358 +++++++++++++++++++++++++++++++++++--------------------
 src/psdimage.hpp |  26 ++--
 2 files changed, 235 insertions(+), 149 deletions(-)

diff --git a/src/psdimage.cpp b/src/psdimage.cpp
index 6fd47f9..6e71533 100644
--- a/src/psdimage.cpp
+++ b/src/psdimage.cpp
@@ -137,21 +137,9 @@ namespace Exiv2 {
     {
     } // PsdImage::PsdImage
 
-    void PsdImage::setExifData(const ExifData& /*exifData*/)
-    {
-        // Todo: implement me!
-        throw(Error(32, "Exif metadata", "Photoshop"));
-    }
-
-    void PsdImage::setIptcData(const IptcData& /*iptcData*/)
-    {
-        // Todo: implement me!
-        throw(Error(32, "IPTC metadata", "Photoshop"));
-    }
-
     void PsdImage::setComment(const std::string& /*comment*/)
     {
-        // Todo: implement me!
+        // not supported
         throw(Error(32, "Image comment", "Photoshop"));
     }
 
@@ -243,7 +231,11 @@ namespace Exiv2 {
             uint32_t resourceSize = getULong(buf, bigEndian);
             uint32_t curOffset = io_->tell();
 
-            processResourceBlock(resourceId, resourceSize);
+#ifdef DEBUG
+        std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex << "
";
+#endif
+
+            readResourceBlock(resourceId, resourceSize);
             resourceSize = (resourceSize + 1) & ~1;        // pad to even
             io_->seek(curOffset + resourceSize, BasicIo::beg);
             resourcesLength -= (12 + resourceNameLength + resourceSize);
@@ -251,7 +243,7 @@ namespace Exiv2 {
 
     } // PsdImage::readMetadata
 
-    void PsdImage::processResourceBlock(uint16_t resourceId, uint32_t resourceSize)
+    void PsdImage::readResourceBlock(uint16_t resourceId, uint32_t resourceSize)
     {
         switch(resourceId)
         {
@@ -304,7 +296,7 @@ namespace Exiv2 {
                 break;
             }
         }
-    }
+    } // PsdImage::readResourceBlock
 
     void PsdImage::writeMetadata()
     {
@@ -333,8 +325,7 @@ namespace Exiv2 {
 #endif
 
         // Ensure that this is the correct image type
-        if (!isPsdType(*io_, true))
-        {
+        if (!isPsdType(*io_, true)) {
             if (io_->error() || io_->eof()) throw Error(20);
             throw Error(22);
         }
@@ -346,19 +337,13 @@ namespace Exiv2 {
 
         // Get Photoshop header from original file
         byte psd_head[26];
-        if (io_->read(psd_head, 26) != 26)
-        {
-            throw Error(3, "Photoshop");
-        }
+        if (io_->read(psd_head, 26) != 26) throw Error(3, "Photoshop");
 
         // Write Photoshop header data out to new PSD file
         if (outIo.write(psd_head, 26) != 26) throw Error(21);
 
         // Read colorDataLength from original PSD 
-        if (io_->read(buf, 4) != 4)
-        {
-            throw Error(3, "Photoshop");
-        }
+        if (io_->read(buf, 4) != 4) throw Error(3, "Photoshop");
 
         uint32_t colorDataLength = getULong(buf, bigEndian);
 
@@ -374,10 +359,7 @@ namespace Exiv2 {
         while (readTotal < colorDataLength) {
             toRead =   static_cast<long>(colorDataLength - readTotal) < lbuf.size_
                      ? colorDataLength - readTotal : lbuf.size_;
-            if (io_->read(lbuf.pData_, toRead) != toRead)
-            {
-                throw Error(3, "Photoshop");
-            }
+            if (io_->read(lbuf.pData_, toRead) != toRead) throw Error(3, "Photoshop");
             readTotal += toRead;
             if (outIo.write(lbuf.pData_, toRead) != toRead) throw Error(21);
         }
@@ -386,10 +368,7 @@ namespace Exiv2 {
         uint32_t resLenOffset = io_->tell();  // remember for later update
 
         // Read length of all resource blocks from original PSD
-        if (io_->read(buf, 4) != 4)
-        {
-            throw Error(3, "Photoshop");
-        }
+        if (io_->read(buf, 4) != 4) throw Error(3, "Photoshop");
 
         uint32_t oldResLength = getULong(buf, bigEndian);
         uint32_t newResLength = 0;
@@ -397,133 +376,128 @@ namespace Exiv2 {
         // Write oldResLength (will be updated later)
         ul2Data(buf, oldResLength, bigEndian);
         if (outIo.write(buf, 4) != 4) throw Error(21);
+
 #ifdef DEBUG
         std::cerr << std::dec << "oldResLength: " << oldResLength << "
";
 #endif
-        // Write metadata resource blocks: IPTC_NAA, (TODO: ExifInfo, XMPPacket)
-        if (iptcData_.count() > 0) {
-            DataBuf rawIptc = IptcParser::encode(iptcData_);
-            if (rawIptc.size_ > 0) {
-#ifdef DEBUG
-                std::cerr << std::dec << "Writing IPTC_NAA: size: " << rawIptc.size_ << "
";
-#endif
-                ul2Data(buf, kPhotoshopResourceType, bigEndian);
-                if (outIo.write(buf, 4) != 4) throw Error(21);
-                us2Data(buf, kPhotoshopResourceID_IPTC_NAA, bigEndian);
-                if (outIo.write(buf, 2) != 2) throw Error(21);
-                us2Data(buf, 0, bigEndian);                      // NULL resource name
-                if (outIo.write(buf, 2) != 2) throw Error(21);
-                ul2Data(buf, rawIptc.size_, bigEndian);
-                if (outIo.write(buf, 4) != 4) throw Error(21);
-                // Write encoded Iptc data
-                if (outIo.write(rawIptc.pData_, rawIptc.size_) != rawIptc.size_) throw Error(21);
-                newResLength += rawIptc.size_ + 12;
-                if (rawIptc.size_ & 1)    // even padding
-                {
-                    buf[0] = 0;
-                    if (outIo.write(buf, 1) != 1) throw Error(21);
-                    newResLength++;
-                }
-            }
-        }
 
-        // Iterate over original resource blocks and copy those not already processed
-        while (oldResLength > 0)
-        {
-            if (io_->read(buf, 8) != 8)
-            {
-                throw Error(3, "Photoshop");
-            }
+        // Iterate over original resource blocks.
+        // Replace or insert IPTC, EXIF and XMP
+        // Original resource blocks assumed to be sorted ASC
+
+        bool iptcDone = false;
+        bool exifDone = false;
+        bool xmpDone = false;
+        while (oldResLength > 0) {
+            if (io_->read(buf, 8) != 8) throw Error(3, "Photoshop");
 
             // read resource type and ID
             uint32_t resourceType = getULong(buf, bigEndian);
-            uint16_t resourceId = getUShort(buf + 4, bigEndian);
-#ifdef DEBUG
-            std::cerr << std::hex << "resourceId: " << resourceId << "
";
-            std::cerr << std::dec;
-#endif
-            if (resourceType != kPhotoshopResourceType)
-            { 
+
+            if (resourceType != kPhotoshopResourceType) {
                 break; // bad resource type
             }
+            uint16_t resourceId = getUShort(buf + 4, bigEndian);
             uint32_t resourceNameLength = buf[6];
             uint32_t adjResourceNameLen = resourceNameLength & ~1;
             unsigned char resourceNameFirstChar = buf[7];
 
             // read rest of resource name, plus any padding
             DataBuf resName(256);
-            if (io_->read(resName.pData_, adjResourceNameLen) != adjResourceNameLen)
-            {
-                throw Error(3, "Photoshop");
-            }
+            if (   io_->read(resName.pData_, adjResourceNameLen)
+                != static_cast<long>(adjResourceNameLen)) throw Error(3, "Photoshop");
 
             // read resource size (actual length w/o padding!)
-            if (io_->read(buf, 4) != 4) 
-            {
-                throw Error(3, "Photoshop"); 
-            }
+            if (io_->read(buf, 4) != 4) throw Error(3, "Photoshop"); 
+
             uint32_t resourceSize = getULong(buf, bigEndian);
             uint32_t curOffset = io_->tell();
 
-            switch(resourceId)
-            {
-                case kPhotoshopResourceID_IPTC_NAA:
-                {
-                    resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
-                    break;   // already processed
-                }
-/*
-                case kPhotoshopResourceID_ExifInfo:
-                {
-                    // TODO: skip here, if exiv2 writes it's own EXIF data
-                    break;
-                }
+            // Write IPTC_NAA resource block
+            if (   resourceId == kPhotoshopResourceID_IPTC_NAA
+                || (resourceId > kPhotoshopResourceID_IPTC_NAA && iptcDone == false)) {
+                newResLength += writeIptcData(iptcData_, outIo);
+                resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
+                iptcDone = true;
+            }
 
-                case kPhotoshopResourceID_XMPPacket:
-                {
-                    // TODO: skip here, if exiv2 writes it's own XMP data
-                    break;
-                }
-*/
-                default:
-                {
-                    // Copy resource block to new PSD file
-                    ul2Data(buf, kPhotoshopResourceType, bigEndian);
-                    if (outIo.write(buf, 4) != 4) throw Error(21);
-                    us2Data(buf, resourceId, bigEndian);
-                    if (outIo.write(buf, 2) != 2) throw Error(21);
-                    // Write resource name as Pascal string
-                    buf[0] = resourceNameLength & 0x000f;
-                    if (outIo.write(buf, 1) != 1) throw Error(21);
-                    buf[0] = resourceNameFirstChar;
-                    if (outIo.write(buf, 1) != 1) throw Error(21);
-                    if (outIo.write(resName.pData_, adjResourceNameLen) != adjResourceNameLen) throw Error(21);
-                    ul2Data(buf, resourceSize, bigEndian);
-                    if (outIo.write(buf, 4) != 4) throw Error(21);
-
-                    readTotal = 0;
-                    toRead = 0;
-                    resourceSize = (resourceSize + 1) & ~1;        // pad to even
-                    while (readTotal < resourceSize) {
-                        toRead =   static_cast<long>(resourceSize - readTotal) < lbuf.size_
-                                 ? resourceSize - readTotal : lbuf.size_;
-                        if (io_->read(lbuf.pData_, toRead) != toRead)
-                        {
-                            throw Error(3, "Photoshop");
-                        }
-                        readTotal += toRead;
-                        if (outIo.write(lbuf.pData_, toRead) != toRead) throw Error(21);
+            // Write ExifInfo resource block
+            else if (   resourceId == kPhotoshopResourceID_ExifInfo
+                     || (resourceId > kPhotoshopResourceID_ExifInfo && exifDone == false)) {
+                newResLength += writeExifData(exifData_, outIo);
+                resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
+                exifDone = true;
+            }
+
+            // Write XMPpacket resource block
+            else if (   resourceId == kPhotoshopResourceID_XMPPacket
+                     || (resourceId > kPhotoshopResourceID_XMPPacket && xmpDone == false)) {
+                newResLength += writeXmpData(xmpData_, outIo);
+                resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
+                xmpDone = true;
+            }
+
+            // Copy all other resource blocks
+            if (   resourceId != kPhotoshopResourceID_IPTC_NAA
+                && resourceId != kPhotoshopResourceID_ExifInfo
+                && resourceId != kPhotoshopResourceID_XMPPacket) {
+#ifdef DEBUG
+                std::cerr << std::hex << "copy : resourceId: " << resourceId << "
";
+                std::cerr << std::dec;
+#endif
+                // Copy resource block to new PSD file
+                ul2Data(buf, kPhotoshopResourceType, bigEndian);
+                if (outIo.write(buf, 4) != 4) throw Error(21);
+                us2Data(buf, resourceId, bigEndian);
+                if (outIo.write(buf, 2) != 2) throw Error(21);
+                // Write resource name as Pascal string
+                buf[0] = resourceNameLength & 0x000f;
+                if (outIo.write(buf, 1) != 1) throw Error(21);
+                buf[0] = resourceNameFirstChar;
+                if (outIo.write(buf, 1) != 1) throw Error(21);
+                if (   outIo.write(resName.pData_, adjResourceNameLen)
+                    != static_cast<long>(adjResourceNameLen)) throw Error(21);
+                ul2Data(buf, resourceSize, bigEndian);
+                if (outIo.write(buf, 4) != 4) throw Error(21);
+
+                readTotal = 0;
+                toRead = 0;
+                resourceSize = (resourceSize + 1) & ~1;        // pad to even
+                while (readTotal < resourceSize) {
+                    toRead =   static_cast<long>(resourceSize - readTotal) < lbuf.size_
+                             ? resourceSize - readTotal : lbuf.size_;
+                    if (io_->read(lbuf.pData_, toRead) != toRead) {
+                        throw Error(3, "Photoshop");
                     }
-                    if (outIo.error()) throw Error(21);
-                    newResLength += resourceSize + adjResourceNameLen + 12;
-                    break;
+                    readTotal += toRead;
+                    if (outIo.write(lbuf.pData_, toRead) != toRead) throw Error(21);
                 }
+                if (outIo.error()) throw Error(21);
+                newResLength += resourceSize + adjResourceNameLen + 12;
             }
 
             io_->seek(curOffset + resourceSize, BasicIo::beg);
             oldResLength -= (12 + adjResourceNameLen + resourceSize);
         }
 
+        // Append IPTC_NAA resource block, if not yet written
+        if (iptcDone == false) {
+            newResLength += writeIptcData(iptcData_, outIo);
+            iptcDone = true;
+        }
+
+        // Append ExifInfo resource block, if not yet written
+        if (exifDone == false) {
+            newResLength += writeExifData(exifData_, outIo);
+            exifDone = true;
+        }
+
+        // Append XmpPacket resource block, if not yet written
+        if (xmpDone == false) {
+            newResLength += writeXmpData(xmpData_, outIo);
+            xmpDone = true;
+        }
+
         // Copy remaining data
         long readSize = 0;
         while ((readSize=io_->read(lbuf.pData_, lbuf.size_))) {
@@ -541,6 +515,126 @@ namespace Exiv2 {
 
     } // PsdImage::doWriteMetadata
 
+    uint32_t PsdImage::writeIptcData(const IptcData& iptcData, BasicIo& out) const
+    {
+        uint32_t resLength = 0;
+        byte buf[8];
+
+        if (iptcData.count() > 0) {
+            DataBuf rawIptc = IptcParser::encode(iptcData);
+            if (rawIptc.size_ > 0) {
+#ifdef DEBUG
+                std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_IPTC_NAA << "
";
+                std::cerr << std::dec << "Writing IPTC_NAA: size: " << rawIptc.size_ << "
";
+#endif
+                ul2Data(buf, kPhotoshopResourceType, bigEndian);
+                if (out.write(buf, 4) != 4) throw Error(21);
+                us2Data(buf, kPhotoshopResourceID_IPTC_NAA, bigEndian);
+                if (out.write(buf, 2) != 2) throw Error(21);
+                us2Data(buf, 0, bigEndian);                      // NULL resource name
+                if (out.write(buf, 2) != 2) throw Error(21);
+                ul2Data(buf, rawIptc.size_, bigEndian);
+                if (out.write(buf, 4) != 4) throw Error(21);
+                // Write encoded Iptc data
+                if (out.write(rawIptc.pData_, rawIptc.size_) != rawIptc.size_) throw Error(21);
+                resLength += rawIptc.size_ + 12;
+                if (rawIptc.size_ & 1)    // even padding
+                {
+                    buf[0] = 0;
+                    if (out.write(buf, 1) != 1) throw Error(21);
+                    resLength++;
+                }
+            }
+        }
+        return resLength;
+    } // PsdImage::writeIptcData
+
+    uint32_t PsdImage::writeExifData(const ExifData& exifData, BasicIo& out)
+    {
+        uint32_t resLength = 0;
+        byte buf[8];
+
+        if (exifData.count() > 0) {
+            Blob blob;
+            ByteOrder bo = byteOrder();
+            if (bo == invalidByteOrder) {
+                bo = littleEndian;
+                setByteOrder(bo);
+            }
+            ExifParser::encode(blob, bo, exifData);
+
+            if (blob.size() > 0) {
+#ifdef DEBUG
+                std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_ExifInfo << "
";
+                std::cerr << std::dec << "Writing ExifInfo: size: " << blob.size() << "
";
+#endif
+                ul2Data(buf, kPhotoshopResourceType, bigEndian);
+                if (out.write(buf, 4) != 4) throw Error(21);
+                us2Data(buf, kPhotoshopResourceID_ExifInfo, bigEndian);
+                if (out.write(buf, 2) != 2) throw Error(21);
+                us2Data(buf, 0, bigEndian);                      // NULL resource name
+                if (out.write(buf, 2) != 2) throw Error(21);
+                ul2Data(buf, blob.size(), bigEndian);
+                if (out.write(buf, 4) != 4) throw Error(21);
+                // Write encoded Exif data
+                if (out.write(&blob[0], blob.size()) != static_cast<long>(blob.size())) throw Error(21);
+                resLength += blob.size() + 12;
+                if (blob.size() & 1)    // even padding
+                {
+                    buf[0] = 0;
+                    if (out.write(buf, 1) != 1) throw Error(21);
+                    resLength++;
+                }
+            }
+        }
+        return resLength;
+    } // PsdImage::writeExifData
+
+    uint32_t PsdImage::writeXmpData(const XmpData& xmpData, BasicIo& out) const
+    {
+        std::string xmpPacket;
+        uint32_t resLength = 0;
+        byte buf[8];
+
+#ifdef DEBUG
+        std::cerr << "writeXmpFromPacket(): " << writeXmpFromPacket() << "
";
+#endif
+//        writeXmpFromPacket(true);
+        if (writeXmpFromPacket() == false) {
+            if (XmpParser::encode(xmpPacket, xmpData) > 1) {
+#ifndef SUPPRESS_WARNINGS
+                std::cerr << "Error: Failed to encode XMP metadata.
";
+#endif
+            }
+        }
+
+        if (xmpPacket.size() > 0) {
+#ifdef DEBUG
+            std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_XMPPacket << "
";
+            std::cerr << std::dec << "Writing XMPPacket: size: " << xmpPacket.size() << "
";
+#endif
+            ul2Data(buf, kPhotoshopResourceType, bigEndian);
+            if (out.write(buf, 4) != 4) throw Error(21);
+            us2Data(buf, kPhotoshopResourceID_XMPPacket, bigEndian);
+            if (out.write(buf, 2) != 2) throw Error(21);
+            us2Data(buf, 0, bigEndian);                      // NULL resource name
+            if (out.write(buf, 2) != 2) throw Error(21);
+            ul2Data(buf, xmpPacket.size(), bigEndian);
+            if (out.write(buf, 4) != 4) throw Error(21);
+            // Write XMPPacket
+            if (out.write(reinterpret_cast<const byte*>(xmpPacket.data()), static_cast<long>(xmpPacket.size()))
+                != static_cast<long>(xmpPacket.size())) throw Error(21);
+            if (out.error()) throw Error(21);
+            resLength += xmpPacket.size() + 12;
+            if (xmpPacket.size() & 1)    // even padding
+            {
+                buf[0] = 0;
+                if (out.write(buf, 1) != 1) throw Error(21);
+                resLength++;
+            }
+        }
+        return resLength;
+    } // PsdImage::writeXmpData
 
     // *************************************************************************
     // free functions
diff --git a/src/psdimage.hpp b/src/psdimage.hpp
index d7cbb87..40489ae 100644
--- a/src/psdimage.hpp
+++ b/src/psdimage.hpp
@@ -87,24 +87,9 @@ namespace Exiv2 {
         //! @name Manipulators
         //@{
         void readMetadata();
-        /*!
-          @brief Todo: Write metadata back to the image. This method is not
-              yet implemented. Calling it will throw an Error(31).
-         */
         void writeMetadata();
         /*!
-          @brief Todo: Not supported yet. Calling this function will throw
-              an instance of Error(32).
-         */
-        void setExifData(const ExifData& exifData);
-        /*!
-          @brief Todo: Not supported yet. Calling this function will throw
-              an instance of Error(32).
-         */
-        void setIptcData(const IptcData& iptcData);
-        /*!
-          @brief Todo: Not supported yet. Calling this function will throw
-              an instance of Error(32).
+          @brief Not supported. Calling this function will throw an Error(32).
          */
         void setComment(const std::string& comment);
         //@}
@@ -128,7 +113,7 @@ namespace Exiv2 {
     private:
         //! @name Manipulators
         //@{
-        EXV_DLLLOCAL void processResourceBlock(uint16_t resourceId, uint32_t resourceSize);
+        EXV_DLLLOCAL void readResourceBlock(uint16_t resourceId, uint32_t resourceSize);
         /*!
           @brief Provides the main implementation of writeMetadata() by
                 writing all buffered metadata to the provided BasicIo.
@@ -137,6 +122,13 @@ namespace Exiv2 {
           @return 4 if opening or writing to the associated BasicIo fails
          */
         EXV_DLLLOCAL void doWriteMetadata(BasicIo& oIo);
+        EXV_DLLLOCAL uint32_t writeExifData(const ExifData& exifData, BasicIo& out);
+        //@}
+
+        //! @name Accessors
+        //@{
+        EXV_DLLLOCAL uint32_t writeIptcData(const IptcData& iptcData, BasicIo& out) const;
+        EXV_DLLLOCAL uint32_t writeXmpData(const XmpData& xmpData, BasicIo& out) const;
         //@}
 
     }; // class PsdImage

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list