"Fossies" - the Fresh Open Source Software Archive

Member "libextractor-1.11/src/plugins/exiv2_extractor.cc" (25 Jun 2020, 19519 Bytes) of package /linux/privat/libextractor-1.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "exiv2_extractor.cc" see the Fossies "Dox" file reference documentation.

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