changeset 619:91c407bb6e1f

merge
author Volker Grabsch <vog@notjusthosting.com>
date Wed, 23 Dec 2009 10:40:40 +0100
parents fe658ac3b709 (current diff) 837543941a27 (diff)
children 74c840bcc16c
files
diffstat 5 files changed, 567 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Dec 23 10:40:05 2009 +0100
+++ b/.hgignore	Wed Dec 23 10:40:40 2009 +0100
@@ -1,3 +1,4 @@
+^usr/
+^log/
 ^pkg/
-^usr/
 ^dist/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devil.mk	Wed Dec 23 10:40:40 2009 +0100
@@ -0,0 +1,63 @@
+# Copyright (C) 2009  Volker Grabsch
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject
+# to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# DevIL
+PKG             := devil
+$(PKG)_IGNORE   :=
+$(PKG)_VERSION  := 1.7.8
+$(PKG)_CHECKSUM := bc27e3e830ba666a3af03548789700d10561fcb1
+$(PKG)_SUBDIR   := devil-$($(PKG)_VERSION)
+$(PKG)_FILE     := DevIL-$($(PKG)_VERSION).tar.gz
+$(PKG)_WEBSITE  := http://openil.sourceforge.net/
+$(PKG)_URL      := http://$(SOURCEFORGE_MIRROR)/project/openil/DevIL/$($(PKG)_VERSION)/$($(PKG)_FILE)
+$(PKG)_DEPS     := gcc zlib openexr jpeg jasper lcms libmng libpng tiff sdl
+
+define $(PKG)_UPDATE
+    wget -q -O- 'http://openil.svn.sourceforge.net/viewvc/openil/tags/?sortby=date' | \
+    grep '<a name="' | \
+    $(SED) -n 's,.*<a name="release-\([0-9][^"]*\)".*,\1,p' | \
+    head -1
+endef
+
+define $(PKG)_BUILD
+    $(SED) 's,__declspec(dllimport),,' -i '$(1)/include/IL/il.h'
+    # wine confuses the cross-compiling detection, so set it explicitly
+    $(SED) 's,cross_compiling=no,cross_compiling=yes,' -i '$(1)/configure'
+    cd '$(1)' && ./configure \
+        --host='$(TARGET)' \
+        --disable-shared \
+        --prefix='$(PREFIX)/$(TARGET)' \
+        --enable-ILU \
+        --enable-ILUT \
+        --disable-allegro \
+        --enable-directx8 \
+        --enable-directx9 \
+        --enable-opengl \
+        --enable-sdl \
+        --disable-sdltest \
+        --disable-wdp \
+        --with-zlib \
+        --without-squish \
+        --without-nvtt \
+        --without-x \
+        --without-examples
+    $(MAKE) -C '$(1)' -j '$(JOBS)' install bin_PROGRAMS= sbin_PROGRAMS= noinst_PROGRAMS= INFO_DEPS=
+endef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/exiv2-improvements.patch	Wed Dec 23 10:40:40 2009 +0100
@@ -0,0 +1,446 @@
+Copyright (C) 2009  Volker Grabsch
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject
+to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Fri Jul  3 11:44:14 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * avoid_extended_Photoshop_IRB_warnings
+Fri Jun 19 17:57:06 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * handle_extended_Photoshop_IRBs
+Thu Jun  4 20:12:36 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * recognize_small_corrupt_IRBs
+Thu Jun  4 15:48:36 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * new_function_Photoshop_valid
+Thu Jun  4 13:05:49 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * skip_writing_redundant_IPTC_IRBs
+Tue May 19 16:03:52 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * read_and_modify_only_the_first_XMP_segment
+Tue May 19 14:05:38 CEST 2009  Volker Grabsch <vog@notjusthosting.com>
+  * handle_empty_IRB
+diff -rN -u old-trunk-1/src/jpgimage.cpp new-trunk-1/src/jpgimage.cpp
+--- old-trunk-1/src/jpgimage.cpp	2009-06-25 17:10:32.000000000 +0200
++++ new-trunk-1/src/jpgimage.cpp	2009-06-25 17:10:32.000000000 +0200
+@@ -87,6 +87,23 @@
+     const char     Photoshop::bimId_[] = "8BIM";
+     const uint16_t Photoshop::iptc_    = 0x0404;
+ 
++    bool Photoshop::valid(const byte* pPsData,
++                          long        sizePsData)
++    {
++        const byte *record = 0;
++        uint32_t sizeIptc = 0;
++        uint32_t sizeHdr = 0;
++        const byte* pCur = pPsData;
++        const byte* pEnd = pPsData + sizePsData;
++        int ret = 0;
++        while (pCur < pEnd
++               && 0 == (ret = Photoshop::locateIptcIrb(pCur, static_cast<long>(pEnd - pCur),
++                                                       &record, &sizeHdr, &sizeIptc))) {
++            pCur = record + sizeHdr + sizeIptc + (sizeIptc & 1);
++        }
++        return ret >= 0;
++    }
++
+     // Todo: Generalised from JpegBase::locateIptcData without really understanding
+     //       the format (in particular the header). So it remains to be confirmed
+     //       if this also makes sense for psTag != Photoshop::iptc
+@@ -106,7 +123,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;
+@@ -121,8 +138,8 @@
+             position += psSize;
+             if (position + 4 > sizePsData) {
+ #ifndef SUPPRESS_WARNINGS
+-                std::cerr << "Error: "
+-                          << "Invalid Photoshop IRB\n";
++                std::cerr << "Warning: "
++                          << "Invalid or extended Photoshop IRB\n";
+ #endif
+                 return -2;
+             }
+@@ -130,9 +147,9 @@
+             position += 4;
+             if (dataSize > static_cast<uint32_t>(sizePsData - position)) {
+ #ifndef SUPPRESS_WARNINGS
+-                std::cerr << "Error: "
++                std::cerr << "Warning: "
+                           << "Invalid Photoshop IRB data size "
+-                          << dataSize << "\n";
++                          << dataSize << " or extended Photoshop IRB\n";
+ #endif
+                 return -2;
+             }
+@@ -158,6 +175,13 @@
+ #ifdef DEBUG
+         std::cerr << "pPsData doesn't start with '8BIM'\n";
+ #endif
++        if (position < sizePsData) {
++#ifndef SUPPRESS_WARNINGS
++            std::cerr << "Warning: "
++                      << "Invalid or extended Photoshop IRB\n";
++#endif
++            return -2;
++        }
+         return 3;
+     } // Photoshop::locateIrb
+ 
+@@ -210,15 +234,23 @@
+             // Data is padded to be even (but not included in size)
+             if (rawIptc.size_ & 1) psBlob.push_back(0x00);
+         }
+-        // Write existing stuff after record, data is rounded to be even.
+-        const uint32_t sizeOldData = sizeHdr + sizeIptc + (sizeIptc & 1);
+-        // Note: Because of the rounding, sizeFront + sizeOldData can be
+-        // _greater_ than sizePsData by 1 (not just equal), if the original
+-        // data was not padded.
+-        if (static_cast<uint32_t>(sizePsData) > sizeFront + sizeOldData) {
+-            append(psBlob, record + sizeOldData,
+-                   sizePsData - sizeFront - sizeOldData);
++        // Write existing stuff after record,
++        // skip the current and all remaining IPTC blocks
++        long pos = sizeFront;
++        while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos,
++                                             &record, &sizeHdr, &sizeIptc)) {
++            const long newPos = static_cast<long>(record - pPsData);
++            // Copy data up to the IPTC IRB
++            if (newPos > pos) {
++                append(psBlob, pPsData + pos, newPos - pos);
++            }
++            // Skip the IPTC IRB
++            pos = newPos + sizeHdr + sizeIptc + (sizeIptc & 1);
++        }
++        if (pos < sizePsData) {
++            append(psBlob, pPsData + pos, sizePsData - pos);
+         }
++        // Data is rounded to be even
+         if (psBlob.size() > 0) rc = DataBuf(&psBlob[0], static_cast<long>(psBlob.size()));
+ #ifdef DEBUG
+         std::cerr << "IRB block at the end of Photoshop::setIptcIrb\n";
+@@ -281,9 +313,10 @@
+         const long bufMinSize = 36;
+         long bufRead = 0;
+         DataBuf buf(bufMinSize);
+-        Blob iptcBlob;
+-        bool foundPsData = false;
++        Blob psBlob;
++        bool foundCompletePsData = false;
+         bool foundExifData = false;
++        bool foundXmpData = false;
+ 
+         // Read section marker
+         int marker = advanceToMarker();
+@@ -297,15 +330,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 (   !foundExifData
+                 && marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
+                 if (size < 8) {
+@@ -328,7 +352,8 @@
+                 --search;
+                 foundExifData = true;
+             }
+-            else if (marker == app1_ && memcmp(buf.pData_ + 2, xmpId_, 29) == 0) {
++            else if (   !foundXmpData
++                     && marker == app1_ && memcmp(buf.pData_ + 2, xmpId_, 29) == 0) {
+                 if (size < 31) {
+                     rc = 6;
+                     break;
+@@ -345,9 +370,10 @@
+ #endif
+                 }
+                 --search;
++                foundXmpData = true;
+             }
+-            else if (   marker == app13_
+-                     && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
++            else if (   !foundCompletePsData
++                     && marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
+                 if (size < 16) {
+                     rc = 2;
+                     break;
+@@ -357,32 +383,17 @@
+                 DataBuf psData(size - 16);
+                 io_->read(psData.pData_, psData.size_);
+                 if (io_->error() || io_->eof()) throw Error(14);
+-                const byte *record = 0;
+-                uint32_t sizeIptc = 0;
+-                uint32_t sizeHdr = 0;
+ #ifdef DEBUG
+                 std::cerr << "Found app13 segment, size = " << size << "\n";
+                 //hexdump(std::cerr, psData.pData_, psData.size_);
+ #endif
+-                // Find actual IPTC data within the APP13 segment
+-                const byte* pEnd = psData.pData_ + psData.size_;
+-                const byte* pCur = psData.pData_;
+-                while (   pCur < pEnd
+-                       && 0 == Photoshop::locateIptcIrb(pCur,
+-                                                        static_cast<long>(pEnd - pCur),
+-                                                        &record,
+-                                                        &sizeHdr,
+-                                                        &sizeIptc)) {
+-                    if (sizeIptc) {
+-#ifdef DEBUG
+-                        std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
+-#endif
+-                        append(iptcBlob, record + sizeHdr, sizeIptc);
+-                    }
+-                    pCur = record + sizeHdr + sizeIptc;
+-                    pCur += (sizeIptc & 1);
++                // Append to psBlob
++                append(psBlob, psData.pData_, psData.size_);
++                // Check whether psBlob is complete
++                if (Photoshop::valid(&psBlob[0], psBlob.size())) {
++                    --search;
++                    foundCompletePsData = true;
+                 }
+-                foundPsData = true;
+             }
+             else if (marker == com_ && comment_.empty())
+             {
+@@ -437,6 +448,24 @@
+             }
+         } // while there are segments to process
+ 
++        // Find actual IPTC data within the psBlob
++        Blob iptcBlob;
++        const byte *record = 0;
++        uint32_t sizeIptc = 0;
++        uint32_t sizeHdr = 0;
++        const byte* pCur = &psBlob[0];
++        const byte* pEnd = pCur + psBlob.size();
++        while (   pCur < pEnd
++               && 0 == Photoshop::locateIptcIrb(pCur, static_cast<long>(pEnd - pCur),
++                                                &record, &sizeHdr, &sizeIptc)) {
++#ifdef DEBUG
++            std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
++#endif
++            if (sizeIptc) {
++                append(iptcBlob, record + sizeHdr, sizeIptc);
++            }
++            pCur = record + sizeHdr + sizeIptc + (sizeIptc & 1);
++        }
+         if (   iptcBlob.size() > 0
+             && IptcParser::decode(iptcData_,
+                                   &iptcBlob[0],
+@@ -489,9 +518,10 @@
+         int comPos = 0;
+         int skipApp1Exif = -1;
+         int skipApp1Xmp = -1;
+-        int skipApp13Ps3 = -1;
++        bool foundCompletePsData = false;
++        std::vector<int> skipApp13Ps3;
+         int skipCom = -1;
+-        DataBuf psData;
++        Blob psBlob;
+         DataBuf rawExif;
+ 
+         // Write image header
+@@ -526,24 +556,31 @@
+                 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 (   skipApp1Xmp == -1
++                     && marker == app1_ && 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) {
++            else if (   !foundCompletePsData
++                     && marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
+ #ifdef DEBUG
+                 std::cerr << "Found APP13 Photoshop PS3 segment\n";
+ #endif
+                 if (size < 16) throw Error(22);
+-                skipApp13Ps3 = count;
+-                ++search;
++                skipApp13Ps3.push_back(count);
+                 io_->seek(16 - bufRead, BasicIo::cur);
+-                psData.alloc(size - 16);
+                 // Load PS data now to allow reinsertion at any point
++                DataBuf psData(size - 16);
+                 io_->read(psData.pData_, size - 16);
+                 if (io_->error() || io_->eof()) throw Error(20);
++                // Append to psBlob
++                append(psBlob, psData.pData_, psData.size_);
++                // Check whether psBlob is complete
++                if (Photoshop::valid(&psBlob[0], psBlob.size())) {
++                    foundCompletePsData = true;
++                }
+             }
+             else if (marker == com_ && skipCom == -1) {
+                 if (size < 2) throw Error(22);
+@@ -583,6 +620,10 @@
+             if (marker < 0) throw Error(22);
+             ++count;
+         }
++
++        if (!foundCompletePsData && skipApp13Ps3.size() > 0) throw Error(22);
++        search += skipApp13Ps3.size();
++
+         if (comPos == 0) {
+             if (marker == eoi_) comPos = count;
+             else comPos = insertPos;
+@@ -591,7 +632,7 @@
+         if (exifData_.count() > 0) ++search;
+         if (writeXmpFromPacket() == false && xmpData_.count() > 0) ++search;
+         if (writeXmpFromPacket() == true && xmpPacket_.size() > 0) ++search;
+-        if (iptcData_.count() > 0) ++search;
++        if (foundCompletePsData || iptcData_.count() > 0) ++search;
+         if (!comment_.empty()) ++search;
+ 
+         io_->seek(seek, BasicIo::beg);
+@@ -673,31 +714,44 @@
+                     if (outIo.error()) throw Error(21);
+                     --search;
+                 }
+-                if (psData.size_ > 0 || iptcData_.count() > 0) {
++                if (foundCompletePsData || 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
+-                    DataBuf newPsData = Photoshop::setIptcIrb(psData.pData_,
+-                                                              psData.size_,
++                    DataBuf newPsData = Photoshop::setIptcIrb(&psBlob[0],
++                                                              psBlob.size(),
+                                                               iptcData_);
+-                    if (newPsData.size_ > 0) {
+-                        // Write APP13 marker, new size, and ps3Id
++                    const long maxChunkSize = 0xffff - 16;
++                    const byte* chunkStart = newPsData.pData_;
++                    const byte* chunkEnd = chunkStart + newPsData.size_;
++                    while (chunkStart < chunkEnd) {
++                        // Determine size of next chunk
++                        long chunkSize = static_cast<long>(chunkEnd - chunkStart);
++                        if (chunkSize > maxChunkSize) {
++                            chunkSize = maxChunkSize;
++                            // Don't break at a valid IRB boundary
++                            const long writtenSize = static_cast<long>(chunkStart - newPsData.pData_);
++                            if (Photoshop::valid(newPsData.pData_, writtenSize + chunkSize)) {
++                                // Since an IRB has minimum size 12,
++                                // (chunkSize - 8) can't be also a IRB boundary
++                                chunkSize -= 8;
++                            }
++                        }
++
++                        // Write APP13 marker, chunk size, and ps3Id
+                         tmpBuf[0] = 0xff;
+                         tmpBuf[1] = app13_;
+-
+-                        if (newPsData.size_ + 16 > 0xffff) throw Error(37, "IPTC");
+-                        us2Data(tmpBuf + 2, static_cast<uint16_t>(newPsData.size_ + 16), bigEndian);
++                        us2Data(tmpBuf + 2, static_cast<uint16_t>(chunkSize + 16), bigEndian);
+                         std::memcpy(tmpBuf + 4, Photoshop::ps3Id_, 14);
+                         if (outIo.write(tmpBuf, 18) != 18) throw Error(21);
+                         if (outIo.error()) throw Error(21);
+ 
+-                        // Write new Photoshop IRB data buffer
+-                        if (   outIo.write(newPsData.pData_, newPsData.size_)
+-                            != newPsData.size_) throw Error(21);
++                        // Write next chunk of the Photoshop IRB data buffer
++                        if (outIo.write(chunkStart, chunkSize) != chunkSize) throw Error(21);
+                         if (outIo.error()) throw Error(21);
++
++                        chunkStart += chunkSize;
+                     }
+-                    if (iptcData_.count() > 0) {
+-                        --search;
+-                    }
++                    --search;
+                 }
+             }
+             if (comPos == count) {
+@@ -724,7 +778,7 @@
+             }
+             else if (   skipApp1Exif == count
+                      || skipApp1Xmp  == count
+-                     || skipApp13Ps3 == count
++                     || find(skipApp13Ps3.begin(), skipApp13Ps3.end(), count) != skipApp13Ps3.end()
+                      || skipCom      == count) {
+                 --search;
+                 io_->seek(size-bufRead, BasicIo::cur);
+diff -rN -u old-trunk-1/src/jpgimage.hpp new-trunk-1/src/jpgimage.hpp
+--- old-trunk-1/src/jpgimage.hpp	2009-06-25 17:10:32.000000000 +0200
++++ new-trunk-1/src/jpgimage.hpp	2009-06-25 17:10:32.000000000 +0200
+@@ -64,6 +64,16 @@
+         static const uint16_t iptc_;    //!< %Photoshop IPTC marker
+ 
+         /*!
++          @brief Validates all IRBs
++
++          @param pPsData        Existing IRB buffer
++          @param sizePsData     Size of the IRB buffer, may be 0
++          @return true  if all IRBs are valid;<BR>
++                  false otherwise
++        */
++        static bool valid(const byte* pPsData,
++                          long        sizePsData);
++        /*!
+           @brief Locates the data for a %Photoshop tag in a %Photoshop formated memory
+               buffer. Operates on raw data to simplify reuse.
+           @param pPsData Pointer to buffer containing entire payload of
+
+diff -rN -u old-trunk-1/src/jpgimage.cpp new-trunk-1/src/jpgimage.cpp
+--- old-trunk-1/src/jpgimage.cpp	2009-07-03 12:02:48.000000000 +0200
++++ new-trunk-1/src/jpgimage.cpp	2009-07-03 12:02:48.000000000 +0200
+@@ -137,7 +137,7 @@
+             psSize += (psSize & 1);
+             position += psSize;
+             if (position + 4 > sizePsData) {
+-#ifndef SUPPRESS_WARNINGS
++#ifdef DEBUG
+                 std::cerr << "Warning: "
+                           << "Invalid or extended Photoshop IRB\n";
+ #endif
+@@ -146,7 +146,7 @@
+             uint32_t dataSize = getULong(pPsData + position, bigEndian);
+             position += 4;
+             if (dataSize > static_cast<uint32_t>(sizePsData - position)) {
+-#ifndef SUPPRESS_WARNINGS
++#ifdef DEBUG
+                 std::cerr << "Warning: "
+                           << "Invalid Photoshop IRB data size "
+                           << dataSize << " or extended Photoshop IRB\n";
+@@ -176,7 +176,7 @@
+         std::cerr << "pPsData doesn't start with '8BIM'\n";
+ #endif
+         if (position < sizePsData) {
+-#ifndef SUPPRESS_WARNINGS
++#ifdef DEBUG
+             std::cerr << "Warning: "
+                       << "Invalid or extended Photoshop IRB\n";
+ #endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/exiv2.mk	Wed Dec 23 10:40:40 2009 +0100
@@ -0,0 +1,54 @@
+# Copyright (C) 2009  Volker Grabsch
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject
+# to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+# Exiv2
+PKG             := exiv2
+$(PKG)_IGNORE   :=
+$(PKG)_VERSION  := 0.18.2
+$(PKG)_CHECKSUM := 452c824a780843a568eeef68f30785ee4141b0a8
+$(PKG)_SUBDIR   := exiv2-$($(PKG)_VERSION)
+$(PKG)_FILE     := exiv2-$($(PKG)_VERSION).tar.gz
+$(PKG)_WEBSITE  := http://www.exiv2.org/
+$(PKG)_URL      := http://www.exiv2.org/$($(PKG)_FILE)
+$(PKG)_DEPS     := gcc libiconv zlib expat
+
+define $(PKG)_UPDATE
+    wget -q -O- 'http://www.exiv2.org/download.html' | \
+    grep 'href="exiv2-' | \
+    $(SED) -n 's,.*exiv2-\([0-9][^>]*\)\.tar.*,\1,p' | \
+    head -1
+endef
+
+define $(PKG)_BUILD
+    # workaround for the missing snprintf() in the <cstdio> of GCC-4.4.0
+    $(SED) 's,#include <cstdio>,#include <stdio.h>,' -i '$(1)/xmpsdk/src/XMPMeta.cpp'
+    # wine confuses the cross-compiling detection, so set it explicitly
+    $(SED) 's,cross_compiling=no,cross_compiling=yes,' -i '$(1)/configure'
+    cd '$(1)' && ./configure \
+        --host='$(TARGET)' \
+        --disable-shared \
+        --prefix='$(PREFIX)/$(TARGET)' \
+        --disable-visibility \
+        --disable-nls \
+        --with-expat
+    $(MAKE) -C '$(1)/xmpsdk/src' -j '$(JOBS)'
+    $(MAKE) -C '$(1)/src'        -j '$(JOBS)' install-lib
+endef
--- a/src/jpeg.mk	Wed Dec 23 10:40:05 2009 +0100
+++ b/src/jpeg.mk	Wed Dec 23 10:40:40 2009 +0100
@@ -37,6 +37,8 @@
 endef
 
 define $(PKG)_BUILD
+    # avoid redefinition of INT32
+    $(SED) 's,#ifndef XMD_H,#if (!defined(XMD_H) \&\& !defined(_BASETSD_H)),' -i '$(1)/jmorecfg.h'
     cd '$(1)' && ./configure \
         CC='$(TARGET)-gcc' RANLIB='$(TARGET)-ranlib' \
         --disable-shared \