#1243 Work-in-progress on writing ICC profiles. Fixed elusive issue in exiv2 -pS foo.jp2

v0.27.3
Robin Mills 9 years ago
parent 05f56e95af
commit 163f3ce7f1

@ -115,6 +115,14 @@ namespace Exiv2
@return 4 if opening or writing to the associated BasicIo fails
*/
EXV_DLLLOCAL void doWriteMetadata(BasicIo& oIo);
/*!
@brief reformats the Jp2Header to store iccProfile
@param oldData DataBufRef to data in the file.
@param newData DataBufRef with updated data
@return length of box (including the 8 bytes of the box)
*/
uint32_t encodeJp2Header(const DataBuf& oldData,DataBuf& newData);
//@}
}; // class Jp2Image

@ -485,25 +485,32 @@ namespace Exiv2
{
lf(out,bLF);
while (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox))
while (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox)
&& io_->tell() < position + box.length) // don't read beyond the box!
{
subBox.length = getLong((byte*)&subBox.length, bigEndian);
subBox.type = getLong((byte*)&subBox.type, bigEndian);
if (subBox.type == kJp2BoxTypeClose || subBox.length < sizeof(box)) break ;
DataBuf data(subBox.length-sizeof(box));
io_->read(data.pData_,data.size_);
if ( bPrint ) {
out << Internal::stringFormat("%8ld | %8ld | sub:",io_->tell()-sizeof(box),subBox.length) << toAscii(subBox.type)
<<" | " << Internal::binaryToString(data,40,0);
<<" | " << Internal::binaryToString(data,30,0);
bLF = true;
}
if(subBox.type == kJp2BoxTypeColorHeader)
{
long pad = 3 ; // don't know why there are 3 padding bytes
if ( bPrint ) {
out << " | pad:" ;
for ( int i = 0 ; i < 3 ; i++ ) out<< " " << (int) data.pData_[i];
}
long iccLength = getULong(data.pData_+pad, bigEndian);
if ( bPrint ) {
out << " | iccLength:" << iccLength ;
}
DataBuf icc(iccLength);
if ( bICC ) out.write((const char*)icc.pData_,icc.size_);
}
@ -589,6 +596,35 @@ namespace Exiv2
} // Jp2Image::writeMetadata
uint32_t Jp2Image::encodeJp2Header(const DataBuf& boxBuf,DataBuf& newBuf)
{
long result = boxBuf.size_;
newBuf.alloc(boxBuf.size_);
::memcpy(newBuf.pData_,boxBuf.pData_,boxBuf.size_);
#ifdef DEBUG
Jp2BoxHeader& box= (Jp2BoxHeader&) *(Jp2BoxHeader*) boxBuf.pData_;
int32_t length = getLong((byte*)&box.length, bigEndian);
uint32_t count = sizeof (Jp2BoxHeader);
char* p = (char*) boxBuf.pData_+sizeof(Jp2BoxHeader);
bool done = false;
while ( !done ) {
Jp2BoxHeader& subBox = (Jp2BoxHeader&) *((Jp2BoxHeader*)p) ;
subBox.length = getLong((byte*)&subBox.length, bigEndian);
subBox.type = getLong((byte*)&subBox.type, bigEndian);
done = subBox.length < sizeof(subBox) || subBox.type == kJp2BoxTypeClose || count >= length;
if ( !done ) {
std::cout << "subbox: "<< toAscii(subBox.type) << " length = " << subBox.length << std::endl;
p += subBox.length ;
count += subBox.length;
}
}
#endif
return (uint32_t) result ;
}
void Jp2Image::doWriteMetadata(BasicIo& outIo)
{
if (!io_->isopen()) throw Error(20);
@ -680,11 +716,12 @@ namespace Exiv2
{
case kJp2BoxTypeJp2Header:
{
DataBuf newBuf ;
encodeJp2Header(boxBuf,newBuf);
#ifdef DEBUG
std::cout << "Exiv2::Jp2Image::doWriteMetadata: Write JP2Header box (length: " << box.length << ")" << std::endl;
#endif
if (outIo.write(boxBuf.pData_, boxBuf.size_) != boxBuf.size_) throw Error(21);
if (outIo.write(newBuf.pData_, newBuf.size_) != newBuf.size_) throw Error(21);
// Write all updated metadata here, just after JP2Header.

Loading…
Cancel
Save