Index: exiv2-svn/src/jpgimage.hpp
===================================================================
--- exiv2-svn/src/jpgimage.hpp	(Revision 1618)
+++ exiv2-svn/src/jpgimage.hpp	(Arbeitskopie)
@@ -95,17 +95,19 @@
                                  uint32_t *const sizeHdr,
                                  uint32_t *const sizeData);
         /*!
-          @brief Set the new IPTC IRB, keeps existing IRBs but removes the
-                 IPTC block if there is no new IPTC data to write.
+          @brief Set the new IPTC IRB, keeps existing IRBs
 
-          @param pPsData    Existing IRB buffer
-          @param sizePsData Size of the IRB buffer, may be 0
-          @param iptcData   Iptc data to embed, may be empty
+          @param pPsData        Existing IRB buffer
+          @param sizePsData     Size of the IRB buffer, may be 0
+          @param iptcData       Iptc data to embed, may be empty
+          @param keepEmptyBlock Whether to keep the IPTC block even
+                                when there is no new IPTC data to write
           @return A data buffer containing the new IRB buffer, may have 0 size
         */
         static DataBuf setIptcIrb(const byte*     pPsData,
                                   long            sizePsData,
-                                  const IptcData& iptcData);
+                                  const IptcData& iptcData,
+                                  bool            keepEmptyBlock=false);
 
     }; // class Photoshop
 
Index: exiv2-svn/src/jpgimage.cpp
===================================================================
--- exiv2-svn/src/jpgimage.cpp	(Revision 1618)
+++ exiv2-svn/src/jpgimage.cpp	(Arbeitskopie)
@@ -106,7 +106,7 @@
         std::cerr << "Photoshop::locateIrb: ";
 #endif
         // Data should follow Photoshop format, if not exit
