[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:44:58 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=6c11387

The following commit has been merged in the master branch:
commit 6c113871efacdb4760a0cac1c7cafa8677f53ed1
Author: Robin Mills <robin at clanmills.com>
Date:   Fri Mar 27 18:47:52 2015 +0000

    #922.  Added options -pS and -pX to exiv2(.exe).   Still to deal with -dI
---
 include/exiv2/actions.hpp  |   2 +
 include/exiv2/image.hpp    |  11 ++-
 include/exiv2/jpgimage.hpp |   2 +-
 include/exiv2/pngimage.hpp |   2 +-
 src/actions.cpp            |  23 +++++-
 src/exiv2.1                |   6 +-
 src/exiv2.cpp              |   8 +-
 src/exiv2app.hpp           |   4 +-
 src/image.cpp              |   8 +-
 src/jpgimage.cpp           | 186 ++++++++++++++++++++++++++-------------------
 src/pngimage.cpp           |  89 ++++++++++++++++------
 11 files changed, 221 insertions(+), 120 deletions(-)

diff --git a/include/exiv2/actions.hpp b/include/exiv2/actions.hpp
index a4ba1df..804e86a 100644
--- a/include/exiv2/actions.hpp
+++ b/include/exiv2/actions.hpp
@@ -178,6 +178,8 @@ namespace Action {
         void printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* image);
         //! Print the label for a summary line
         void printLabel(const std::string& label) const;
+        //! Print image Structure information
+        int printStructure(std::ostream& out,Exiv2::printStructureOption_e option);
         /*!
           @brief Print one summary line with a label (if provided) and requested
                  data. A line break is printed only if a label is provided.
diff --git a/include/exiv2/image.hpp b/include/exiv2/image.hpp
index c824b6e..9659694 100644
--- a/include/exiv2/image.hpp
+++ b/include/exiv2/image.hpp
@@ -72,6 +72,11 @@ namespace Exiv2 {
     typedef std::vector<NativePreview> NativePreviewList;
 
     /*!
+      @brief options for printStructure
+     */
+    typedef enum { kpsNone, kpsBasic, kpsXMP } printStructureOption_e ;
+
+    /*!
       @brief Abstract base class defining the interface for an image. This is
          the top-level interface to the Exiv2 library.
 
@@ -107,7 +112,7 @@ namespace Exiv2 {
           @throw Error if reading of the file fails or the image data is
                 not valid (does not look like data of the specific image type).
          */
-        virtual void printStructure();
+        virtual void printStructure(std::ostream& out,printStructureOption_e option=kpsNone);
         /*!
           @brief Read all metadata supported by a specific image format from the
               image. Before this method is called, the image metadata will be
@@ -450,7 +455,7 @@ namespace Exiv2 {
     class EXIV2API ImageFactory {
         friend bool Image::good() const;
     public:
-		/*!
+        /*!
           @brief Create the appropriate class type implemented BasicIo based on the protocol of the input.
 
           "-" path implies the data from stdin and it is handled by StdinIo.
@@ -466,7 +471,7 @@ namespace Exiv2 {
          */
         static BasicIo::AutoPtr createIo(const std::string& path, bool useCurl = true);
 #ifdef EXV_UNICODE_PATH
-		/*!
+        /*!
           @brief Like createIo() but accepts a unicode path in an std::wstring.
           @note This function is only available on Windows.
          */
diff --git a/include/exiv2/jpgimage.hpp b/include/exiv2/jpgimage.hpp
index 5be3c38..c0a6159 100644
--- a/include/exiv2/jpgimage.hpp
+++ b/include/exiv2/jpgimage.hpp
@@ -150,7 +150,7 @@ namespace Exiv2 {
     public:
         //! @name Manipulators
         //@{
-        void printStructure();
+        void printStructure(std::ostream& out,printStructureOption_e option);
         void readMetadata();
         void writeMetadata();
         //@}
diff --git a/include/exiv2/pngimage.hpp b/include/exiv2/pngimage.hpp
index 6bfd037..fc0339b 100644
--- a/include/exiv2/pngimage.hpp
+++ b/include/exiv2/pngimage.hpp
@@ -84,7 +84,7 @@ namespace Exiv2
 
         //! @name Manipulators
         //@{
-        void printStructure();
+        void printStructure(std::ostream& out,printStructureOption_e option);
         void readMetadata();
         void writeMetadata();
         //@}
diff --git a/src/actions.cpp b/src/actions.cpp
index 95ed65e..129ef5d 100644
--- a/src/actions.cpp
+++ b/src/actions.cpp
@@ -237,10 +237,12 @@ namespace Action {
         path_ = path;
         int rc = 0;
         switch (Params::instance().printMode_) {
-        case Params::pmSummary: rc = printSummary();     break;
-        case Params::pmList:    rc = printList();        break;
-        case Params::pmComment: rc = printComment();     break;
-        case Params::pmPreview: rc = printPreviewList(); break;
+        case Params::pmSummary:   rc = printSummary();     break;
+        case Params::pmList:      rc = printList();        break;
+        case Params::pmComment:   rc = printComment();     break;
+        case Params::pmPreview:   rc = printPreviewList(); break;
+        case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic); break;
+        case Params::pmXMP:       rc = printStructure(std::cout,Exiv2::kpsXMP);   break;
         }
         return rc;
     }
@@ -250,6 +252,19 @@ namespace Action {
         return 1;
     } // Print::run
 
+    int Print::printStructure(std::ostream& out,Exiv2::printStructureOption_e option)
+    {
+        if (!Exiv2::fileExists(path_, true)) {
+            std::cerr << path_ << ": "
+                      << _("Failed to open the file
");
+            return -1;
+        }
+        Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_);
+        assert(image.get() != 0);
+        image->printStructure(out,option);
+        return 0;
+    }
+
     int Print::printSummary()
     {
         if (!Exiv2::fileExists(path_, true)) {
diff --git a/src/exiv2.1 b/src/exiv2.1
index c421270..993da89 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 "Mar 11, 2015"
+.TH EXIV2 1 "Mar 27, 2015"
 .\" Please adjust this date whenever revising the manpage.
 .\"
 .\" Some roff macros, for reference:
@@ -231,6 +231,10 @@ x : XMP properties (\-PXkyct)
 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)
+.br
+X : print "raw" XMP (jpg and png only)
 .TP
 .B \-P 
Iflgs
P
 Print flags for fine control of the tag list ('print' action). Allows
diff --git a/src/exiv2.cpp b/src/exiv2.cpp
index 6ac6662..9fe5e18 100644
--- a/src/exiv2.cpp
+++ b/src/exiv2.cpp
@@ -296,6 +296,8 @@ void Params::help(std::ostream& os) const
        << _("             x : XMP properties (-PXkyct)
")
        << _("             c : JPEG comment
")
        << _("             p : list available previews
")
+       << _("             S : print structure of image
")
+       << _("             X : extract XMP from image
")
        << _("   -P flgs Print flags for fine control of tag lists ('print' action):
")
        << _("             E : include Exif tags in the list
")
        << _("             I : IPTC datasets
")
@@ -555,8 +557,10 @@ int Params::evalPrint(const std::string& optarg)
         case 'h': rc = evalPrintFlags("Exgnycsh"); break;
         case 'i': rc = evalPrintFlags("Ikyct"); break;
         case 'x': rc = evalPrintFlags("Xkyct"); break;
-        case 'c': action_ = Action::print; printMode_ = pmComment; break;
-        case 'p': action_ = Action::print; printMode_ = pmPreview; break;
+        case 'c': action_ = Action::print; printMode_ = pmComment  ; break;
+        case 'p': action_ = Action::print; printMode_ = pmPreview  ; break;
+        case 'S': action_ = Action::print; printMode_ = pmStructure; break;
+        case 'X': action_ = Action::print; printMode_ = pmXMP      ; break;
         default:
             std::cerr << progname() << ": " << _("Unrecognized print mode") << " `"
                       << optarg << "'
";
diff --git a/src/exiv2app.hpp b/src/exiv2app.hpp
index 5cd3b1a..6674624 100644
--- a/src/exiv2app.hpp
+++ b/src/exiv2app.hpp
@@ -144,7 +144,9 @@ public:
         pmSummary,
         pmList,
         pmComment,
-        pmPreview
+        pmPreview,
+		pmStructure,
+		pmXMP
     };
 
     //! Individual items to print, bitmap
diff --git a/src/image.cpp b/src/image.cpp
index d13b8ec..47f7508 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -68,6 +68,8 @@ EXIV2_RCSID("@(#) $Id$")
 #include <cstdio>
 #include <cstring>
 #include <cassert>
+#include <iostream>
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #ifdef _MSC_VER
@@ -160,7 +162,7 @@ namespace Exiv2 {
     Image::~Image()
     {
     }
-    void Image::printStructure()
+    void Image::printStructure(std::ostream&, printStructureOption_e)
     {
     }
 
@@ -435,13 +437,13 @@ namespace Exiv2 {
             return BasicIo::AutoPtr(new XPathIo(path)); // may throw
 
         return BasicIo::AutoPtr(new FileIo(path));
-        
+
         UNUSED(useCurl);
     } // ImageFactory::createIo
 
 #ifdef EXV_UNICODE_PATH
     BasicIo::AutoPtr ImageFactory::createIo(const std::wstring& wpath, bool useCurl)
-	{
+    {
         Protocol fProt = fileProtocol(wpath);
 #if EXV_USE_SSH == 1
         if (fProt == pSsh || fProt == pSftp) {
diff --git a/src/jpgimage.cpp b/src/jpgimage.cpp
index f7b997c..802c0a6 100644
--- a/src/jpgimage.cpp
+++ b/src/jpgimage.cpp
@@ -507,7 +507,7 @@ namespace Exiv2 {
         }
     } // JpegBase::readMetadata
 
-    void JpegBase::printStructure()
+    void JpegBase::printStructure(std::ostream& out,printStructureOption_e option)
     {
         if (io_->open() != 0) throw Error(9, io_->path(), strError());
         // Ensure that this is the correct image type
@@ -515,90 +515,116 @@ namespace Exiv2 {
             if (io_->error() || io_->eof()) throw Error(14);
             throw Error(15);
         }
-        
-        // nemonic for markers
-        std::string nm[256] ;
-        nm[0xd8]="SOI"  ;
-        nm[0xd9]="EOI"  ;
-        nm[0xda]="SOS"  ;
-        nm[0xdb]="DQT"  ;
-        nm[0xdd]="DRI"  ;
-        nm[0xfe]="COM"  ;
-        
-        // 0xe0 .. 0xef are APPn
-        // 0xc0 .. 0xcf are SOFn (except 4)
-        nm[0xc4]="DHT"  ;
-        for ( int i = 0 ; i <= 15 ; i++ ) {
-        	char MN[10];
-        	sprintf(MN,"APP%d",i);
-            nm[0xe0+i] = MN;
-            if ( i != 4 ) {
-                sprintf(MN,"SOF%d",i);
-                nm[0xc0+i] = MN;
+
+        if ( option == kpsBasic || option == kpsXMP ) {
+            char sbuff[80];
+
+            // nemonic for markers
+            std::string nm[256] ;
+            nm[0xd8]="SOI"  ;
+            nm[0xd9]="EOI"  ;
+            nm[0xda]="SOS"  ;
+            nm[0xdb]="DQT"  ;
+            nm[0xdd]="DRI"  ;
+            nm[0xfe]="COM"  ;
+
+            // 0xe0 .. 0xef are APPn
+            // 0xc0 .. 0xcf are SOFn (except 4)
+            nm[0xc4]="DHT"  ;
+            for ( int i = 0 ; i <= 15 ; i++ ) {
+                char MN[10];
+                sprintf(MN,"APP%d",i);
+                nm[0xe0+i] = MN;
+                if ( i != 4 ) {
+                    sprintf(MN,"SOF%d",i);
+                    nm[0xc0+i] = MN;
+                }
             }
-        }
 
-        // Container for the signature
-        const long bufMinSize = 36;
-        long bufRead = 0, startSig = 0;
-        DataBuf buf(bufMinSize);
+            // Container for the signature
+            const long bufMinSize = 36;
+            long bufRead = 0, startSig = 0;
+            DataBuf buf(bufMinSize);
+
+            // Read section marker
+            int marker = advanceToMarker();
+            if (marker < 0) throw Error(15);
+
+            if ( option == kpsBasic ) out << "  offset | marker   | length | signature" << std::endl ;
+
+            while (1) {
+                // print marker bytes
+                sprintf(sbuff,"%8ld   %#02x %-5s",io_->tell(), marker,nm[marker].c_str());
+                if ( option == kpsBasic ) out << sbuff;
+                if ( marker == eoi_ ) break ;
+
+                // Read size and signature
+                std::memset(buf.pData_, 0x0, buf.size_);
+                bufRead = io_->read(buf.pData_, bufMinSize);
+                if (io_->error()) throw Error(14);
+                if (bufRead < 2) throw Error(15);
+                uint16_t size = 0;
+                sbuff[0]=0;
+
+                // not all markers have size field.
+                if( ( marker >= sof0_ && marker <= sof15_)
+                ||  ( marker >= app0_ && marker <= (app0_ | 0x0F))
+                ||    marker == dht_
+                ||    marker == dqt_
+                ||    marker == dri_
+                ||    marker == com_
+                ||    marker == sos_
+                ){
+                    size = getUShort(buf.pData_, bigEndian);
+                    sprintf(sbuff,"%7d   ", size);
+                } else {
+                    sprintf(sbuff,"        ");
+                }
+                if ( option == kpsBasic ) out << sbuff ;
+
+                // only print the signature for appn
+                if (marker >= app0_ && marker <= (app0_ | 0x0F)) {
+                    char http[5];
+                    http[4]=0;
+                    memcpy(http,buf.pData_+2,4);
+                    if ( option == kpsXMP && strncmp(http,"http",4) == 0 ) {
+                        // http://ns.adobe.com/xap/1.0/
+                        if ( size > 0 ) {
+                            io_->seek(-bufRead , BasicIo::cur);
+                            byte* xmp  = new byte[size+1];
+                            io_->read(xmp,size);
+                            int start = 0 ;
+                            while (xmp[start]) start++; start++;
+                            xmp[size]=0;
+                            out << xmp + start << std::endl;
+                            delete [] xmp;
+                            bufRead = size;
+                        }
+                    } else if ( option == kpsBasic ) {
+                        startSig = size>0?2:0;
+                        int endSig = size?size:bufRead;
+                        if (endSig > 32) endSig = 32 ;
+                        while (startSig++ < endSig ) {
+                            byte c = buf.pData_[startSig-1] ;
+                            c      = (' '<=c && c<128) ? c : '.' ;
+                            out << (char) c ;
+                            // else     endSig = startSig;
+                        }
+                    }
+                }
 
-        // Read section marker
-        int marker = advanceToMarker();
-        if (marker < 0) throw Error(15);
 
-        printf("STRUCTURE OF FILE:
");
-        printf("  offset | marker     | size | signature
");
-        while (1) {
-            // print marker bytes
-            printf("%8ld   %#02x %-5s",io_->tell(), marker,nm[marker].c_str());
-            if ( marker == eoi_ ) break ;
-
-			// Read size and signature
-			std::memset(buf.pData_, 0x0, buf.size_);
-			bufRead = io_->read(buf.pData_, bufMinSize);
-			if (io_->error()) throw Error(14);
-			if (bufRead < 2) throw Error(15);
-			uint16_t size = 0;
-
-			// not all markers have size field.
-			if( ( marker >= sof0_ && marker <= sof15_)
-			||  ( marker >= app0_ && marker <= (app0_ | 0x0F))
-			||    marker == dht_
-			||    marker == dqt_
-			||    marker == dri_
-			||    marker == com_
-			||    marker == sos_
-			){
-				size = getUShort(buf.pData_, bigEndian);
-				printf("%7d   ", size);
-			} else {
-				printf("        ");
-			}
-
-			// only print the signature for appn
-			if (marker >= app0_ && marker <= (app0_ | 0x0F)) {
-				startSig = size>0?2:0;
-				int endSig = size?size:bufRead;
-				if (endSig > 32) endSig = 32 ;
-				while (startSig++ < endSig ) {
-					int c = buf.pData_[startSig-1] ;
-					printf("%c", (' '<=c && c<128) ? c : '.' );
-					// else     endSig = startSig;
-				}
-			}
-
-			// Skip the segment if the size is known
-			if (io_->seek(size - bufRead, BasicIo::cur)) throw Error(14);
-
-			printf("
");
-			// sos_ is immediately followed by entropy-coded data & eoi_
-			if (marker == sos_) break;
-
-			// Read the beginning of the next segment
-			marker = advanceToMarker();
+                // 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();
+            }
         }
-        printf("-----------------
");
     }
 
     void JpegBase::writeMetadata()
diff --git a/src/pngimage.cpp b/src/pngimage.cpp
index ef57991..5c05f86 100644
--- a/src/pngimage.cpp
+++ b/src/pngimage.cpp
@@ -91,7 +91,7 @@ namespace Exiv2 {
         return "image/png";
     }
 
-    void PngImage::printStructure()
+    void PngImage::printStructure(std::ostream& out,printStructureOption_e option)
     {
         if (io_->open() != 0) {
             throw Error(9, io_->path(), strError());
@@ -103,34 +103,75 @@ namespace Exiv2 {
             throw Error(3, "PNG");
         }
 
-        printf("index   |  chunk_type  | chunk_size
");
-        long index = 0, i = 0;
-        const long imgSize = io_->size();
-        DataBuf cheaderBuf(8);
+        char    chType[5];
+        chType[0]=0;
+        chType[4]=0;
 
-        while(!io_->eof()) {
-            std::memset(cheaderBuf.pData_, 0x0, cheaderBuf.size_);
-            long bufRead = io_->read(cheaderBuf.pData_, cheaderBuf.size_);
-            if (io_->error()) throw Error(14);
-            if (bufRead != cheaderBuf.size_) throw Error(20);
+        if ( option == kpsBasic || option == kpsXMP ) {
 
-            // Decode chunk data length.
-            uint32_t dataOffset = Exiv2::getULong(cheaderBuf.pData_, Exiv2::bigEndian);
-            long pos = io_->tell();
-            if (   pos == -1
-                || dataOffset > uint32_t(0x7FFFFFFF)
-                || static_cast<long>(dataOffset) > imgSize - pos) throw Exiv2::Error(14);
+            if ( option == kpsBasic ) out << "index | chunk_type | length | data" << std::endl;
 
-            printf("%5ld       ", index);
-            for (i = 4; i < 8; i++)
-                printf("%c", cheaderBuf.pData_[i]);
-            printf("          %u
", dataOffset);
+            long       index   = 0;
+            const long imgSize = io_->size();
+            DataBuf    cheaderBuf(8);
 
-            index++;
-            io_->seek(dataOffset + 4 , BasicIo::cur);
-            if (io_->error() || io_->eof()) throw Error(14);
-        }
+            while( !io_->eof() && ::strcmp(chType,"IEND") ) {
+                std::memset(cheaderBuf.pData_, 0x0, cheaderBuf.size_);
+                long bufRead = io_->read(cheaderBuf.pData_, cheaderBuf.size_);
+                if (io_->error()) throw Error(14);
+                if (bufRead != cheaderBuf.size_) throw Error(20);
+
+                // Decode chunk data length.
+                uint32_t dataOffset = Exiv2::getULong(cheaderBuf.pData_, Exiv2::bigEndian);
+                long pos = io_->tell();
+                if (   pos == -1
+                    || dataOffset > uint32_t(0x7FFFFFFF)
+                    || static_cast<long>(dataOffset) > imgSize - pos) throw Exiv2::Error(14);
+
+                for (int i = 4; i < 8; i++) {
+                    chType[i-4]=cheaderBuf.pData_[i];
+                }
+
+                byte   buff[32];
+                size_t blen  = sizeof(buff)-1;
+                buff  [blen] = 0;
+                buff  [   0] = 0;
+
+                size_t     dOff = dataOffset;
+
+                if ( dataOffset > blen ) {
+                    io_->read(buff,blen);
+                    dataOffset -=  blen ;
+                    for ( size_t i = 0 ; i < blen ; i++ ) {
+                        int c = buff[i] ;
+                        buff[i] = (' '<=c && c<128) ? c : '.' ;
+                    }
+                }
+
+                char sbuff[80];
+                sprintf(sbuff,"%5ld %12s %8lu   %s
", index++,chType,dOff,buff);
+                if ( option == kpsBasic ) out << sbuff;
+
+                // for XMP, back up and read the whole block
+                const char* key = "XML:com.adobe.xmp" ;
+                int       start = ::strlen(key);
+                buff[start] = 0;
+                if ( option == kpsXMP && ::strcmp((const char*)buff,key) == 0 ) {
+                    io_->seek(-blen , BasicIo::cur);
+                    dataOffset = dOff ;
+                    byte* xmp  = new byte[dataOffset+5];
+                    io_->read(xmp,dataOffset+4);
+                    xmp[dataOffset]=0;
+                    while ( xmp[start] == 0 ) start++;
+                    out << xmp+start << std::endl;
+                    delete [] xmp;
+                    dataOffset = 0;
+                }
 
+                if ( dataOffset ) io_->seek(dataOffset + 4 , BasicIo::cur);
+                if (io_->error()) throw Error(14);
+            }
+        }
     }
 
     void PngImage::readMetadata()

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list