|
|
|
@ -324,12 +324,14 @@ namespace Exiv2 {
|
|
|
|
|
int c = -1;
|
|
|
|
|
// Skips potential padding between markers
|
|
|
|
|
while ((c=io_->getb()) != 0xff) {
|
|
|
|
|
if (c == EOF) return -1;
|
|
|
|
|
if (c == EOF)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Markers can start with any number of 0xff
|
|
|
|
|
while ((c=io_->getb()) == 0xff) {
|
|
|
|
|
if (c == EOF) return -2;
|
|
|
|
|
if (c == EOF)
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
@ -562,10 +564,12 @@ namespace Exiv2 {
|
|
|
|
|
|
|
|
|
|
void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, int depth)
|
|
|
|
|
{
|
|
|
|
|
if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError());
|
|
|
|
|
if (io_->open() != 0)
|
|
|
|
|
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
|
|
|
|
|
// Ensure that this is the correct image type
|
|
|
|
|
if (!isThisType(*io_, false)) {
|
|
|
|
|
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
|
|
|
|
|
if (io_->error() || io_->eof())
|
|
|
|
|
throw Error(kerFailedToReadImageData);
|
|
|
|
|
throw Error(kerNotAJpeg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -573,7 +577,6 @@ namespace Exiv2 {
|
|
|
|
|
Exiv2::Uint32Vector iptcDataSegs;
|
|
|
|
|
|
|
|
|
|
if (bPrint || option == kpsXMP || option == kpsIccProfile || option == kpsIptcErase) {
|
|
|
|
|
|
|
|
|
|
// nmonic for markers
|
|
|
|
|
std::string nm[256];
|
|
|
|
|
nm[0xd8] = "SOI";
|
|
|
|
@ -599,11 +602,8 @@ namespace Exiv2 {
|
|
|
|
|
// which markers have a length field?
|
|
|
|
|
bool mHasLength[256];
|
|
|
|
|
for (int i = 0; i < 256; i++)
|
|
|
|
|
mHasLength[i]
|
|
|
|
|
= ( i >= sof0_ && i <= sof15_)
|
|
|
|
|
|| ( i >= app0_ && i <= (app0_ | 0x0F))
|
|
|
|
|
|| ( i == dht_ || i == dqt_ || i == dri_ || i == com_ || i == sos_ )
|
|
|
|
|
;
|
|
|
|
|
mHasLength[i] = (i >= sof0_ && i <= sof15_) || (i >= app0_ && i <= (app0_ | 0x0F)) ||
|
|
|
|
|
(i == dht_ || i == dqt_ || i == dri_ || i == com_ || i == sos_);
|
|
|
|
|
|
|
|
|
|
// Container for the signature
|
|
|
|
|
bool bExtXMP = false;
|
|
|
|
@ -613,7 +613,8 @@ namespace Exiv2 {
|
|
|
|
|
|
|
|
|
|
// Read section marker
|
|
|
|
|
int marker = advanceToMarker();
|
|
|
|
|
if (marker < 0) throw Error(kerNotAJpeg);
|
|
|
|
|
if (marker < 0)
|
|
|
|
|
throw Error(kerNotAJpeg);
|
|
|
|
|
|
|
|
|
|
bool done = false;
|
|
|
|
|
bool first = true;
|
|
|
|
@ -630,10 +631,13 @@ namespace Exiv2 {
|
|
|
|
|
// Read size and signature
|
|
|
|
|
std::memset(buf.pData_, 0x0, buf.size_);
|
|
|
|
|
bufRead = io_->read(buf.pData_, bufMinSize);
|
|
|
|
|
if (io_->error()) throw Error(kerFailedToReadImageData);
|
|
|
|
|
if (bufRead < 2) throw Error(kerNotAJpeg);
|
|
|
|
|
if (io_->error())
|
|
|
|
|
throw Error(kerFailedToReadImageData);
|
|
|
|
|
if (bufRead < 2)
|
|
|
|
|
throw Error(kerNotAJpeg);
|
|
|
|
|
uint16_t size = mHasLength[marker] ? getUShort(buf.pData_, bigEndian) : 0;
|
|
|
|
|
if ( bPrint && mHasLength[marker] ) out << Internal::stringFormat(" | %7d ", size);
|
|
|
|
|
if (bPrint && mHasLength[marker])
|
|
|
|
|
out << Internal::stringFormat(" | %7d ", size);
|
|
|
|
|
|
|
|
|
|
// print signature for APPn
|
|
|
|
|
if (marker >= app0_ && marker <= (app0_ | 0x0F)) {
|
|
|
|
@ -663,7 +667,8 @@ namespace Exiv2 {
|
|
|
|
|
// and dumping the XMP in a post read operation similar to kpsIptcErase
|
|
|
|
|
// for the moment, dumping 'on the fly' is working fine
|
|
|
|
|
if (!bExtXMP) {
|
|
|
|
|
while (xmp[start]) start++;
|
|
|
|
|
while (xmp[start])
|
|
|
|
|
start++;
|
|
|
|
|
start++;
|
|
|
|
|
if (::strstr((char*)xmp + start, "HasExtendedXMP")) {
|
|
|
|
|
start = size; // ignore this packet, we'll get on the next time around
|
|
|
|
@ -746,11 +751,14 @@ namespace Exiv2 {
|
|
|
|
|
if (bFlir) {
|
|
|
|
|
// FLIRFILEHEAD* pFFF = (FLIRFILEHEAD*) (exif+start) ;
|
|
|
|
|
while (start < max) {
|
|
|
|
|
if ( exif[start] == 'I' && exif[start+1] == 'I' ) break;
|
|
|
|
|
if ( exif[start] == 'M' && exif[start+1] == 'M' ) break;
|
|
|
|
|
if (exif[start] == 'I' && exif[start + 1] == 'I')
|
|
|
|
|
break;
|
|
|
|
|
if (exif[start] == 'M' && exif[start + 1] == 'M')
|
|
|
|
|
break;
|
|
|
|
|
start++;
|
|
|
|
|
}
|
|
|
|
|
if ( start < max ) std::cout << " FFF start = " << start << std::endl ;
|
|
|
|
|
if (start < max)
|
|
|
|
|
std::cout << " FFF start = " << start << std::endl;
|
|
|
|
|
// << " index = " << pFFF->dwIndexOff << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -759,7 +767,8 @@ namespace Exiv2 {
|
|
|
|
|
} else {
|
|
|
|
|
// create a copy on write memio object with the data, then print the structure
|
|
|
|
|
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(exif + start, size - start));
|
|
|
|
|
if ( start < max ) printTiffStructure(*p,out,option,depth);
|
|
|
|
|
if (start < max)
|
|
|
|
|
printTiffStructure(*p, out, option, depth);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// restore and clean up
|
|
|
|
@ -777,9 +786,11 @@ namespace Exiv2 {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Skip the segment if the size is known
|
|
|
|
|
if (io_->seek(size - bufRead, BasicIo::cur)) throw Error(kerFailedToReadImageData);
|
|
|
|
|
if (io_->seek(size - bufRead, BasicIo::cur))
|
|
|
|
|
throw Error(kerFailedToReadImageData);
|
|
|
|
|
|
|
|
|
|
if ( bLF ) out << std::endl;
|
|
|
|
|
if (bLF)
|
|
|
|
|
out << std::endl;
|
|
|
|
|
|
|
|
|
|
if (marker != sos_) {
|
|
|
|
|
// Read the beginning of the next segment
|
|
|
|
@ -787,7 +798,8 @@ namespace Exiv2 {
|
|
|
|
|
REPORT_MARKER;
|
|
|
|
|
}
|
|
|
|
|
done |= marker == eoi_ || marker == sos_;
|
|
|
|
|
if ( done && bPrint ) out << std::endl;
|
|
|
|
|
if (done && bPrint)
|
|
|
|
|
out << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (option == kpsIptcErase && iptcDataSegs.size()) {
|
|
|
|
@ -796,7 +808,10 @@ namespace Exiv2 {
|
|
|
|
|
uint32_t toggle = 0;
|
|
|
|
|
for (Uint32Vector_i i = iptcDataSegs.begin(); i != iptcDataSegs.end(); i++) {
|
|
|
|
|
std::cout << *i;
|
|
|
|
|
if ( toggle++ % 2 ) std::cout << std::endl; else std::cout << ' ' ;
|
|
|
|
|
if (toggle++ % 2)
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
else
|
|
|
|
|
std::cout << ' ';
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
uint32_t count = (uint32_t)iptcDataSegs.size();
|
|
|
|
@ -814,7 +829,8 @@ namespace Exiv2 {
|
|
|
|
|
}
|
|
|
|
|
pos[count + 1] = io_->size() - pos[count];
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
for ( uint64_t i = 0 ; i < count+2 ; i++ ) std::cout << pos[i] << " " ;
|
|
|
|
|
for (uint64_t i = 0; i < count + 2; i++)
|
|
|
|
|
std::cout << pos[i] << " ";
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
// $ dd bs=1 skip=$((0)) count=$((13164)) if=ETH0138028.jpg of=E1.jpg
|
|
|
|
@ -828,7 +844,8 @@ namespace Exiv2 {
|
|
|
|
|
assert(tempIo.get() != 0);
|
|
|
|
|
for (uint64_t i = 0; i < (count / 2) + 1; i++) {
|
|
|
|
|
uint64_t start = pos[2 * i] + 2; // step JPG 2 byte marker
|
|
|
|
|
if ( start == 2 ) start = 0 ; // read the file 2 byte SOI
|
|
|
|
|
if (start == 2)
|
|
|
|
|
start = 0; // read the file 2 byte SOI
|
|
|
|
|
long length = (long)(pos[2 * i + 1] - start);
|
|
|
|
|
if (length) {
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|