changeset 2207:bbb1d964e854

package exiv2: add an important bugfix
author Volker Grabsch <vog@notjusthosting.com>
date Fri, 13 Jan 2012 17:17:44 +0100
parents 1286c378d068
children ddc26046c388
files src/exiv2-r2646.patch
diffstat 1 files changed, 175 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/exiv2-r2646.patch	Fri Jan 13 17:17:44 2012 +0100
@@ -0,0 +1,175 @@
+This file is part of mingw-cross-env.
+See doc/index.html for further information.
+
+This patch has been taken from:
+http://dev.exiv2.org/projects/exiv2/repository/revisions/2646
+
+Index: trunk/src/jpgimage.cpp
+===================================================================
+--- trunk/src/jpgimage.cpp	(revision 2645)
++++ trunk/src/jpgimage.cpp	(revision 2646)
+@@ -86,10 +86,21 @@
+     const char     JpegBase::xmpId_[]  = "http://ns.adobe.com/xap/1.0/\0";
+ 
+     const char     Photoshop::ps3Id_[] = "Photoshop 3.0\0";
+-    const char     Photoshop::bimId_[] = "8BIM";
++    const char*    Photoshop::irbId_[] = {"8BIM", "AgHg", "DCSR", "PHUT"};
+     const uint16_t Photoshop::iptc_    = 0x0404;
+     const uint16_t Photoshop::preview_ = 0x040c;
+ 
++    bool Photoshop::isIrb(const byte* pPsData,
++                          long        sizePsData)
++    {
++        if (sizePsData < 4) return false;
++        for (size_t i = 0; i < (sizeof irbId_) / (sizeof *irbId_); i++) {
++            assert(strlen(irbId_[i]) == 4);
++            if (memcmp(pPsData, irbId_[i], 4) == 0) return true;
++        }
++        return false;
++    }
++
+     bool Photoshop::valid(const byte* pPsData,
+                           long        sizePsData)
+     {
+@@ -126,8 +137,7 @@
+         std::cerr << "Photoshop::locateIrb: ";
+ #endif
+         // Data should follow Photoshop format, if not exit
+-        while (   position <= sizePsData - 12
+-               && memcmp(pPsData + position, Photoshop::bimId_, 4) == 0) {
++        while (position <= sizePsData - 12 && isIrb(pPsData + position, 4)) {
+             const byte *hrd = pPsData + position;
+             position += 4;
+             uint16_t type = getUShort(pPsData + position, bigEndian);
+@@ -237,7 +247,7 @@
+         DataBuf rawIptc = IptcParser::encode(iptcData);
+         if (rawIptc.size_ > 0) {
+             byte tmpBuf[12];
+-            std::memcpy(tmpBuf, Photoshop::bimId_, 4);
++            std::memcpy(tmpBuf, Photoshop::irbId_[0], 4);
+             us2Data(tmpBuf + 4, iptc_, bigEndian);
+             tmpBuf[6] = 0;
+             tmpBuf[7] = 0;
+Index: trunk/src/jpgimage.hpp
+===================================================================
+--- trunk/src/jpgimage.hpp	(revision 2645)
++++ trunk/src/jpgimage.hpp	(revision 2646)
+@@ -64,11 +64,21 @@
+     struct EXIV2API Photoshop {
+         // Todo: Public for now
+         static const char     ps3Id_[]; //!< %Photoshop marker
+-        static const char     bimId_[]; //!< %Photoshop marker
++        static const char*    irbId_[]; //!< %Photoshop IRB markers
+         static const uint16_t iptc_;    //!< %Photoshop IPTC marker
+         static const uint16_t preview_; //!< %Photoshop preview marker
+ 
+         /*!
++          @brief Checks an IRB
++
++          @param pPsData        Existing IRB buffer
++          @param sizePsData     Size of the IRB buffer
++          @return true  if the IRB marker is known and the buffer is big enough to check this;<BR>
++                  false otherwise
++        */
++        static bool isIrb(const byte* pPsData,
++                          long        sizePsData);
++        /*!
+           @brief Validates all IRBs
+ 
+           @param pPsData        Existing IRB buffer
+Index: trunk/src/psdimage.cpp
+===================================================================
+--- trunk/src/psdimage.cpp	(revision 2645)
++++ trunk/src/psdimage.cpp	(revision 2646)
+@@ -39,6 +39,7 @@
+ # include "exv_conf.h"
+ #endif
+ #include "psdimage.hpp"
++#include "jpgimage.hpp"
+ #include "image.hpp"
+ #include "basicio.hpp"
+ #include "error.hpp"
+@@ -56,11 +57,9 @@
+ //       Extend this helper to a proper class with all required functionality,
+ //       then move it here or into a separate file?
+ 
+-const uint32_t kPhotoshopResourceType = 0x3842494d; // '8BIM'
+-
+ //! @cond IGNORE
+ struct PhotoshopResourceBlock {
+-    uint32_t      resourceType;       // always kPhotoshopResourceType
++    uint32_t      resourceType;       // one of the markers in Photoshop::irbId_[]
+     uint16_t      resourceId;
+     unsigned char resourceName[2];    // Pascal string (length byte + characters), padded to an even size -- this assumes the empty string
+     uint32_t      resourceDataSize;
+@@ -215,14 +214,11 @@
+                 throw Error(3, "Photoshop");
+             }
+ 
+-            // read resource type and ID
+-            uint32_t resourceType = getULong(buf, bigEndian);
+-            uint16_t resourceId = getUShort(buf + 4, bigEndian);
+-
+-            if (resourceType != kPhotoshopResourceType)
++            if (!Photoshop::isIrb(buf, 4))
+             {
+                 break; // bad resource type
+             }
++            uint16_t resourceId = getUShort(buf + 4, bigEndian);
+             uint32_t resourceNameLength = buf[6] & ~1;
+ 
+             // skip the resource name, plus any padding
+@@ -447,7 +443,8 @@
+             // read resource type and ID
+             uint32_t resourceType = getULong(buf, bigEndian);
+ 
+-            if (resourceType != kPhotoshopResourceType) {
++            if (!Photoshop::isIrb(buf, 4))
++            {
+                 throw Error(3, "Photoshop"); // bad resource type
+             }
+             uint16_t resourceId = getUShort(buf + 4, bigEndian);
+@@ -493,11 +490,12 @@
+                 && resourceId != kPhotoshopResourceID_ExifInfo
+                 && resourceId != kPhotoshopResourceID_XMPPacket) {
+ #ifdef DEBUG
++                std::cerr << std::hex << "copy : resourceType: " << resourceType << "\n";
+                 std::cerr << std::hex << "copy : resourceId: " << resourceId << "\n";
+                 std::cerr << std::dec;
+ #endif
+                 // Copy resource block to new PSD file
+-                ul2Data(buf, kPhotoshopResourceType, bigEndian);
++                ul2Data(buf, resourceType, bigEndian);
+                 if (outIo.write(buf, 4) != 4) throw Error(21);
+                 us2Data(buf, resourceId, bigEndian);
+                 if (outIo.write(buf, 2) != 2) throw Error(21);
+@@ -577,8 +575,7 @@
+                 std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_IPTC_NAA << "\n";
+                 std::cerr << std::dec << "Writing IPTC_NAA: size: " << rawIptc.size_ << "\n";
+ #endif
+-                ul2Data(buf, kPhotoshopResourceType, bigEndian);
+-                if (out.write(buf, 4) != 4) throw Error(21);
++                if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 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
+@@ -618,8 +615,7 @@
+                 std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_ExifInfo << "\n";
+                 std::cerr << std::dec << "Writing ExifInfo: size: " << blob.size() << "\n";
+ #endif
+-                ul2Data(buf, kPhotoshopResourceType, bigEndian);
+-                if (out.write(buf, 4) != 4) throw Error(21);
++                if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 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
+@@ -663,8 +659,7 @@
+             std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_XMPPacket << "\n";
+             std::cerr << std::dec << "Writing XMPPacket: size: " << xmpPacket.size() << "\n";
+ #endif
+-            ul2Data(buf, kPhotoshopResourceType, bigEndian);
+-            if (out.write(buf, 4) != 4) throw Error(21);
++            if (out.write(reinterpret_cast<const byte*>(Photoshop::irbId_[0]), 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