#1074. jpgimage.cpp ICC support (Work in Progress)

v0.27.3
Robin Mills 9 years ago
parent 7cf3cb1fbf
commit 06eabfdd88

@ -228,6 +228,17 @@ namespace Exiv2 {
from the actual image until the writeMetadata() method is called. from the actual image until the writeMetadata() method is called.
*/ */
virtual void clearComment(); virtual void clearComment();
/*!
@brief Set the image iccProfile. The new profile is not written
to the image until the writeMetadata() method is called.
@param iccProfile DataBuf containing profile (binary)
*/
virtual void setIccProfile(DataBuf& iccProfile);
/*!
@brief Erase iccProfile. the profile isnot not removed from
the actual image until the writeMetadata() method is called.
*/
virtual void clearIccProfile();
/*! /*!
@brief Copy all existing metadata from source Image. The data is @brief Copy all existing metadata from source Image. The data is
copied into internal buffers and is not written to the image copied into internal buffers and is not written to the image
@ -422,6 +433,7 @@ namespace Exiv2 {
ExifData exifData_; //!< Exif data container ExifData exifData_; //!< Exif data container
IptcData iptcData_; //!< IPTC data container IptcData iptcData_; //!< IPTC data container
XmpData xmpData_; //!< XMP data container XmpData xmpData_; //!< XMP data container
DataBuf iccProfile_; //!< ICC buffer (binary data)
std::string comment_; //!< User comment std::string comment_; //!< User comment
std::string xmpPacket_; //!< XMP packet std::string xmpPacket_; //!< XMP packet
int pixelWidth_; //!< image pixel width int pixelWidth_; //!< image pixel width

@ -233,6 +233,7 @@ namespace Exiv2 {
static const byte eoi_; //!< JPEG EOI marker static const byte eoi_; //!< JPEG EOI marker
static const byte app0_; //!< JPEG APP0 marker static const byte app0_; //!< JPEG APP0 marker
static const byte app1_; //!< JPEG APP1 marker static const byte app1_; //!< JPEG APP1 marker
static const byte app2_; //!< JPEG APP2 marker
static const byte app13_; //!< JPEG APP13 marker static const byte app13_; //!< JPEG APP13 marker
static const byte com_; //!< JPEG Comment marker static const byte com_; //!< JPEG Comment marker
static const byte sof0_; //!< JPEG Start-Of-Frame marker static const byte sof0_; //!< JPEG Start-Of-Frame marker

@ -181,6 +181,7 @@ namespace Exiv2 {
clearXmpPacket(); clearXmpPacket();
clearXmpData(); clearXmpData();
clearComment(); clearComment();
clearIccProfile();
} }
ExifData& Image::exifData() ExifData& Image::exifData()
@ -283,6 +284,16 @@ namespace Exiv2 {
comment_ = comment; comment_ = comment;
} }
void Image::setIccProfile(Exiv2::DataBuf& iccProfile)
{
iccProfile_ = iccProfile;
}
void Image::clearIccProfile()
{
iccProfile_.release();
}
void Image::setByteOrder(ByteOrder byteOrder) void Image::setByteOrder(ByteOrder byteOrder)
{ {
byteOrder_ = byteOrder; byteOrder_ = byteOrder;

@ -67,6 +67,7 @@ namespace Exiv2 {
const byte JpegBase::eoi_ = 0xd9; const byte JpegBase::eoi_ = 0xd9;
const byte JpegBase::app0_ = 0xe0; const byte JpegBase::app0_ = 0xe0;
const byte JpegBase::app1_ = 0xe1; const byte JpegBase::app1_ = 0xe1;
const byte JpegBase::app2_ = 0xe2;
const byte JpegBase::app13_ = 0xed; const byte JpegBase::app13_ = 0xed;
const byte JpegBase::com_ = 0xfe; const byte JpegBase::com_ = 0xfe;
@ -351,6 +352,7 @@ namespace Exiv2 {
bool foundCompletePsData = false; bool foundCompletePsData = false;
bool foundExifData = false; bool foundExifData = false;
bool foundXmpData = false; bool foundXmpData = false;
bool foundIccProfile = false;
// Read section marker // Read section marker
int marker = advanceToMarker(); int marker = advanceToMarker();
@ -449,6 +451,15 @@ namespace Exiv2 {
} }
--search; --search;
} }
else if ( !foundIccProfile && marker == app2_ ) {
// Seek to beginning and read the iccProfile
io_->seek(31 - bufRead, BasicIo::cur);
DataBuf iccProfile(size);
io_->read(iccProfile.pData_, iccProfile.size_);
if (io_->error() || io_->eof()) throw Error(14);
this->setIccProfile(iccProfile);
foundXmpData = true;
}
else if ( pixelHeight_ == 0 else if ( pixelHeight_ == 0
&& ( marker == sof0_ || marker == sof1_ || marker == sof2_ && ( marker == sof0_ || marker == sof1_ || marker == sof2_
|| marker == sof3_ || marker == sof5_ || marker == sof6_ || marker == sof3_ || marker == sof5_ || marker == sof6_
@ -799,6 +810,7 @@ namespace Exiv2 {
int comPos = 0; int comPos = 0;
int skipApp1Exif = -1; int skipApp1Exif = -1;
int skipApp1Xmp = -1; int skipApp1Xmp = -1;
int skipApp2IccProfile = -1;
bool foundCompletePsData = false; bool foundCompletePsData = false;
std::vector<int> skipApp13Ps3; std::vector<int> skipApp13Ps3;
int skipCom = -1; int skipCom = -1;
@ -844,6 +856,12 @@ namespace Exiv2 {
++search; ++search;
if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22); if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
} }
else if ( skipApp2IccProfile == -1 && marker == app2_) {
if (size < 31) throw Error(22);
skipApp2IccProfile = count;
++search;
if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(22);
}
else if ( !foundCompletePsData else if ( !foundCompletePsData
&& marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) { && marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
#ifdef DEBUG #ifdef DEBUG
@ -995,6 +1013,20 @@ namespace Exiv2 {
if (outIo.error()) throw Error(21); if (outIo.error()) throw Error(21);
--search; --search;
} }
if (iccProfile_.size_ > 0) {
// Write APP2 marker, size of APP2 field, and IccProfile
tmpBuf[0] = 0xff;
tmpBuf[1] = app2_;
if (iccProfile_.size_ > 0xffff) throw Error(37, "IccProfile");
us2Data(tmpBuf + 2, static_cast<uint16_t>(iccProfile_.size_), bigEndian);
if (outIo.write(tmpBuf, 4) != 4) throw Error(21);
// Write new iccProfile
if ( outIo.write(iccProfile_.pData_,iccProfile_.size_) != static_cast<long>(iccProfile_.size_) ) throw Error(21);
if ( outIo.error() ) throw Error(21);
--search;
}
if (foundCompletePsData || iptcData_.count() > 0) { if (foundCompletePsData || iptcData_.count() > 0) {
// Set the new IPTC IRB, keeps existing IRBs but removes the // Set the new IPTC IRB, keeps existing IRBs but removes the
// IPTC block if there is no new IPTC data to write // IPTC block if there is no new IPTC data to write

@ -258,7 +258,8 @@ namespace Exiv2 {
if( bDump ) { if( bDump ) {
DataBuf dataBuf; DataBuf dataBuf;
byte* data = new byte[dataOffset]; byte* data = new byte[dataOffset+1];
data[dataOffset]=0;
io_->read(data,dataOffset); io_->read(data,dataOffset);
io_->seek(restore, BasicIo::beg); io_->seek(restore, BasicIo::beg);
uint32_t name_l = (uint32_t) std::strlen((const char*)data)+1; // leading string length uint32_t name_l = (uint32_t) std::strlen((const char*)data)+1; // leading string length
@ -308,7 +309,7 @@ namespace Exiv2 {
IptcData::printStructure(out,dataBuf.pData_,dataBuf.size_,depth); IptcData::printStructure(out,dataBuf.pData_,dataBuf.size_,depth);
} }
} }
delete [] data; delete[] data;
} }
io_->seek(dataOffset + 4 , BasicIo::cur); io_->seek(dataOffset + 4 , BasicIo::cur);
if (io_->error()) throw Error(14); if (io_->error()) throw Error(14);

Loading…
Cancel
Save