-        while (   position <= sizePsData - 14
+        while (   position <= sizePsData - 12
                && memcmp(pPsData + position, Photoshop::bimId_, 4) == 0) {
             const byte *hrd = pPsData + position;
             position += 4;
@@ -173,7 +173,8 @@
 
     DataBuf Photoshop::setIptcIrb(const byte*     pPsData,
                                   long            sizePsData,
-                                  const IptcData& iptcData)
+                                  const IptcData& iptcData,
+                                  bool            keepEmptyBlock)
     {
         if (sizePsData > 0) assert(pPsData);
 #ifdef DEBUG
@@ -198,7 +199,7 @@
         }
         // Write new iptc record if we have it
         DataBuf rawIptc = IptcParser::encode(iptcData);
-        if (rawIptc.size_ > 0) {
+        if (rawIptc.size_ > 0 || keepEmptyBlock) {
             byte tmpBuf[12];
             std::memcpy(tmpBuf, Photoshop::bimId_, 4);
             us2Data(tmpBuf + 4, iptc_, bigEndian);
@@ -281,7 +282,6 @@
         const long bufMinSize = 36;
         long bufRead = 0;
         DataBuf buf(bufMinSize);
-        Blob iptcBlob;
         bool foundPsData = false;
 
         // Read section marker
@@ -296,15 +296,6 @@
             if (bufRead < 2) throw Error(15);
             uint16_t size = getUShort(buf.pData_, bigEndian);
 
-            if (foundPsData && marker != app13_) {
-                // For IPTC, decrement search only after all app13 segments are
-                // loaded, assuming they all appear in sequence. But decode IPTC
-                // data after the loop, in case an app13 is the last segment
-                // before sos or eoi.
-                foundPsData = false;
-                if (--search == 0) break;
-            }
-
             if (marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
                 if (size < 8) {
                     rc = 1;
@@ -344,6 +335,7 @@
                 --search;
             }
             else if (   marker == app13_
+                     && !foundPsData
                      && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
                 if (size < 16) {
                     rc = 2;
@@ -354,6 +346,7 @@
                 DataBuf psData(size - 16);
                 io_->read(psData.pData_, psData.size_);
                 if (io_->error() || io_->eof()) throw Error(14);
+                Blob iptcBlob;
                 const byte *record = 0;
                 uint32_t sizeIptc = 0;
                 uint32_t sizeHdr = 0;
@@ -370,16 +363,26 @@
                                                         &record,
                                                         &sizeHdr,
                                                         &sizeIptc)) {
-                    if (sizeIptc) {
 #ifdef DEBUG
-                        std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
+                    std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
 #endif
+                    if (sizeIptc) {
                         append(iptcBlob, record + sizeHdr, sizeIptc);
                     }
                     pCur = record + sizeHdr + sizeIptc;
                     pCur += (sizeIptc & 1);
                 }
+                if (   iptcBlob.size() > 0
+                    && IptcParser::decode(iptcData_,
+                                          &iptcBlob[0],
+                                          static_cast<uint32_t>(iptcBlob.size()))) {
+#ifndef SUPPRESS_WARNINGS
+                    std::cerr << "Warning: Failed to decode IPTC metadata.\n";
+#endif
+                    iptcData_.clear();
+                }
                 foundPsData = true;
+                --search;
             }
             else if (marker == com_ && comment_.empty())
             {
@@ -434,16 +437,6 @@
             }
         } // while there are segments to process
 
-        if (   iptcBlob.size() > 0
-            && IptcParser::decode(iptcData_,
-                                  &iptcBlob[0],
-                                  static_cast<uint32_t>(iptcBlob.size()))) {
-#ifndef SUPPRESS_WARNINGS
-            std::cerr << "Warning: Failed to decode IPTC metadata.\n";
-#endif
-            iptcData_.clear();
-        }
-
         if (rc != 0) {
 #ifndef SUPPRESS_WARNINGS
             std::cerr << "Warning: JPEG format error, rc = " << rc << "\n";
@@ -487,6 +480,7 @@
         int skipApp1Xmp = -1;
         int skipApp13Ps3 = -1;
         int skipCom = -1;
+        bool multipleApp13Ps3 = false;
         DataBuf psData;
         DataBuf rawExif;
 
@@ -511,7 +505,8 @@
                 insertPos = count + 1;
                 if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
             }
-            else if (marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
+            else if (marker == app1_ && skipApp1Exif == -1
+                     && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
                 if (size < 8) throw Error(22);
                 skipApp1Exif = count;
                 ++search;
@@ -521,24 +516,32 @@
                 io_->read(rawExif.pData_, rawExif.size_);
                 if (io_->error() || io_->eof()) throw Error(22);
             }
-            else if (marker == app1_ && memcmp(buf.pData_ + 2, xmpId_, 29) == 0) {
+            else if (marker == app1_ && skipApp1Xmp == -1
+                     && memcmp(buf.pData_ + 2, xmpId_, 29) == 0) {
                 if (size < 31) throw Error(22);
                 skipApp1Xmp = count;
                 ++search;
                 if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
             }
             else if (marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
+                if (skipApp13Ps3 == -1) {
 #ifdef DEBUG
-                std::cerr << "Found APP13 Photoshop PS3 segment\n";
+                    std::cerr << "Found APP13 Photoshop PS3 segment\n";
 #endif
-                if (size < 16) throw Error(22);
-                skipApp13Ps3 = count;
-                ++search;
-                io_->seek(16 - bufRead, BasicIo::cur);
-                psData.alloc(size - 16);
-                // Load PS data now to allow reinsertion at any point
-                io_->read(psData.pData_, size - 16);
-                if (io_->error() || io_->eof()) throw Error(20);
+                    if (size < 16) throw Error(22);
+                    skipApp13Ps3 = count;
+                    ++search;
+                    io_->seek(16 - bufRead, BasicIo::cur);
+                    psData.alloc(size - 16);
+                    // Load PS data now to allow reinsertion at any point
+                    io_->read(psData.pData_, size - 16);
+                    if (io_->error() || io_->eof()) throw Error(20);
+                } else {
+#ifdef DEBUG
+                    std::cerr << "Found another APP13 Photoshop PS3 segment\n";
+#endif
+                    multipleApp13Ps3 = true;
+                }
             }
             else if (marker == com_ && skipCom == -1) {
                 if (size < 2) throw Error(22);
@@ -658,9 +661,11 @@
                 if (psData.size_ > 0 || iptcData_.count() > 0) {
                     // Set the new IPTC IRB, keeps existing IRBs but removes the
                     // IPTC block if there is no new IPTC data to write
+                    // and no other IPTC IRBs are following
                     DataBuf newPsData = Photoshop::setIptcIrb(psData.pData_,
                                                               psData.size_,
-                                                              iptcData_);
+                                                              iptcData_,
+                                                              multipleApp13Ps3);
                     if (newPsData.size_ > 0) {
                         // Write APP13 marker, new size, and ps3Id
                         tmpBuf[0] = 0xff;
