#1074 Added ICC support to tiffimage.writeMetadata(). pngimage.readMetadata() is not complete.

v0.27.3
Robin Mills 9 years ago
parent 925fede113
commit 3aaebf50f7

@ -234,6 +234,11 @@ namespace Exiv2 {
@param iccProfile DataBuf containing profile (binary)
*/
virtual void setIccProfile(DataBuf& iccProfile);
/*!
@brief find the iccProfile using printStructure() and call setIccProfile()
*/
virtual void findIccProfile();
/*!
@brief Erase iccProfile. the profile is not removed from
the actual image until the writeMetadata() method is called.

@ -370,6 +370,25 @@ namespace Exiv2 {
{
return (supportedMetadata_ & metadataId) != 0;
}
void Image::findIccProfile()
{
if (io().open() != 0) return;
long restore = io().tell();
std::stringstream binary( std::ios_base::out | std::ios_base::in | std::ios_base::binary );
io().seek(0,Exiv2::BasicIo::beg);
printStructure(binary,kpsIccProfile,0);
long length = (long) binary.rdbuf()->pubseekoff(0, binary.end, binary.out);
DataBuf iccProfile(length);
binary.rdbuf()->pubseekoff(0, binary.beg, binary.out); // rewind
binary.read((char*)iccProfile.pData_,iccProfile.size_);
#if 1
std::cerr << "findIccProfile length:" << length <<" data:"<< Internal::binaryToString(iccProfile.pData_, length > 24?24:length,0) << std::endl;
#endif
setIccProfile(iccProfile);
io().seek(restore,Exiv2::BasicIo::beg);
} // findIccProfile
AccessMode Image::checkMode(MetadataId metadataId) const
{
@ -579,7 +598,7 @@ namespace Exiv2 {
}
return Image::AutoPtr();
} // ImageFactory::create
// *****************************************************************************
// template, inline and free functions

@ -533,21 +533,7 @@ namespace Exiv2 {
}
} // psBlob.size() > 0
if ( rc==0 && foundIccData ) {
long restore = io_->tell();
std::stringstream binary( std::ios_base::out | std::ios_base::in | std::ios_base::binary );
io_->seek(0,Exiv2::BasicIo::beg);
printStructure(binary,kpsIccProfile,0);
long length = (long) binary.rdbuf()->pubseekoff(0, binary.end, binary.out);
DataBuf iccProfile(length);
binary.rdbuf()->pubseekoff(0, binary.beg, binary.out); // rewind
binary.read((char*)iccProfile.pData_,iccProfile.size_);
#if DEBUG
std::cerr << "iccProfile length:" << length <<" data:"<< Internal::binaryToString(iccProfile.pData_, length > 24?24:length,0) << std::endl;
#endif
setIccProfile(iccProfile);
io_->seek(restore,Exiv2::BasicIo::beg);
}
if ( rc==0 && foundIccData ) findIccProfile();
if (rc != 0) {
#ifndef SUPPRESS_WARNINGS

@ -334,7 +334,18 @@ namespace Exiv2 {
throw Error(3, "PNG");
}
clearMetadata();
/*
// Add icc profile to the metadata (see comments in writeMetadata())
if ( iccProfile_.size_ == 0 ) {
findIccProfile();
Exiv2::ExifKey key("Exif.Image.InterColorProfile");
if ( iccProfile_.size_ > 0 && exifData_.findKey(key) == exifData_.end() ) {
Exiv2::DataValue value(iccProfile_.pData_,iccProfile_.size_);
exifData_.add(key,&value);
}
}
*/
const long imgSize = io_->size();
DataBuf cheaderBuf(8); // Chunk header size : 4 bytes (data size) + 4 bytes (chunk type).
@ -420,7 +431,7 @@ namespace Exiv2 {
io_->seek(dataOffset + 4 , BasicIo::cur);
if (io_->error() || io_->eof()) throw Error(14);
}
} // PngImage::readMetadata
void PngImage::writeMetadata()
@ -455,6 +466,14 @@ namespace Exiv2 {
if (io_->error() || io_->eof()) throw Error(20);
throw Error(22);
}
// remove the ICC profile from the exifData because it's only "parked"
// we should not store ICC profiles in the ExifData
// PNG use an ICCP segment.
Exiv2::ExifKey key("Exif.Image.InterColorProfile");
Exiv2::ExifData::iterator pos = exifData_.findKey(key);
if ( pos != exifData_.end() ) exifData_.erase(pos);
// Write PNG Signature.
if (outIo.write(pngSignature, 8) != 8) throw Error(21);
@ -510,6 +529,17 @@ namespace Exiv2 {
}
}
if ( iccProfile_.size_ > 0 )
{
// Update Comment data to a new PNG chunk
//std::string chunk = PngChunk::makeMetadataChunk(comment_, mdComment);
//if (outIo.write((const byte*)chunk.data(), static_cast<long>(chunk.size())) != (long)chunk.size())
//{
// throw Error(21);
//}
std::cout << "found an ICC profile" << std::endl;
}
if (exifData_.count() > 0)
{
// Update Exif data to a new PNG chunk

@ -218,6 +218,19 @@ namespace Exiv2 {
bo = littleEndian;
}
setByteOrder(bo);
// fixup ICC profile
Exiv2::ExifKey key("Exif.Image.InterColorProfile");
Exiv2::ExifData::iterator pos = exifData_.findKey(key);
bool found = pos != exifData_.end();
if ( iccProfile_.size_ > 0 ) {
Exiv2::DataValue value(iccProfile_.pData_,iccProfile_.size_);
if ( found ) pos->setValue(&value);
else exifData_.add(key,&value);
} else {
if ( found ) exifData_.erase(pos);
}
TiffParser::encode(*io_, pData, size, bo, exifData_, iptcData_, xmpData_); // may throw
} // TiffImage::writeMetadata
@ -2503,7 +2516,7 @@ namespace Exiv2 {
{ 0x0214, ifd0Id }, // Exif.Image.ReferenceBlackWhite
{ 0x828d, ifd0Id }, // Exif.Image.CFARepeatPatternDim
{ 0x828e, ifd0Id }, // Exif.Image.CFAPattern
{ 0x8773, ifd0Id }, // Exif.Image.InterColorProfile
// { 0x8773, ifd0Id }, // Exif.Image.InterColorProfile
{ 0x8824, ifd0Id }, // Exif.Image.SpectralSensitivity
{ 0x8828, ifd0Id }, // Exif.Image.OECF
{ 0x9102, ifd0Id }, // Exif.Image.CompressedBitsPerPixel

Loading…
Cancel
Save