libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

exiv2_extractor.cc (22031B)


      1 // ***************************************************************** -*- C++ -*-
      2 /*
      3  * This program is free software; you can redistribute it and/or
      4  * modify it under the terms of the GNU General Public License
      5  * as published by the Free Software Foundation; either version 3
      6  * of the License, or (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program; if not, write to the Free Software
     15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
     16  */
     17 /**
     18  * @file plugins/exiv2_extractor.cc
     19  * @brief libextractor plugin for Exif using exiv2
     20  * @author Andreas Huggel (ahu)
     21  * @author Christian Grothoff
     22  */
     23 #include "platform.h"
     24 #include "extractor.h"
     25 #include <iostream>
     26 #include <iomanip>
     27 #include <cassert>
     28 #include <cstring>
     29 #include <math.h>
     30 #include <exiv2/exiv2.hpp>
     31 
     32 /**
     33  * Enable debugging to get error messages.
     34  */
     35 #define DEBUG 0
     36 
     37 
     38 /**
     39  * Implementation of EXIV2's BasicIO interface based
     40  * on the 'struct EXTRACTOR_ExtractContext.
     41  */
     42 class ExtractorIO : public Exiv2::BasicIo
     43 {
     44 private:
     45 
     46 /**
     47  * Extract context we are using.
     48  */
     49 struct EXTRACTOR_ExtractContext *ec;
     50 
     51 /**
     52  * Dummy string "(unknown)" to represent the unknown source.
     53  *
     54  * It is needed as class variable as in EXIV2 0.28 and greater the path() method
     55  * returns a const reference.
     56  */
     57 std::string io_path;
     58 
     59 public:
     60 
     61 /**
     62  * Constructor.
     63  *
     64  * @param s_ec extract context to wrap
     65  */
     66 ExtractorIO (struct EXTRACTOR_ExtractContext *s_ec)
     67 {
     68   ec = s_ec;
     69   io_path = "(unknown)";
     70 }
     71 
     72 
     73 /**
     74  * Destructor.
     75  */
     76 virtual ~ExtractorIO ()
     77 {
     78   /* nothing to do */
     79 }
     80 
     81 
     82 /**
     83  * Open stream.
     84  *
     85  * @return 0 (always successful)
     86  */
     87 virtual int open ();
     88 
     89 /**
     90  * Close stream.
     91  *
     92  * @return 0 (always successful)
     93  */
     94 virtual int close ();
     95 
     96 /**
     97  * Read up to 'rcount' bytes into a buffer
     98  *
     99  * @param rcount number of bytes to read
    100  * @return buffer with data read, empty buffer (!) on failure (!)
    101  */
    102 #if EXIV2_TEST_VERSION (0,28,0)
    103 virtual Exiv2::DataBuf read (size_t rcount);
    104 #else
    105 virtual Exiv2::DataBuf read (long rcount);
    106 #endif
    107 
    108 /**
    109  * Read up to 'rcount' bytes into 'buf'.
    110  *
    111  * @param buf buffer to fill
    112  * @param rcount size of 'buf'
    113  * @return number of bytes read successfully, 0 on failure (!)
    114  */
    115 #if EXIV2_TEST_VERSION (0,28,0)
    116 virtual size_t read (Exiv2::byte *buf,
    117                    size_t rcount);
    118 #else
    119 virtual long read (Exiv2::byte *buf,
    120                    long rcount);
    121 #endif
    122 
    123 #if EXIV2_TEST_VERSION (0,28,0)
    124 virtual void populateFakeData();
    125 #endif
    126 
    127 /**
    128  * Read a single character.
    129  *
    130  * @return the character
    131  * @throw exception on errors
    132  */
    133 virtual int getb ();
    134 
    135 /**
    136  * Write to stream.
    137  *
    138  * @param data data to write
    139  * @param wcount how many bytes to write
    140  * @return -1 (always fails)
    141  */
    142 #if EXIV2_TEST_VERSION(0,28,0)
    143 virtual size_t write (const Exiv2::byte *data,
    144                     size_t wcount);
    145 #else
    146 virtual long write (const Exiv2::byte *data,
    147                     long wcount);
    148 #endif
    149 
    150 /**
    151  * Write to stream.
    152  *
    153  * @param src stream to copy
    154  * @return -1 (always fails)
    155  */
    156 #if EXIV2_TEST_VERSION(0,28,0)
    157 virtual size_t write (Exiv2::BasicIo &src);
    158 #else
    159 virtual long write (Exiv2::BasicIo &src);
    160 #endif
    161 
    162 /**
    163  * Write a single byte.
    164  *
    165  * @param data byte to write
    166  * @return -1 (always fails)
    167  */
    168 virtual int putb (Exiv2::byte data);
    169 
    170 /**
    171  * Not supported.
    172  *
    173  * @throws error
    174  */
    175 virtual void transfer (Exiv2::BasicIo& src);
    176 
    177 
    178 #if EXIV2_TEST_VERSION (0,28,0)
    179 #define SEEK_OFFSET_TYPE int64_t
    180 #else
    181 #define SEEK_OFFSET_TYPE long
    182 #endif
    183   
    184 /**
    185  * Seek to the given offset.
    186  *
    187  * @param offset desired offset
    188  * @parma pos offset is relative to where?
    189  * @return -1 on failure, 0 on success
    190  */
    191 virtual int seek (SEEK_OFFSET_TYPE offset,
    192                   Exiv2::BasicIo::Position pos);
    193 
    194 /**
    195  * Not supported.
    196  *
    197  * @throws error
    198  */
    199 virtual Exiv2::byte*mmap (bool isWritable);
    200 
    201 /**
    202  * Not supported.
    203  *
    204  * @return -1 (error)
    205  */
    206 virtual int munmap ();
    207 
    208 /**
    209  * Return our current offset in the file.
    210  *
    211  * @return -1 on error
    212  */
    213 #if EXIV2_TEST_VERSION(0,28,0)
    214 virtual size_t tell (void) const;
    215 #else
    216 virtual long int tell (void) const;
    217 #endif
    218 
    219 /**
    220  * Return overall size of the file.
    221  *
    222  * @return -1 on error
    223  */
    224 #if EXIV2_TEST_VERSION (0,26,0)
    225 virtual size_t size (void) const;
    226 
    227 #else
    228 virtual long int size (void) const;
    229 
    230 #endif
    231 
    232 /**
    233  * Check if file is open.
    234  *
    235  * @return true (always).
    236  */
    237 virtual bool isopen () const;
    238 
    239 /**
    240  * Check if this file source is in error mode.
    241  *
    242  * @return 0 (always all is fine).
    243  */
    244 virtual int error () const;
    245 
    246 /**
    247  * Check if current position of the file is at the end
    248  *
    249  * @return true if at EOF, false if not.
    250  */
    251 virtual bool eof () const;
    252 
    253 /**
    254  * Not supported.
    255  *
    256  * @throws error
    257  */
    258 #if EXIV2_TEST_VERSION(0,28,0)
    259 virtual const std::string& path () const noexcept;
    260 #else
    261 virtual std::string path () const;
    262 #endif
    263 
    264 #ifdef EXV_UNICODE_PATH
    265 /**
    266  * Not supported.
    267  *
    268  * @throws error
    269  */
    270 virtual std::wstring wpath () const;
    271 
    272 #endif
    273 
    274 /**
    275  * Not supported.
    276  *
    277  * @throws error
    278  */
    279 #if EXIV2_TEST_VERSION(0,28,0)
    280 virtual Exiv2::BasicIo::UniquePtr temporary () const;
    281 #else
    282 virtual Exiv2::BasicIo::AutoPtr temporary () const;
    283 #endif
    284 
    285 };
    286 
    287 
    288 /**
    289  * Open stream.
    290  *
    291  * @return 0 (always successful)
    292  */
    293 int
    294 ExtractorIO::open ()
    295 {
    296   return 0;
    297 }
    298 
    299 
    300 /**
    301  * Close stream.
    302  *
    303  * @return 0 (always successful)
    304  */
    305 int
    306 ExtractorIO::close ()
    307 {
    308   return 0;
    309 }
    310 
    311 
    312 /**
    313  * Read up to 'rcount' bytes into a buffer
    314  *
    315  * @param rcount number of bytes to read
    316  * @return buffer with data read, empty buffer (!) on failure (!)
    317  */
    318 Exiv2::DataBuf
    319 #if EXIV2_TEST_VERSION (0,28,0)
    320 ExtractorIO::read (size_t rcount)
    321 #else
    322 ExtractorIO::read (long rcount)
    323 #endif
    324 {
    325   void *data;
    326   ssize_t ret;
    327 
    328   if (-1 == (ret = ec->read (ec->cls, &data, rcount)))
    329     return Exiv2::DataBuf (NULL, 0);
    330   return Exiv2::DataBuf ((const Exiv2::byte *) data, ret);
    331 }
    332 
    333 
    334 /**
    335  * Read up to 'rcount' bytes into 'buf'.
    336  *
    337  * @param buf buffer to fill
    338  * @param rcount size of 'buf'
    339  * @return number of bytes read successfully, 0 on failure (!)
    340  */
    341 #if EXIV2_TEST_VERSION (0,28,0)
    342 size_t
    343 ExtractorIO::read (Exiv2::byte *buf,
    344                    size_t rcount)
    345 #else
    346 long
    347 ExtractorIO::read (Exiv2::byte *buf,
    348                    long rcount)
    349 #endif
    350 {
    351   void *data;
    352   ssize_t ret;
    353   long got;
    354 
    355   got = 0;
    356   while (got < rcount)
    357   {
    358     if (-1 == (ret = ec->read (ec->cls, &data, rcount - got)))
    359       return got;
    360     if (0 == ret)
    361       break;
    362     memcpy (&buf[got], data, ret);
    363     got += ret;
    364   }
    365   return got;
    366 }
    367 
    368 #if EXIV2_TEST_VERSION (0,28,0)
    369 void ExtractorIO::populateFakeData()
    370 {
    371   return;
    372 }
    373 #endif
    374 
    375 /**
    376  * Read a single character.
    377  *
    378  * @return the character
    379  * @throw exception on errors
    380  */
    381 int
    382 ExtractorIO::getb ()
    383 {
    384   void *data;
    385   const unsigned char *r;
    386 
    387   if (1 != ec->read (ec->cls, &data, 1))
    388 #if EXIV2_TEST_VERSION(0,28,0)
    389     throw Exiv2::Error (Exiv2::ErrorCode::kerDecodeLangAltQualifierFailed);
    390 #elif EXIV2_TEST_VERSION (0,27,0)
    391     throw Exiv2::BasicError<char> (Exiv2::kerDecodeLangAltQualifierFailed);
    392 #else
    393     throw Exiv2::BasicError<char> (42 /* error code */);
    394 #endif
    395   r = (const unsigned char *) data;
    396   return *r;
    397 }
    398 
    399 
    400 /**
    401  * Write to stream.
    402  *
    403  * @param data data to write
    404  * @param wcount how many bytes to write
    405  * @return -1 (always fails)
    406  */
    407 #if EXIV2_TEST_VERSION(0,28,0)
    408 size_t
    409 ExtractorIO::write (const Exiv2::byte *data,
    410                     size_t wcount)
    411 #else
    412 long
    413 ExtractorIO::write (const Exiv2::byte *data,
    414                     long wcount)
    415 #endif
    416 {
    417   return -1;
    418 }
    419 
    420 
    421 /**
    422  * Write to stream.
    423  *
    424  * @param src stream to copy
    425  * @return -1 (always fails)
    426  */
    427 #if EXIV2_TEST_VERSION(0,28,0)
    428 size_t
    429 #else
    430 long
    431 #endif
    432 ExtractorIO::write (Exiv2::BasicIo &src)
    433 {
    434   return -1;
    435 }
    436 
    437 
    438 /**
    439  * Write a single byte.
    440  *
    441  * @param data byte to write
    442  * @return -1 (always fails)
    443  */
    444 int
    445 ExtractorIO::putb (Exiv2::byte data)
    446 {
    447   return -1;
    448 }
    449 
    450 
    451 /**
    452  * Not supported.
    453  *
    454  * @throws error
    455  */
    456 void
    457 ExtractorIO::transfer (Exiv2::BasicIo& src)
    458 {
    459 #if EXIV2_TEST_VERSION(0,28,0)
    460   throw Exiv2::Error (Exiv2::ErrorCode::kerDecodeLangAltQualifierFailed);
    461 #elif EXIV2_TEST_VERSION (0,27,0)
    462   throw Exiv2::BasicError<char> (Exiv2::kerDecodeLangAltQualifierFailed);
    463 #else
    464   throw Exiv2::BasicError<char> (42 /* error code */);
    465 #endif
    466 }
    467 
    468 
    469 /**
    470  * Seek to the given offset.
    471  *
    472  * @param offset desired offset
    473  * @parma pos offset is relative to where?
    474  * @return -1 on failure, 0 on success
    475  */
    476 int
    477 ExtractorIO::seek (SEEK_OFFSET_TYPE offset,
    478                    Exiv2::BasicIo::Position pos)
    479 {
    480   int rel;
    481 
    482   switch (pos)
    483   {
    484   case beg:   // Exiv2::BasicIo::beg:
    485     rel = SEEK_SET;
    486     break;
    487   case cur:
    488     rel = SEEK_CUR;
    489     break;
    490   case end:
    491     rel = SEEK_END;
    492     break;
    493   default:
    494     abort ();
    495   }
    496   if (-1 == ec->seek (ec->cls, offset, rel))
    497     return -1;
    498   return 0;
    499 }
    500 
    501 
    502 /**
    503  * Not supported.
    504  *
    505  * @throws error
    506  */
    507 Exiv2::byte *
    508 ExtractorIO::mmap (bool isWritable)
    509 {
    510 #if EXIV2_TEST_VERSION (0,28,0)
    511   throw Exiv2::Error (Exiv2::ErrorCode::kerDecodeLangAltQualifierFailed);
    512 #elif EXIV2_TEST_VERSION (0,27,0)
    513   throw Exiv2::BasicError<char> (Exiv2::kerDecodeLangAltQualifierFailed);
    514 #else
    515   throw Exiv2::BasicError<char> (42 /* error code */);
    516 #endif
    517 }
    518 
    519 
    520 /**
    521  * Not supported.
    522  *
    523  * @return -1 error
    524  */
    525 int
    526 ExtractorIO::munmap ()
    527 {
    528   return -1;
    529 }
    530 
    531 
    532 /**
    533  * Return our current offset in the file.
    534  *
    535  * @return -1 on error
    536  */
    537 #if EXIV2_TEST_VERSION(0,28,0)
    538 size_t
    539 #else
    540 long int
    541 #endif
    542 ExtractorIO::tell (void) const
    543 {
    544   return (long) ec->seek (ec->cls, 0, SEEK_CUR);
    545 }
    546 
    547 
    548 /**
    549  * Return overall size of the file.
    550  *
    551  * @return -1 on error
    552  */
    553 #if EXIV2_TEST_VERSION (0,26,0)
    554 size_t
    555 #else
    556 long int
    557 #endif
    558 ExtractorIO::size (void) const
    559 {
    560   return (long) ec->get_size (ec->cls);
    561 }
    562 
    563 
    564 /**
    565  * Check if file is open.
    566  *
    567  * @return true (always).
    568  */
    569 bool
    570 ExtractorIO::isopen () const
    571 {
    572   return true;
    573 }
    574 
    575 
    576 /**
    577  * Check if this file source is in error mode.
    578  *
    579  * @return 0 (always all is fine).
    580  */
    581 int
    582 ExtractorIO::error () const
    583 {
    584   return 0;
    585 }
    586 
    587 
    588 /**
    589  * Check if current position of the file is at the end
    590  *
    591  * @return true if at EOF, false if not.
    592  */
    593 bool
    594 ExtractorIO::eof () const
    595 {
    596   return size () == tell ();
    597 }
    598 
    599 
    600 /**
    601  * Return the string with the path.
    602  *
    603  * @return the string "(unknown)"
    604  */
    605 #if EXIV2_TEST_VERSION (0,28,0)
    606 const std::string&
    607 ExtractorIO::path () const noexcept
    608 #else
    609 std::string
    610 ExtractorIO::path () const
    611 #endif
    612 {
    613   return io_path;
    614 }
    615 
    616 
    617 #ifdef EXV_UNICODE_PATH
    618 /**
    619  * Not supported.
    620  *
    621  * @throws error
    622  */
    623 std::wstring
    624 ExtractorIO::wpath () const
    625 {
    626 #if EXIV2_TEST_VERSION (0,28,0)
    627   throw Exiv2::Error (Exiv2::ErrorCode::kerDecodeLangAltQualifierFailed);
    628 #elif EXIV2_TEST_VERSION (0,27,0)
    629   throw Exiv2::BasicError<char> (Exiv2::kerDecodeLangAltQualifierFailed);
    630 #else
    631   throw Exiv2::BasicError<char> (42 /* error code */);
    632 #endif
    633 }
    634 
    635 
    636 #endif
    637 
    638 
    639 /**
    640  * Not supported.
    641  *
    642  * @throws error
    643  */
    644 #if EXIV2_TEST_VERSION(0,28,0)
    645 Exiv2::BasicIo::UniquePtr
    646 #else
    647 Exiv2::BasicIo::AutoPtr
    648 #endif
    649 ExtractorIO::temporary () const
    650 {
    651   fprintf (stderr, "throwing temporary error\n");
    652 #if EXIV2_TEST_VERSION(0,28,0)
    653   throw Exiv2::Error (Exiv2::ErrorCode::kerDecodeLangAltQualifierFailed);
    654 #elif EXIV2_TEST_VERSION (0,27,0)
    655   throw Exiv2::BasicError<char> (Exiv2::kerDecodeLangAltQualifierFailed);
    656 #else
    657   throw Exiv2::BasicError<char> (42 /* error code */);
    658 #endif
    659 }
    660 
    661 
    662 /**
    663  * Pass the given UTF-8 string to the 'proc' callback using
    664  * the given type.  Uses 'return 1' if 'proc' returns non-0.
    665  *
    666  * @param s 0-terminated UTF8 string value with the meta data
    667  * @param type libextractor type for the meta data
    668  */
    669 #define ADD(s, type) do { if (0 != proc (proc_cls, "exiv2", type, \
    670                                          EXTRACTOR_METAFORMAT_UTF8, \
    671                                          "text/plain", s, strlen (s) \
    672                                          + 1)) return 1; \
    673 } while (0)
    674 
    675 
    676 /**
    677  * Try to find a given key in the exifData and if a value is
    678  * found, pass it to 'proc'.
    679  *
    680  * @param exifData metadata set to inspect
    681  * @param key key to lookup in exifData
    682  * @param type extractor type to use
    683  * @param proc function to call with results
    684  * @param proc_cls closurer for proc
    685  * @return 0 to continue extracting, 1 to abort
    686  */
    687 static int
    688 add_exiv2_tag (const Exiv2::ExifData& exifData,
    689                const std::string& key,
    690                enum EXTRACTOR_MetaType type,
    691                EXTRACTOR_MetaDataProcessor proc,
    692                void *proc_cls)
    693 {
    694   const char *str;
    695   Exiv2::ExifKey ek (key);
    696   Exiv2::ExifData::const_iterator md = exifData.findKey (ek);
    697 
    698   if (exifData.end () == md)
    699     return 0; /* not found */
    700   std::string ccstr = Exiv2::toString (*md);
    701   str = ccstr.c_str ();
    702   /* skip over whitespace */
    703   while ( (strlen (str) > 0) && isspace ((unsigned char) str[0]))
    704     str++;
    705   if (strlen (str) > 0)
    706     ADD (str, type);
    707   md++;
    708   return 0;
    709 }
    710 
    711 
    712 /**
    713  * Try to find a given key in the iptcData and if a value is
    714  * found, pass it to 'proc'.
    715  *
    716  * @param ipctData metadata set to inspect
    717  * @param key key to lookup in exifData
    718  * @param type extractor type to use
    719  * @param proc function to call with results
    720  * @param proc_cls closurer for proc
    721  * @return 0 to continue extracting, 1 to abort
    722  */
    723 static int
    724 add_iptc_data (const Exiv2::IptcData& iptcData,
    725                const std::string& key,
    726                enum EXTRACTOR_MetaType type,
    727                EXTRACTOR_MetaDataProcessor proc,
    728                void *proc_cls)
    729 {
    730   const char *str;
    731   Exiv2::IptcKey ek (key);
    732   Exiv2::IptcData::const_iterator md = iptcData.findKey (ek);
    733 
    734   while (iptcData.end () !=  md)
    735   {
    736     if (0 != strcmp (Exiv2::toString (md->key ()).c_str (), key.c_str ()))
    737       break;
    738     std::string ccstr = Exiv2::toString (*md);
    739     str = ccstr.c_str ();
    740     /* skip over whitespace */
    741     while ((strlen (str) > 0) && isspace ((unsigned char) str[0]))
    742       str++;
    743     if (strlen (str) > 0)
    744       ADD (str, type);
    745     md++;
    746   }
    747   return 0;
    748 }
    749 
    750 
    751 /**
    752  * Try to find a given key in the xmpData and if a value is
    753  * found, pass it to 'proc'.
    754  *
    755  * @param xmpData metadata set to inspect
    756  * @param key key to lookup in exifData
    757  * @param type extractor type to use
    758  * @param proc function to call with results
    759  * @param proc_cls closurer for proc
    760  * @return 0 to continue extracting, 1 to abort
    761  */
    762 static int
    763 add_xmp_data (const Exiv2::XmpData& xmpData,
    764               const std::string& key,
    765               enum EXTRACTOR_MetaType type,
    766               EXTRACTOR_MetaDataProcessor proc,
    767               void *proc_cls)
    768 {
    769   const char *str;
    770   Exiv2::XmpKey ek (key);
    771   Exiv2::XmpData::const_iterator md = xmpData.findKey (ek);
    772 
    773   while (xmpData.end () != md)
    774   {
    775     if (0 != strcmp (Exiv2::toString (md->key ()).c_str (), key.c_str ()))
    776       break;
    777     std::string ccstr = Exiv2::toString (*md);
    778     str = ccstr.c_str ();
    779     while ( (strlen (str) > 0) && isspace ((unsigned char) str[0]))
    780       str++;
    781     if (strlen (str) > 0)
    782       ADD (str, type);
    783     md++;
    784   }
    785   return 0;
    786 }
    787 
    788 
    789 /**
    790  * Call 'add_exiv2_tag' for the given key-type combination.
    791  * Uses 'return' if add_exiv2_tag returns non-0.
    792  *
    793  * @param s key to lookup
    794  * @param type libextractor type to use for the meta data found under the given key
    795  */
    796 #define ADDEXIV(s,t) do { if (0 != add_exiv2_tag (exifData, s, t, ec->proc, \
    797                                                   ec->cls)) return; } while (0)
    798 
    799 
    800 /**
    801  * Call 'add_iptc_data' for the given key-type combination.
    802  * Uses 'return' if add_iptc_data returns non-0.
    803  *
    804  * @param s key to lookup
    805  * @param type libextractor type to use for the meta data found under the given key
    806  */
    807 #define ADDIPTC(s,t) do { if (0 != add_iptc_data (iptcData, s, t, ec->proc, \
    808                                                   ec->cls)) return; } while (0)
    809 
    810 
    811 /**
    812  * Call 'add_xmp_data' for the given key-type combination.
    813  * Uses 'return' if add_xmp_data returns non-0.
    814  *
    815  * @param s key to lookup
    816  * @param type libextractor type to use for the meta data found under the given key
    817  */
    818 #define ADDXMP(s,t)  do { if (0 != add_xmp_data  (xmpData,  s, t, ec->proc, \
    819                                                   ec->cls)) return; } while (0)
    820 
    821 
    822 /**
    823  * Main entry method for the 'exiv2' extraction plugin.
    824  *
    825  * @param ec extraction context provided to the plugin
    826  */
    827 extern "C" void
    828 EXTRACTOR_exiv2_extract_method (struct EXTRACTOR_ExtractContext *ec)
    829 {
    830   try
    831   {
    832 #if ! EXIV2_TEST_VERSION (0,24,0)
    833     Exiv2::LogMsg::setLevel (Exiv2::LogMsg::mute);
    834 #endif
    835 #if EXIV2_TEST_VERSION(0,28,0)
    836     std::unique_ptr<Exiv2::BasicIo> eio (new ExtractorIO (ec));
    837     Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open (std::move(eio));
    838 #else
    839     std::auto_ptr<Exiv2::BasicIo> eio (new ExtractorIO (ec));
    840     Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open (eio);
    841 #endif
    842     if (0 == image.get ())
    843       return;
    844     image->readMetadata ();
    845     Exiv2::ExifData &exifData = image->exifData ();
    846     if (! exifData.empty ())
    847     {
    848       ADDEXIV ("Exif.Image.Copyright", EXTRACTOR_METATYPE_COPYRIGHT);
    849       ADDEXIV ("Exif.Photo.UserComment", EXTRACTOR_METATYPE_COMMENT);
    850       ADDEXIV ("Exif.GPSInfo.GPSLatitudeRef",
    851                EXTRACTOR_METATYPE_GPS_LATITUDE_REF);
    852       ADDEXIV ("Exif.GPSInfo.GPSLatitude", EXTRACTOR_METATYPE_GPS_LATITUDE);
    853       ADDEXIV ("Exif.GPSInfo.GPSLongitudeRef",
    854                EXTRACTOR_METATYPE_GPS_LONGITUDE_REF);
    855       ADDEXIV ("Exif.GPSInfo.GPSLongitude", EXTRACTOR_METATYPE_GPS_LONGITUDE);
    856       ADDEXIV ("Exif.Image.Make", EXTRACTOR_METATYPE_CAMERA_MAKE);
    857       ADDEXIV ("Exif.Image.Model", EXTRACTOR_METATYPE_CAMERA_MODEL);
    858       ADDEXIV ("Exif.Image.Orientation", EXTRACTOR_METATYPE_ORIENTATION);
    859       ADDEXIV ("Exif.Photo.DateTimeOriginal", EXTRACTOR_METATYPE_CREATION_DATE);
    860       ADDEXIV ("Exif.Photo.ExposureBiasValue",
    861                EXTRACTOR_METATYPE_EXPOSURE_BIAS);
    862       ADDEXIV ("Exif.Photo.Flash", EXTRACTOR_METATYPE_FLASH);
    863       ADDEXIV ("Exif.CanonSi.FlashBias", EXTRACTOR_METATYPE_FLASH_BIAS);
    864       ADDEXIV ("Exif.Panasonic.FlashBias", EXTRACTOR_METATYPE_FLASH_BIAS);
    865       ADDEXIV ("Exif.Olympus.FlashBias", EXTRACTOR_METATYPE_FLASH_BIAS);
    866       ADDEXIV ("Exif.Photo.FocalLength", EXTRACTOR_METATYPE_FOCAL_LENGTH);
    867       ADDEXIV ("Exif.Photo.FocalLengthIn35mmFilm",
    868                EXTRACTOR_METATYPE_FOCAL_LENGTH_35MM);
    869       ADDEXIV ("Exif.Photo.ISOSpeedRatings", EXTRACTOR_METATYPE_ISO_SPEED);
    870       ADDEXIV ("Exif.CanonSi.ISOSpeed", EXTRACTOR_METATYPE_ISO_SPEED);
    871       ADDEXIV ("Exif.Nikon1.ISOSpeed", EXTRACTOR_METATYPE_ISO_SPEED);
    872       ADDEXIV ("Exif.Nikon2.ISOSpeed", EXTRACTOR_METATYPE_ISO_SPEED);
    873       ADDEXIV ("Exif.Nikon3.ISOSpeed", EXTRACTOR_METATYPE_ISO_SPEED);
    874       ADDEXIV ("Exif.Photo.ExposureProgram", EXTRACTOR_METATYPE_EXPOSURE_MODE);
    875       ADDEXIV ("Exif.CanonCs.ExposureProgram",
    876                EXTRACTOR_METATYPE_EXPOSURE_MODE);
    877       ADDEXIV ("Exif.Photo.MeteringMode", EXTRACTOR_METATYPE_METERING_MODE);
    878       ADDEXIV ("Exif.CanonCs.Macro", EXTRACTOR_METATYPE_MACRO_MODE);
    879       ADDEXIV ("Exif.Fujifilm.Macro", EXTRACTOR_METATYPE_MACRO_MODE);
    880       ADDEXIV ("Exif.Olympus.Macro", EXTRACTOR_METATYPE_MACRO_MODE);
    881       ADDEXIV ("Exif.Panasonic.Macro", EXTRACTOR_METATYPE_MACRO_MODE);
    882       ADDEXIV ("Exif.CanonCs.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    883       ADDEXIV ("Exif.Fujifilm.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    884       ADDEXIV ("Exif.Sigma.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    885       ADDEXIV ("Exif.Nikon1.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    886       ADDEXIV ("Exif.Nikon2.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    887       ADDEXIV ("Exif.Nikon3.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    888       ADDEXIV ("Exif.Olympus.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    889       ADDEXIV ("Exif.Panasonic.Quality", EXTRACTOR_METATYPE_IMAGE_QUALITY);
    890       ADDEXIV ("Exif.CanonSi.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    891       ADDEXIV ("Exif.Fujifilm.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    892       ADDEXIV ("Exif.Sigma.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    893       ADDEXIV ("Exif.Nikon1.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    894       ADDEXIV ("Exif.Nikon2.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    895       ADDEXIV ("Exif.Nikon3.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    896       ADDEXIV ("Exif.Olympus.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    897       ADDEXIV ("Exif.Panasonic.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE);
    898       ADDEXIV ("Exif.Photo.FNumber", EXTRACTOR_METATYPE_APERTURE);
    899       ADDEXIV ("Exif.Photo.ExposureTime", EXTRACTOR_METATYPE_EXPOSURE);
    900     }
    901 
    902     Exiv2::IptcData &iptcData = image->iptcData ();
    903     if (! iptcData.empty ())
    904     {
    905       ADDIPTC ("Iptc.Application2.Keywords", EXTRACTOR_METATYPE_KEYWORDS);
    906       ADDIPTC ("Iptc.Application2.City", EXTRACTOR_METATYPE_LOCATION_CITY);
    907       ADDIPTC ("Iptc.Application2.SubLocation",
    908                EXTRACTOR_METATYPE_LOCATION_SUBLOCATION);
    909       ADDIPTC ("Iptc.Application2.CountryName",
    910                EXTRACTOR_METATYPE_LOCATION_COUNTRY);
    911     }
    912 
    913     Exiv2::XmpData &xmpData = image->xmpData ();
    914     if (! xmpData.empty ())
    915     {
    916       ADDXMP ("Xmp.photoshop.Country", EXTRACTOR_METATYPE_LOCATION_COUNTRY);
    917       ADDXMP ("Xmp.photoshop.City", EXTRACTOR_METATYPE_LOCATION_CITY);
    918       ADDXMP ("Xmp.xmp.Rating", EXTRACTOR_METATYPE_RATING);
    919       ADDXMP ("Xmp.MicrosoftPhoto.Rating", EXTRACTOR_METATYPE_RATING);
    920       ADDXMP ("Xmp.iptc.CountryCode", EXTRACTOR_METATYPE_LOCATION_COUNTRY_CODE);
    921       ADDXMP ("Xmp.xmp.CreatorTool", EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE);
    922       ADDXMP ("Xmp.lr.hierarchicalSubject", EXTRACTOR_METATYPE_SUBJECT);
    923     }
    924   }
    925 #if EXIV2_TEST_VERSION (0,28,0)
    926   catch (const Exiv2::Error& e)
    927 #else
    928   catch (const Exiv2::AnyError& e)
    929 #endif
    930   {
    931 #if DEBUG
    932     std::cerr << "Caught Exiv2 exception '" << e << "'\n";
    933 #endif
    934   }
    935   catch (void *anything)
    936   {
    937   }
    938 }
    939 
    940 
    941 /* end of exiv2_extractor.cc */