libextractor

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

commit 5071b3fb9309f0a213e6a0d0f70c0d1e5a8555aa
parent d4abc255a88fe3e1be97bc7802aa0ee400d0e521
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu,  9 Aug 2012 05:58:16 +0000

fixing exiv2 plugin

Diffstat:
Msrc/main/extract.c | 12++++++------
Msrc/plugins/Makefile.am | 2+-
Msrc/plugins/exiv2_extractor.cc | 99+++++++++++++++++++++++++++++--------------------------------------------------
Msrc/plugins/test_exiv2.c | 239++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/plugins/test_lib.c | 5++++-
Rtest/exiv-iptc.jpg -> src/plugins/testdata/exiv2_iptc.jpg | 0
6 files changed, 278 insertions(+), 79 deletions(-)

diff --git a/src/main/extract.c b/src/main/extract.c @@ -117,9 +117,9 @@ struct Help * @param opt program options (NULL-terminated array) */ static void -formatHelp (const char *general, - const char *description, - const struct Help *opt) +format_help (const char *general, + const char *description, + const struct Help *opt) { size_t slen; unsigned int i; @@ -209,7 +209,7 @@ formatHelp (const char *general, * Run --help. */ static void -printHelp () +print_help () { static struct Help help[] = { @@ -239,7 +239,7 @@ printHelp () gettext_noop("do not print keywords of the given TYPE") }, { 0, NULL, NULL, NULL }, }; - formatHelp (_("extract [OPTIONS] [FILENAME]*"), + format_help (_("extract [OPTIONS] [FILENAME]*"), _("Extract metadata from files."), help); @@ -671,7 +671,7 @@ main (int argc, char *argv[]) processor = &print_selected_keywords_grep_friendly; break; case 'h': - printHelp (); + print_help (); return 0; case 'i': in_process = YES; diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am @@ -60,7 +60,7 @@ PLUGIN_JPEG=libextractor_jpeg.la TEST_JPEG=test_jpeg endif -if HAVE_POPPLER +if HAVE_EXIV2 PLUGIN_EXIV2=libextractor_exiv2.la TEST_EXIV2=test_exiv2 endif diff --git a/src/plugins/exiv2_extractor.cc b/src/plugins/exiv2_extractor.cc @@ -33,16 +33,16 @@ #include <exiv2/futils.hpp> /** - * Should we suppress exiv2 warnings? + * Enable debugging to get error messages. */ -#define SUPPRESS_WARNINGS 1 +#define DEBUG 0 /** * Implementation of EXIV2's BasicIO interface based * on the 'struct EXTRACTOR_ExtractContext. */ -class ExtractorIO:Exiv2::BasicIo +class ExtractorIO : public Exiv2::BasicIo { private: @@ -263,7 +263,7 @@ ExtractorIO::read (long rcount) { void *data; ssize_t ret; - + if (-1 == (ret = ec->read (ec->cls, &data, rcount))) return Exiv2::DataBuf (NULL, 0); return Exiv2::DataBuf ((const Exiv2::byte *) data, ret); @@ -301,11 +301,11 @@ int ExtractorIO::getb () { void *data; - char *r; + const unsigned char *r; if (1 != ec->read (ec->cls, &data, 1)) throw Exiv2::BasicError<char> (42 /* error code */); - r = (char *) data; + r = (const unsigned char *) data; return *r; } @@ -514,6 +514,7 @@ ExtractorIO::wpath () const Exiv2::BasicIo::AutoPtr ExtractorIO::temporary () const { + fprintf (stderr, "throwing temporary error\n"); throw Exiv2::BasicError<char> (42 /* error code */); } @@ -540,11 +541,11 @@ ExtractorIO::temporary () const * @return 0 to continue extracting, 1 to abort */ static int -addExiv2Tag (const Exiv2::ExifData& exifData, - const std::string& key, - enum EXTRACTOR_MetaType type, - EXTRACTOR_MetaDataProcessor proc, - void *proc_cls) +add_exiv2_tag (const Exiv2::ExifData& exifData, + const std::string& key, + enum EXTRACTOR_MetaType type, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls) { const char *str; Exiv2::ExifKey ek (key); @@ -576,11 +577,11 @@ addExiv2Tag (const Exiv2::ExifData& exifData, * @return 0 to continue extracting, 1 to abort */ static int -addIptcData (const Exiv2::IptcData& iptcData, - const std::string& key, - enum EXTRACTOR_MetaType type, - EXTRACTOR_MetaDataProcessor proc, - void *proc_cls) +add_iptc_data (const Exiv2::IptcData& iptcData, + const std::string& key, + enum EXTRACTOR_MetaType type, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls) { const char *str; Exiv2::IptcKey ek (key); @@ -615,11 +616,11 @@ addIptcData (const Exiv2::IptcData& iptcData, * @return 0 to continue extracting, 1 to abort */ static int -addXmpData(const Exiv2::XmpData& xmpData, - const std::string& key, - enum EXTRACTOR_MetaType type, - EXTRACTOR_MetaDataProcessor proc, - void *proc_cls) +add_xmp_data (const Exiv2::XmpData& xmpData, + const std::string& key, + enum EXTRACTOR_MetaType type, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls) { const char * str; Exiv2::XmpKey ek (key); @@ -641,33 +642,33 @@ addXmpData(const Exiv2::XmpData& xmpData, /** - * Call 'addExiv2Tag' for the given key-type combination. - * Uses 'return' if addExiv2Tag returns non-0. + * Call 'add_exiv2_tag' for the given key-type combination. + * Uses 'return' if add_exiv2_tag returns non-0. * * @param s key to lookup * @param type libextractor type to use for the meta data found under the given key */ -#define ADDEXIV(s,t) do { if (0 != addExiv2Tag (exifData, s, t, ec->proc, ec->cls)) return; } while (0) +#define ADDEXIV(s,t) do { if (0 != add_exiv2_tag (exifData, s, t, ec->proc, ec->cls)) return; } while (0) /** - * Call 'addIptcData' for the given key-type combination. - * Uses 'return' if addIptcData returns non-0. + * Call 'add_iptc_data' for the given key-type combination. + * Uses 'return' if add_iptc_data returns non-0. * * @param s key to lookup * @param type libextractor type to use for the meta data found under the given key */ -#define ADDIPTC(s,t) do { if (0 != addIptcData (iptcData, s, t, ec->proc, ec->cls)) return; } while (0) +#define ADDIPTC(s,t) do { if (0 != add_iptc_data (iptcData, s, t, ec->proc, ec->cls)) return; } while (0) /** - * Call 'addXmpData' for the given key-type combination. - * Uses 'return' if addXmpData returns non-0. + * Call 'add_xmp_data' for the given key-type combination. + * Uses 'return' if add_xmp_data returns non-0. * * @param s key to lookup * @param type libextractor type to use for the meta data found under the given key */ -#define ADDXMP(s,t) do { if (0 != addXmpData (xmpData, s, t, ec->proc, ec->cls)) return; } while (0) +#define ADDXMP(s,t) do { if (0 != add_xmp_data (xmpData, s, t, ec->proc, ec->cls)) return; } while (0) /** @@ -680,7 +681,8 @@ EXTRACTOR_exiv2_extract_method (struct EXTRACTOR_ExtractContext *ec) { try { - std::auto_ptr<Exiv2::BasicIo> eio = new ExtractorIO (ec); + Exiv2::LogMsg::setLevel (Exiv2::LogMsg::mute); + std::auto_ptr<Exiv2::BasicIo> eio(new ExtractorIO (ec)); Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open (eio); if (0 == image.get ()) return; @@ -735,35 +737,6 @@ EXTRACTOR_exiv2_extract_method (struct EXTRACTOR_ExtractContext *ec) ADDEXIV ("Exif.Panasonic.WhiteBalance", EXTRACTOR_METATYPE_WHITE_BALANCE); ADDEXIV ("Exif.Photo.FNumber", EXTRACTOR_METATYPE_APERTURE); ADDEXIV ("Exif.Photo.ExposureTime", EXTRACTOR_METATYPE_EXPOSURE); - -#if FIXME - /* FIXME: the 'ADD' macro below won't work as we don't have 'proc' and 'proc_cls' in - this scope... */ - Exiv2::ExifData::const_iterator md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.ApertureValue")); - if (exifData.end() != md) - { - std::ostringstream os; - os << std::fixed << std::setprecision(1) - << "F" << exp(log(2.0) * md->toFloat() / 2); - ADD (os.str().c_str(), EXTRACTOR_METATYPE_APERTURE); - } - - md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.ShutterSpeedValue")); - if (exifData.end() != md) - { - double tmp = exp(log(2.0) * md->toFloat()) + 0.5; - std::ostringstream os; - if (tmp > 1) - { - os << "1/" << static_cast<long>(tmp) << " s"; - } - else - { - os << static_cast<long>(1/tmp) << " s"; - } - ADD (os.str().c_str(), EXTRACTOR_METATYPE_EXPOSURE); - } -#endif } Exiv2::IptcData &iptcData = image->iptcData(); @@ -773,12 +746,12 @@ EXTRACTOR_exiv2_extract_method (struct EXTRACTOR_ExtractContext *ec) ADDIPTC ("Iptc.Application2.City", EXTRACTOR_METATYPE_LOCATION_CITY); ADDIPTC ("Iptc.Application2.SubLocation", EXTRACTOR_METATYPE_LOCATION_SUBLOCATION); ADDIPTC ("Iptc.Application2.CountryName", EXTRACTOR_METATYPE_LOCATION_COUNTRY); - ADDIPTC ("Xmp.photoshop.Country", EXTRACTOR_METATYPE_RATING); } Exiv2::XmpData &xmpData = image->xmpData(); if (! xmpData.empty()) { + ADDXMP ("Xmp.photoshop.Country", EXTRACTOR_METATYPE_LOCATION_COUNTRY); ADDXMP ("Xmp.photoshop.City", EXTRACTOR_METATYPE_LOCATION_CITY); ADDXMP ("Xmp.xmp.Rating", EXTRACTOR_METATYPE_RATING); ADDXMP ("Xmp.MicrosoftPhoto.Rating", EXTRACTOR_METATYPE_RATING); @@ -789,8 +762,8 @@ EXTRACTOR_exiv2_extract_method (struct EXTRACTOR_ExtractContext *ec) } catch (const Exiv2::AnyError& e) { -#ifndef SUPPRESS_WARNINGS - std::cout << "Caught Exiv2 exception '" << e << "'\n"; +#if DEBUG + std::cerr << "Caught Exiv2 exception '" << e << "'\n"; #endif } } diff --git a/src/plugins/test_exiv2.c b/src/plugins/test_exiv2.c @@ -19,7 +19,7 @@ */ /** * @file plugins/test_exiv2.c - * @brief testcase for ogg plugin + * @brief testcase for exiv2 plugin * @author Christian Grothoff */ #include "platform.h" @@ -36,23 +36,246 @@ int main (int argc, char *argv[]) { - struct SolutionData exiv2_image_sol[] = + struct SolutionData exiv2_iptc_sol[] = { { - EXTRACTOR_METATYPE_IMAGE_DIMENSIONS, + EXTRACTOR_METATYPE_GPS_LATITUDE_REF, EXTRACTOR_METAFORMAT_UTF8, "text/plain", - "3x3", - strlen ("3x3") + 1, + "North", + strlen ("North") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_GPS_LATITUDE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "28deg 8' 17.585\" ", + strlen ("28deg 8' 17.585\" ") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_GPS_LONGITUDE_REF, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "West", + strlen ("West") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_GPS_LONGITUDE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "14deg 14' 21.713\" ", + strlen ("14deg 14' 21.713\" ") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_CAMERA_MAKE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "PENTAX Corporation", + strlen ("PENTAX Corporation") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_CAMERA_MODEL, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "PENTAX Optio W30", + strlen ("PENTAX Optio W30") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_ORIENTATION, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "top, left", + strlen ("top, left") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_CREATION_DATE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "2008:06:29 16:06:10", + strlen ("2008:06:29 16:06:10") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_EXPOSURE_BIAS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "0 EV", + strlen ("0 EV") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_FLASH, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "No, compulsory", + strlen ("No, compulsory") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_FOCAL_LENGTH, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "18.9 mm", + strlen ("18.9 mm") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_FOCAL_LENGTH_35MM, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "114.0 mm", + strlen ("114.0 mm") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_ISO_SPEED, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "64", + strlen ("64") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_METERING_MODE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Multi-segment", + strlen ("Multi-segment") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_APERTURE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "F8", + strlen ("F8") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_EXPOSURE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "1/320 s", + strlen ("1/320 s") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_LOCATION_CITY, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Los Verdes", + strlen ("Los Verdes") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_LOCATION_SUBLOCATION, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Fuerteventura", + strlen ("Fuerteventura") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_LOCATION_COUNTRY, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Spain", + strlen ("Spain") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Fuerteventura", + strlen ("Fuerteventura") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Landschaftsbild", + strlen ("Landschaftsbild") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "ProCenter Rene Egli", + strlen ("ProCenter Rene Egli") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Sand", + strlen ("Sand") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Sport", + strlen ("Sport") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Urlaub", + strlen ("Urlaub") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Was?", + strlen ("Was?") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Wind", + strlen ("Wind") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Windsurfen", + strlen ("Windsurfen") + 1, + 0 + }, + { + EXTRACTOR_METATYPE_KEYWORDS, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "Wo?", + strlen ("Wo?") + 1, 0 }, { 0, 0, NULL, NULL, 0, -1 } }; struct ProblemSet ps[] = { - { NULL, NULL }, - { "testdata/exiv2_image.jpg", - exiv2_image_sol }, + { "testdata/exiv2_iptc.jpg", + exiv2_iptc_sol }, { NULL, NULL } }; return ET_main ("exiv2", ps); diff --git a/src/plugins/test_lib.c b/src/plugins/test_lib.c @@ -75,8 +75,11 @@ process_replies (void *cls, return 0; } fprintf (stderr, - "Got additional meta data of type %d from plugin `%s'\n", + "Got additional meta data of type %d and format %d with value `%.*s' from plugin `%s'\n", type, + format, + (int) data_len, + data, plugin_name); return 0; } diff --git a/test/exiv-iptc.jpg b/src/plugins/testdata/exiv2_iptc.jpg Binary files differ.