diff --git a/include/exiv2/pngimage.hpp b/include/exiv2/pngimage.hpp index ed538902..cfa83da1 100644 --- a/include/exiv2/pngimage.hpp +++ b/include/exiv2/pngimage.hpp @@ -113,6 +113,8 @@ namespace Exiv2 void doWriteMetadata(BasicIo& oIo); //@} + std::string profileName_; + }; // class PngImage // ***************************************************************************** diff --git a/src/pngimage.cpp b/src/pngimage.cpp index b4e5ed1c..6eb74421 100644 --- a/src/pngimage.cpp +++ b/src/pngimage.cpp @@ -462,16 +462,16 @@ namespace Exiv2 { // The ICC profile name can vary from 1-79 characters. uint32_t iccOffset = 0; while (iccOffset < 80 && iccOffset < chunkLength) { - const byte* profileName = chunkData.pData_ + iccOffset; - ++iccOffset; - if (*profileName == 0x00) + if (chunkData.pData_[iccOffset++] == 0x00) { break; + } } + profileName_ = std::string(reinterpret_cast(chunkData.pData_), iccOffset-1); ++iccOffset; // +1 = 'compressed' flag zlibToDataBuf(chunkData.pData_ + iccOffset, chunkLength - iccOffset, iccProfile_); #ifdef DEBUG - std::cout << "Exiv2::PngImage::readMetadata: profile name size: " << iccOffset - 2 << std::endl; + std::cout << "Exiv2::PngImage::readMetadata: profile name: " << profileName_ << std::endl; std::cout << "Exiv2::PngImage::readMetadata: iccProfile.size_ (uncompressed) : " << iccProfile_.size_ << std::endl; #endif @@ -619,25 +619,26 @@ namespace Exiv2 { DataBuf compressed; if ( zlibToCompressed(iccProfile_.pData_,iccProfile_.size_,compressed) ) { - const byte* header = (const byte*) "ICC PROFILE\0\0" ; // \0 = default compression + const byte* nullComp = (const byte*) "\0\0"; const byte* type = (const byte*) "iCCP"; - uint32_t headerLen = 13 ; - uint32_t typeLen = 4; - uint32_t chunkLength = headerLen + compressed.size_ ; + const long nameLength = profileName_.size(); + const uint32_t chunkLength = profileName_.size() + 2 + compressed.size_ ; byte length[4]; ul2Data (length,chunkLength,bigEndian); // calculate CRC uLong tmp = crc32(0L, Z_NULL, 0); - tmp = crc32(tmp, (const Bytef*)type ,typeLen); - tmp = crc32(tmp, (const Bytef*)header ,headerLen); + tmp = crc32(tmp, (const Bytef*)type, 4); + tmp = crc32(tmp, (const Bytef*)profileName_.data(), nameLength); + tmp = crc32(tmp, (const Bytef*)nullComp, 2); tmp = crc32(tmp, (const Bytef*)compressed.pData_,compressed.size_); byte crc[4]; ul2Data(crc, tmp, bigEndian); - if( outIo.write(length,4) != 4 - || outIo.write(type ,typeLen) != (long) typeLen - || outIo.write(header,headerLen) != (long) headerLen + if( outIo.write(length, 4) != 4 + || outIo.write(type, 4) != 4 + || outIo.write(reinterpret_cast(profileName_.data()), nameLength) != nameLength + || outIo.write(nullComp,2) != 2 || outIo.write (compressed.pData_,compressed.size_) != compressed.size_ || outIo.write(crc,4) != 4 ){ @@ -645,7 +646,7 @@ namespace Exiv2 { } #ifdef DEBUG std::cout << "Exiv2::PngImage::doWriteMetadata: build iCCP" - << " chunk (length: " << compressed.size_ + headerLen << ")" << std::endl; + << " chunk (length: " << compressed.size_ + chunkLength << ")" << std::endl; #endif } } diff --git a/test/data/icc-test.out b/test/data/icc-test.out index 56f99beb..54b9c2e9 100644 --- a/test/data/icc-test.out +++ b/test/data/icc-test.out @@ -310,7 +310,7 @@ STRUCTURE OF PNG FILE: ReaganLargePng.png 33 | iTXt | 31 | Description.....x.KLJNIMK..... | 0xc1fefec8 76 | zTXt | 8461 | Raw profile type exif..x...iv. | 0x91fbf6a0 8549 | zTXt | 636 | Raw profile type iptc..x..TKn. | 0x4e5178d3 - 9197 | iCCP | 1159185 | ICC PROFILE..x...uP.[..9@.HB.D | 0x92791a05 + 9197 | iCCP | 1159185 | ICC profile..x...uP.[..9@.HB.D | 0xd3dbe519 1168394 | iTXt | 7156 | XML:com.adobe.xmp.....