From f6c79a0d206e48ef9308577d1d8b3613f39a54a3 Mon Sep 17 00:00:00 2001 From: Robin Mills Date: Fri, 24 Apr 2015 19:51:45 +0000 Subject: [PATCH] #922. Work in progress on options -pS and -pX --- src/exiv2.1 | 10 +++++----- src/image.cpp | 1 + src/jpgimage.cpp | 39 +++++++++++++++++++++++++-------------- src/tiffimage.cpp | 40 +++++++++++++++++++++++++--------------- 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/exiv2.1 b/src/exiv2.1 index d1f23b18..562f4b51 100644 --- a/src/exiv2.1 +++ b/src/exiv2.1 @@ -3,7 +3,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH EXIV2 1 "Apr 21, 2015" +.TH EXIV2 1 "Apr 24, 2015" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -170,7 +170,7 @@ fmt Default format is %Y%m%d_%H%M%S. lvl d | i | i | w | e debug, info, warning, error -mod s | a | t | v | h | i | x | c | p | i | S | X : +mod s | a | t | v | h | i | x | c | p | i | S | X : summary, add, translated, vanilla, hex ... iptc ,xmp, comment, preview, Structure,XMP raw @@ -305,9 +305,9 @@ c : JPEG comment .br p : list available image previews, sorted by preview image size in pixels .br -S : print image structure information (jpg and png only) +S : print image structure information (jpg, png and tiff only) .br -X : print "raw" XMP (jpg and png only) +X : print "raw" XMP (jpg, png and tiff only) .TP .B \-P \fIflgs\fP Print flags for fine control of the tag list ('print' action). Allows @@ -374,7 +374,7 @@ into the file. .br This is option is intended for "filter" operations on the XMP such as: .br -$ exiv2 -e{tgt}- \fIfilename\fP | xmllint .... | exiv2 -i{tgt}- \fIfilename\fP +$ exiv2 -e{tgt}- \fIfilename\fP | xmllint .... | exiv2 -i{tgt}- \fIfilename\fP .sp 1 Only JPEG thumbnails can be inserted (not TIFF thumbnails), they need to be named \fIfile\fP\-thumb.jpg. diff --git a/src/image.cpp b/src/image.cpp index 47f75081..bead82b9 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -164,6 +164,7 @@ namespace Exiv2 { } void Image::printStructure(std::ostream&, printStructureOption_e) { + throw Error(13, io_->path()); } void Image::clearMetadata() diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp index f4ea25e0..4fe3741a 100644 --- a/src/jpgimage.cpp +++ b/src/jpgimage.cpp @@ -515,6 +515,8 @@ namespace Exiv2 { return true ; } +#define REPORT_MARKER if ( option == kpsBasic ) { sprintf(sbuff,"%8ld | %#02x %-5s",io_->tell(), marker,nm[marker].c_str()); out << sbuff; } + void JpegBase::printStructure(std::ostream& out,printStructureOption_e option) { if (io_->open() != 0) throw Error(9, io_->path(), strError()); @@ -560,13 +562,16 @@ namespace Exiv2 { int marker = advanceToMarker(); if (marker < 0) throw Error(15); - if ( option == kpsBasic ) out << " offset | marker | length | signature" << std::endl ; - - while (1) { + bool done = false; + bool first= true; + while (!done) { // print marker bytes - sprintf(sbuff,"%8ld %#02x %-5s",io_->tell(), marker,nm[marker].c_str()); - if ( option == kpsBasic ) out << sbuff; - if ( marker == eoi_ ) break ; + if ( first && option == kpsBasic ) { + out << "STRUCTURE OF JPEG FILE: " << io_->path() << std::endl; + out << " address | marker | length | signature" << std::endl ; + REPORT_MARKER; + } + first = false; // Read size and signature std::memset(buf.pData_, 0x0, buf.size_); @@ -586,9 +591,7 @@ namespace Exiv2 { || marker == sos_ ){ size = getUShort(buf.pData_, bigEndian); - sprintf(sbuff,"%7d ", size); - } else { - sprintf(sbuff," "); + sprintf(sbuff," | %7d ", size); } if ( option == kpsBasic ) out << sbuff ; @@ -650,6 +653,7 @@ namespace Exiv2 { startSig = size>0?2:0; int endSig = size?size:bufRead; if (endSig > 32) endSig = 32 ; + out << "| "; while (startSig++ < endSig ) { byte c = buf.pData_[startSig-1] ; c = (' '<=c && c<128) ? c : '.' ; @@ -659,16 +663,23 @@ namespace Exiv2 { } } - // Skip the segment if the size is known if (io_->seek(size - bufRead, BasicIo::cur)) throw Error(14); if ( option == kpsBasic ) out << std::endl; - // sos_ is immediately followed by entropy-coded data & eoi_ - if (marker == sos_) break; - // Read the beginning of the next segment - marker = advanceToMarker(); + if (marker == sos_) + // sos_ is immediately followed by entropy-coded data & eoi_ + done = true; + else { + // Read the beginning of the next segment + marker = advanceToMarker(); + REPORT_MARKER; + if ( marker == eoi_ ) { + if ( option == kpsBasic ) out << std::endl; + done = true; + } + } } } } diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp index 0c3c962d..08f8c79a 100644 --- a/src/tiffimage.cpp +++ b/src/tiffimage.cpp @@ -303,34 +303,42 @@ namespace Exiv2 { } // http://en.wikipedia.org/wiki/Endianness - static uint32_t byteSwap(uint32_t* pValue,bool b) + static uint32_t byteSwap(uint32_t value,bool bSwap) { uint32_t result = 0; - uint32_t value = *pValue ; result |= (value & 0x000000FF) << 24; result |= (value & 0x0000FF00) << 8; result |= (value & 0x00FF0000) >> 8; result |= (value & 0xFF000000) >> 24; - return b ? result : value; + return bSwap ? result : value; } - static uint16_t byteSwap(uint16_t* pValue,bool b) + static uint16_t byteSwap(uint16_t value,bool bSwap) { uint16_t result = 0; - uint16_t value = *pValue ; result |= (value & 0x00FF) << 8; result |= (value & 0xFF00) >> 8; - return b ? result : value; + return bSwap ? result : value; } static uint16_t byteSwap2(DataBuf& buf,size_t offset,bool bSwap) { - return byteSwap((uint16_t*)&buf.pData_[offset],bSwap); + uint16_t v; + char* p = (char*) &v; + p[0] = buf.pData_[offset]; + p[1] = buf.pData_[offset+1]; + return byteSwap(v,bSwap); } static uint32_t byteSwap4(DataBuf& buf,size_t offset,bool bSwap) { - return byteSwap((uint32_t*)&buf.pData_[offset],bSwap); + uint32_t v; + char* p = (char*) &v; + p[0] = buf.pData_[offset]; + p[1] = buf.pData_[offset+1]; + p[2] = buf.pData_[offset+2]; + p[3] = buf.pData_[offset+3]; + return byteSwap(v,bSwap); } // http://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf @@ -356,14 +364,15 @@ namespace Exiv2 { { std::string result = ""; size_t start = 0 ; - if (size > 32) size = 32 ; + bool bLong = size > 32; + if ( bLong ) size = 32 ; while (start < size ) { int c = (int) buff[start++] ; if (c < ' ' || c > 127) c = '.' ; result += (char) c ; } - return result; + return result + (bLong ? " ..." : "") ; } std::string rationalValue(byte* buff,size_t size) @@ -512,8 +521,8 @@ namespace Exiv2 { #endif if ( option == kpsBasic ) { // out << string_format("count = %u\n",count); - out << "STRUCTURE OF TIFF FILE:\n"; - out << " tag | type | count | offset | value\n"; + out << "STRUCTURE OF TIFF FILE: " << io_->path() << std::endl; + out << " address | tag | type | count | offset | value\n"; } uint32_t offset = byteSwap4(buf,4,bSwap); @@ -533,14 +542,15 @@ namespace Exiv2 { uint32_t Count = byteSwap4(buf,4,bSwap); uint32_t Offset = byteSwap4(buf,8,bSwap); if ( option == kpsBasic ) { - out << stringFormat("%#06x %-20s |%10s |%9u |%9u | ",Tag,tagName(Tag),typeName(Type),Count,Offset); - if ( Count > 4 && isStringType(Type) ) { // 4 byte or ascii + uint32_t address = offset + 2 + i*12 ; + out << stringFormat("%8u | %#06x %-20s |%10s |%9u |%9u | ",address,Tag,tagName(Tag),typeName(Type),Count,Offset); + if ( isStringType(Type) ) { size_t restore = io_->tell(); io_->seek(Offset,BasicIo::beg); size_t size = Count > bufSize ? bufSize : Count; io_->read(buf.pData_,size ); io_->seek(restore,BasicIo::beg); - out << stringValue(buf.pData_,size); + out << stringValue(buf.pData_,Count); } else if ( Count == 1 && Type == Exiv2::unsignedShort ) { out << byteSwap2(buf,8,bSwap); } else if ( Count == 1 && Type == Exiv2::unsignedLong ) {