#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.
*/
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
copied into internal buffers and is not written to the image
@ -422,6 +433,7 @@ namespace Exiv2 {
ExifData exifData_; //!< Exif data container
IptcData iptcData_; //!< IPTC data container
XmpData xmpData_; //!< XMP data container
DataBuf iccProfile_; //!< ICC buffer (binary data)
std::string comment_; //!< User comment
std::string xmpPacket_; //!< XMP packet
int pixelWidth_; //!< image pixel width

@ -233,6 +233,7 @@ namespace Exiv2 {
static const byte eoi_; //!< JPEG EOI marker
static const byte app0_; //!< JPEG APP0 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 com_; //!< JPEG Comment marker
static const byte sof0_; //!< JPEG Start-Of-Frame marker

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

@ -67,6 +67,7 @@ namespace Exiv2 {
const byte JpegBase::eoi_ = 0xd9;
const byte JpegBase::app0_ = 0xe0;
const byte JpegBase::app1_ = 0xe1;
const byte JpegBase::app2_ = 0xe2;
const byte JpegBase::app13_ = 0xed;
const byte JpegBase::com_ = 0xfe;
@ -351,6 +352,7 @@ namespace Exiv2 {
bool foundCompletePsData = false;
bool foundExifData = false;
bool foundXmpData = false;
bool foundIccProfile = false;
// Read section marker
int marker = advanceToMarker();
@ -449,6 +451,15 @@ namespace Exiv2 {
}
--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
&& ( marker == sof0_ || marker == sof1_ || marker == sof2_
|| marker == sof3_ || marker == sof5_ || marker == sof6_
@ -799,6 +810,7 @@ namespace Exiv2 {
int comPos = 0;
int skipApp1Exif = -1;
int skipApp1Xmp = -1;
int skipApp2IccProfile = -1;
bool foundCompletePsData = false;
std::vector<int> skipApp13Ps3;
int skipCom = -1;
@ -844,6 +856,12 @@ namespace Exiv2 {
++search;
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
&& marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
#ifdef DEBUG
@ -995,6 +1013,20 @@ namespace Exiv2 {
if (outIo.error()) throw Error(21);
--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) {
// Set the new IPTC IRB, keeps existing IRBs but removes the
// IPTC block if there is no new IPTC data to write

@ -258,7 +258,8 @@ namespace Exiv2 {
if( bDump ) {
DataBuf dataBuf;
byte* data = new byte[dataOffset];
byte* data = new byte[dataOffset+1];
data[dataOffset]=0;
io_->read(data,dataOffset);
io_->seek(restore, BasicIo::beg);
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);
}
}
delete [] data;
delete[] data;
}
io_->seek(dataOffset + 4 , BasicIo::cur);
if (io_->error()) throw Error(14);

Loading…
Cancel
Save