This file is part of MXE. See 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;
+ 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(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(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(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