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 */