aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--src/include/extractor.h9
-rw-r--r--src/main/extractor.c13
-rw-r--r--src/plugins/exiv2/exiv2extractor.cc729
4 files changed, 421 insertions, 333 deletions
diff --git a/ChangeLog b/ChangeLog
index e78aaf9..05b1c30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
1Sat Dec 5 11:32:30 CET 2009
2 Adding extraction of Iptc data using exiv2.
3
1Sat Jul 4 23:05:22 CEST 2009 4Sat Jul 4 23:05:22 CEST 2009
2 Fixed code to work with RPM 4.7. 5 Fixed code to work with RPM 4.7.
3 Releasing libextractor 0.5.23. 6 Releasing libextractor 0.5.23.
diff --git a/src/include/extractor.h b/src/include/extractor.h
index 211ab31..9daeb91 100644
--- a/src/include/extractor.h
+++ b/src/include/extractor.h
@@ -190,7 +190,14 @@ typedef enum {
190 EXTRACTOR_DISC_NUMBER = 134, 190 EXTRACTOR_DISC_NUMBER = 134,
191 EXTRACTOR_GNUNET_DISPLAY_TYPE = 135, 191 EXTRACTOR_GNUNET_DISPLAY_TYPE = 135,
192 EXTRACTOR_GNUNET_ECBC_URI = 136, 192 EXTRACTOR_GNUNET_ECBC_URI = 136,
193 EXTRACTOR_GNUNET_FULL_DATA = 137 193 EXTRACTOR_GNUNET_FULL_DATA = 137,
194 EXTRACTOR_LOCATION_CITY = 138,
195 EXTRACTOR_LOCATION_COUNTRY = 139,
196 EXTRACTOR_LOCATION_SUBLOCATION = 140,
197 EXTRACTOR_GPS_LATITUDE_REF = 141,
198 EXTRACTOR_GPS_LATITUDE = 142,
199 EXTRACTOR_GPS_LONGITUDE_REF = 143,
200 EXTRACTOR_GPS_LONGITUDE = 144
194} EXTRACTOR_KeywordType; 201} EXTRACTOR_KeywordType;
195 202
196/** 203/**
diff --git a/src/main/extractor.c b/src/main/extractor.c
index c884113..f89ea0d 100644
--- a/src/main/extractor.c
+++ b/src/main/extractor.c
@@ -176,15 +176,22 @@ static const char *keywordTypes[] = {
176 gettext_noop("filesize"), 176 gettext_noop("filesize"),
177 gettext_noop("track number"), 177 gettext_noop("track number"),
178 gettext_noop("international standard recording code"), 178 gettext_noop("international standard recording code"),
179 gettext_noop("disc number"), /* 134 */ 179 gettext_noop("disc number"),
180 gettext_noop("preferred display style (GNUnet)"), 180 gettext_noop("preferred display style (GNUnet)"), /* 135 */
181 gettext_noop("GNUnet URI of ECBC data"), 181 gettext_noop("GNUnet URI of ECBC data"),
182 gettext_noop("Complete file data (for non-binary files only)"), 182 gettext_noop("Complete file data (for non-binary files only)"),
183 gettext_noop("city"),
184 gettext_noop("country"),
185 gettext_noop("sublocation"), /* 140 */
186 gettext_noop("GPS latitude ref"),
187 gettext_noop("GPS latitude"),
188 gettext_noop("GPS longitude ref"),
189 gettext_noop("GPS longitude"),
183 NULL 190 NULL
184}; 191};
185 192
186/* the number of keyword types (for bounds-checking) */ 193/* the number of keyword types (for bounds-checking) */
187#define HIGHEST_TYPE_NUMBER 138 194#define HIGHEST_TYPE_NUMBER 145
188 195
189#ifdef HAVE_LIBOGG 196#ifdef HAVE_LIBOGG
190#if HAVE_VORBIS 197#if HAVE_VORBIS
diff --git a/src/plugins/exiv2/exiv2extractor.cc b/src/plugins/exiv2/exiv2extractor.cc
index 673edd4..1bb267b 100644
--- a/src/plugins/exiv2/exiv2extractor.cc
+++ b/src/plugins/exiv2/exiv2extractor.cc
@@ -79,368 +79,440 @@ struct EXTRACTOR_Keywords * addExiv2Tag(const Exiv2::ExifData& exifData,
79 result = addKeyword(type, 79 result = addKeyword(type,
80 strdup(str), 80 strdup(str),
81 result); 81 result);
82 md++;
82 } 83 }
83 return result; 84 return result;
84} 85}
85 86
86extern "C" {
87 87
88#if WORKAROUND_905 88struct EXTRACTOR_Keywords * addIptcData(const Exiv2::IptcData& iptcData,
89 static struct EXTRACTOR_Keywords * extract(const char * filename, 89 const std::string& key,
90 unsigned char * data, 90 EXTRACTOR_KeywordType type,
91 size_t size, 91 struct EXTRACTOR_Keywords * result)
92 struct EXTRACTOR_Keywords * prev) 92{
93#else 93 const char * str;
94 struct EXTRACTOR_Keywords * libextractor_exiv2_extract(const char * filename, 94
95 unsigned char * data, 95 Exiv2::IptcKey ek(key);
96 size_t size, 96 Exiv2::IptcData::const_iterator md = iptcData.findKey(ek);
97 struct EXTRACTOR_Keywords * prev) 97 while (md != iptcData.end())
98#endif 98 {
99 { 99 if (0 != strcmp (Exiv2::toString(md->key()).c_str(), key.c_str()))
100 struct EXTRACTOR_Keywords * result = prev; 100 break;
101 std::string ccstr = Exiv2::toString(*md);
102 str = ccstr.c_str();
103 while ( (strlen(str) > 0) && isspace(str[0])) str++;
104 if (strlen(str) > 0)
105 result = addKeyword(type,
106 strdup(str),
107 result);
108 md++;
109 }
110 return result;
111}
101 112
102 try {
103 113
104 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(data, size);
105 assert(image.get() != 0);
106 image->readMetadata();
107 Exiv2::ExifData &exifData = image->exifData();
108 if (exifData.empty()) return result;
109 114
110 // Camera make
111 result = addExiv2Tag(exifData,
112 "Exif.Image.Make",
113 EXTRACTOR_CAMERA_MAKE,
114 result);
115 115
116 // Camera model
117 result = addExiv2Tag(exifData,
118 "Exif.Image.Model",
119 EXTRACTOR_CAMERA_MODEL,
120 result);
121 116
122 // Camera model
123 result = addExiv2Tag(exifData,
124 "Exif.Image.Orientation",
125 EXTRACTOR_ORIENTATION,
126 result);
127 117
128 // Image Timestamp
129 result = addExiv2Tag(exifData,
130 "Exif.Photo.DateTimeOriginal",
131 EXTRACTOR_DATE,
132 result);
133 118
134 // Exposure time 119extern "C" {
135 // From ExposureTime, failing that, try ShutterSpeedValue 120
136 struct EXTRACTOR_Keywords * newResult; 121#if WORKAROUND_905
137 newResult = addExiv2Tag(exifData, 122 static struct EXTRACTOR_Keywords * extract(const char * filename,
138 "Exif.Photo.ExposureTime", 123 unsigned char * data,
139 EXTRACTOR_EXPOSURE, 124 size_t size,
140 result); 125 struct EXTRACTOR_Keywords * prev)
141 Exiv2::ExifData::const_iterator md; 126#else
142 if (newResult == result) { 127 struct EXTRACTOR_Keywords * libextractor_exiv2_extract(const char * filename,
143 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.ShutterSpeedValue")); 128 unsigned char * data,
144 if (md != exifData.end()) { 129 size_t size,
130 struct EXTRACTOR_Keywords * prev)
131#endif
132 {
133 struct EXTRACTOR_Keywords * result = prev;
134 try
135 {
136 Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(data, size);
137 assert(image.get() != 0);
138 image->readMetadata();
139 Exiv2::ExifData &exifData = image->exifData();
140 if (!exifData.empty())
141 {
142 // Camera make
143 result = addExiv2Tag(exifData,
144 "Exif.Image.Make",
145 EXTRACTOR_CAMERA_MAKE,
146 result);
147
148 // Camera model
149 result = addExiv2Tag(exifData,
150 "Exif.Image.Model",
151 EXTRACTOR_CAMERA_MODEL,
152 result);
153
154 // Camera model
155 result = addExiv2Tag(exifData,
156 "Exif.Image.Orientation",
157 EXTRACTOR_ORIENTATION,
158 result);
159
160 // Image Timestamp
161 result = addExiv2Tag(exifData,
162 "Exif.Photo.DateTimeOriginal",
163 EXTRACTOR_DATE,
164 result);
165
166 // Exposure time
167 // From ExposureTime, failing that, try ShutterSpeedValue
168 struct EXTRACTOR_Keywords * newResult;
169 newResult = addExiv2Tag(exifData,
170 "Exif.Photo.ExposureTime",
171 EXTRACTOR_EXPOSURE,
172 result);
173 Exiv2::ExifData::const_iterator md;
174 if (newResult == result) {
175 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.ShutterSpeedValue"));
176 if (md != exifData.end()) {
145 double tmp = exp(log(2.0) * md->toFloat()) + 0.5; 177 double tmp = exp(log(2.0) * md->toFloat()) + 0.5;
146 std::ostringstream os; 178 std::ostringstream os;
147 if (tmp > 1) { 179 if (tmp > 1) {
148 os << "1/" << static_cast<long>(tmp) << " s"; 180 os << "1/" << static_cast<long>(tmp) << " s";
149 } 181 }
150 else { 182 else {
151 os << static_cast<long>(1/tmp) << " s"; 183 os << static_cast<long>(1/tmp) << " s";
152 } 184 }
153 newResult = addKeyword(EXTRACTOR_EXPOSURE, 185 newResult = addKeyword(EXTRACTOR_EXPOSURE,
154 strdup(os.str().c_str()), 186 strdup(os.str().c_str()),
155 result); 187 result);
156 } 188 }
157 } 189 }
158 result = newResult; 190 result = newResult;
159 191
160 // Aperture 192 // Aperture
161 // Get if from FNumber and, failing that, try ApertureValue 193 // Get if from FNumber and, failing that, try ApertureValue
162 newResult = addExiv2Tag(exifData, 194 newResult = addExiv2Tag(exifData,
163 "Exif.Photo.FNumber", 195 "Exif.Photo.FNumber",
164 EXTRACTOR_APERTURE, 196 EXTRACTOR_APERTURE,
165 result); 197 result);
166 if (newResult == result) { 198 if (newResult == result) {
167 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.ApertureValue")); 199 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.ApertureValue"));
168 if (md != exifData.end()) { 200 if (md != exifData.end()) {
169 std::ostringstream os; 201 std::ostringstream os;
170 os << std::fixed << std::setprecision(1) 202 os << std::fixed << std::setprecision(1)
171 << "F" << exp(log(2.0) * md->toFloat() / 2); 203 << "F" << exp(log(2.0) * md->toFloat() / 2);
172 newResult = addKeyword(EXTRACTOR_APERTURE, 204 newResult = addKeyword(EXTRACTOR_APERTURE,
173 strdup(os.str().c_str()), 205 strdup(os.str().c_str()),
174 result); 206 result);
175 } 207 }
176 } 208 }
177 result = newResult; 209 result = newResult;
178 210
179 // Exposure bias 211 // Exposure bias
180 result = addExiv2Tag(exifData, 212 result = addExiv2Tag(exifData,
181 "Exif.Photo.ExposureBiasValue", 213 "Exif.Photo.ExposureBiasValue",
182 EXTRACTOR_EXPOSURE_BIAS, 214 EXTRACTOR_EXPOSURE_BIAS,
183 result); 215 result);
184 216
185 // Flash 217 // Flash
186 result = addExiv2Tag(exifData, 218 result = addExiv2Tag(exifData,
187 "Exif.Photo.Flash", 219 "Exif.Photo.Flash",
188 EXTRACTOR_FLASH, 220 EXTRACTOR_FLASH,
189 result); 221 result);
190 222
191 // Flash bias 223 // Flash bias
192 // Todo: Implement this for other cameras 224 // Todo: Implement this for other cameras
193 newResult = addExiv2Tag(exifData, 225 newResult = addExiv2Tag(exifData,
194 "Exif.CanonSi.FlashBias", 226 "Exif.CanonSi.FlashBias",
195 EXTRACTOR_FLASH_BIAS, 227 EXTRACTOR_FLASH_BIAS,
196 result); 228 result);
197 if (newResult == result) { 229 if (newResult == result) {
198 newResult = addExiv2Tag(exifData, 230 newResult = addExiv2Tag(exifData,
199 "Exif.Panasonic.FlashBias", 231 "Exif.Panasonic.FlashBias",
200 EXTRACTOR_FLASH_BIAS, 232 EXTRACTOR_FLASH_BIAS,
201 result); 233 result);
202 } 234 }
203 if (newResult == result) { 235 if (newResult == result) {
204 newResult = addExiv2Tag(exifData, 236 newResult = addExiv2Tag(exifData,
205 "Exif.Olympus.FlashBias", 237 "Exif.Olympus.FlashBias",
206 EXTRACTOR_FLASH_BIAS, 238 EXTRACTOR_FLASH_BIAS,
207 result); 239 result);
208 } 240 }
209 result = newResult; 241 result = newResult;
210 242
211 // Actual focal length and 35 mm equivalent 243 // Actual focal length and 35 mm equivalent
212 // Todo: Calculate 35 mm equivalent a la jhead 244 // Todo: Calculate 35 mm equivalent a la jhead
213 result = addExiv2Tag(exifData, 245 result = addExiv2Tag(exifData,
214 "Exif.Photo.FocalLength", 246 "Exif.Photo.FocalLength",
215 EXTRACTOR_FOCAL_LENGTH, 247 EXTRACTOR_FOCAL_LENGTH,
216 result); 248 result);
217 249
218 result = addExiv2Tag(exifData, 250 result = addExiv2Tag(exifData,
219 "Exif.Photo.FocalLengthIn35mmFilm", 251 "Exif.Photo.FocalLengthIn35mmFilm",
220 EXTRACTOR_FOCAL_LENGTH_35MM, 252 EXTRACTOR_FOCAL_LENGTH_35MM,
221 result); 253 result);
222 254
223 // ISO speed 255 // ISO speed
224 // from ISOSpeedRatings or the Makernote 256 // from ISOSpeedRatings or the Makernote
225 newResult = addExiv2Tag(exifData, 257 newResult = addExiv2Tag(exifData,
226 "Exif.Photo.ISOSpeedRatings", 258 "Exif.Photo.ISOSpeedRatings",
227 EXTRACTOR_ISO_SPEED, 259 EXTRACTOR_ISO_SPEED,
228 result); 260 result);
229 if (newResult == result) { 261 if (newResult == result) {
230 newResult = addExiv2Tag(exifData, 262 newResult = addExiv2Tag(exifData,
231 "Exif.CanonSi.ISOSpeed", 263 "Exif.CanonSi.ISOSpeed",
232 EXTRACTOR_ISO_SPEED, 264 EXTRACTOR_ISO_SPEED,
233 result); 265 result);
234 } 266 }
235 if (newResult == result) { 267 if (newResult == result) {
236 newResult = addExiv2Tag(exifData, 268 newResult = addExiv2Tag(exifData,
237 "Exif.Nikon1.ISOSpeed", 269 "Exif.Nikon1.ISOSpeed",
238 EXTRACTOR_ISO_SPEED, 270 EXTRACTOR_ISO_SPEED,
239 result); 271 result);
240 } 272 }
241 if (newResult == result) { 273 if (newResult == result) {
242 newResult = addExiv2Tag(exifData, 274 newResult = addExiv2Tag(exifData,
243 "Exif.Nikon2.ISOSpeed", 275 "Exif.Nikon2.ISOSpeed",
244 EXTRACTOR_ISO_SPEED, 276 EXTRACTOR_ISO_SPEED,
245 result); 277 result);
246 } 278 }
247 if (newResult == result) { 279 if (newResult == result) {
248 newResult = addExiv2Tag(exifData, 280 newResult = addExiv2Tag(exifData,
249 "Exif.Nikon3.ISOSpeed", 281 "Exif.Nikon3.ISOSpeed",
250 EXTRACTOR_ISO_SPEED, 282 EXTRACTOR_ISO_SPEED,
251 result); 283 result);
252 } 284 }
253 result = newResult; 285 result = newResult;
254 286
255 // Exposure mode 287 // Exposure mode
256 // From ExposureProgram or Canon Makernote 288 // From ExposureProgram or Canon Makernote
257 newResult = addExiv2Tag(exifData, 289 newResult = addExiv2Tag(exifData,
258 "Exif.Photo.ExposureProgram", 290 "Exif.Photo.ExposureProgram",
259 EXTRACTOR_EXPOSURE_MODE, 291 EXTRACTOR_EXPOSURE_MODE,
260 result); 292 result);
261 if (newResult == result) { 293 if (newResult == result) {
262 newResult = addExiv2Tag(exifData, 294 newResult = addExiv2Tag(exifData,
263 "Exif.CanonCs.ExposureProgram", 295 "Exif.CanonCs.ExposureProgram",
264 EXTRACTOR_EXPOSURE_MODE, 296 EXTRACTOR_EXPOSURE_MODE,
265 result); 297 result);
266 } 298 }
267 result = newResult; 299 result = newResult;
268 300
269 // Metering mode 301 // Metering mode
270 result = addExiv2Tag(exifData, 302 result = addExiv2Tag(exifData,
271 "Exif.Photo.MeteringMode", 303 "Exif.Photo.MeteringMode",
272 EXTRACTOR_METERING_MODE, 304 EXTRACTOR_METERING_MODE,
273 result); 305 result);
274 306
275 // Macro mode 307 // Macro mode
276 // Todo: Implement this for other cameras 308 // Todo: Implement this for other cameras
277 newResult = addExiv2Tag(exifData, 309 newResult = addExiv2Tag(exifData,
278 "Exif.CanonCs.Macro", 310 "Exif.CanonCs.Macro",
279 EXTRACTOR_MACRO_MODE, 311 EXTRACTOR_MACRO_MODE,
280 result); 312 result);
281 if (newResult == result) { 313 if (newResult == result) {
282 newResult = addExiv2Tag(exifData, 314 newResult = addExiv2Tag(exifData,
283 "Exif.Fujifilm.Macro", 315 "Exif.Fujifilm.Macro",
284 EXTRACTOR_MACRO_MODE, 316 EXTRACTOR_MACRO_MODE,
285 result); 317 result);
286 } 318 }
287 if (newResult == result) { 319 if (newResult == result) {
288 newResult = addExiv2Tag(exifData, 320 newResult = addExiv2Tag(exifData,
289 "Exif.Olympus.Macro", 321 "Exif.Olympus.Macro",
290 EXTRACTOR_MACRO_MODE, 322 EXTRACTOR_MACRO_MODE,
291 result); 323 result);
292 } 324 }
293 if (newResult == result) { 325 if (newResult == result) {
294 newResult = addExiv2Tag(exifData, 326 newResult = addExiv2Tag(exifData,
295 "Exif.Panasonic.Macro", 327 "Exif.Panasonic.Macro",
296 EXTRACTOR_MACRO_MODE, 328 EXTRACTOR_MACRO_MODE,
297 result); 329 result);
298 } 330 }
299 result = newResult; 331 result = newResult;
332
333 // Image quality setting (compression)
334 // Todo: Implement this for other cameras
335 newResult = addExiv2Tag(exifData,
336 "Exif.CanonCs.Quality",
337 EXTRACTOR_IMAGE_QUALITY,
338 result);
339 if (newResult == result) {
340 newResult = addExiv2Tag(exifData,
341 "Exif.Fujifilm.Quality",
342 EXTRACTOR_IMAGE_QUALITY,
343 result);
344 }
345 if (newResult == result) {
346 newResult = addExiv2Tag(exifData,
347 "Exif.Sigma.Quality",
348 EXTRACTOR_IMAGE_QUALITY,
349 result);
350 }
351 if (newResult == result) {
352 newResult = addExiv2Tag(exifData,
353 "Exif.Nikon1.Quality",
354 EXTRACTOR_IMAGE_QUALITY,
355 result);
356 }
357 if (newResult == result) {
358 newResult = addExiv2Tag(exifData,
359 "Exif.Nikon2.Quality",
360 EXTRACTOR_IMAGE_QUALITY,
361 result);
362 }
363 if (newResult == result) {
364 newResult = addExiv2Tag(exifData,
365 "Exif.Nikon3.Quality",
366 EXTRACTOR_IMAGE_QUALITY,
367 result);
368 }
369 if (newResult == result) {
370 newResult = addExiv2Tag(exifData,
371 "Exif.Olympus.Quality",
372 EXTRACTOR_IMAGE_QUALITY,
373 result);
374 }
375 if (newResult == result) {
376 newResult = addExiv2Tag(exifData,
377 "Exif.Panasonic.Quality",
378 EXTRACTOR_IMAGE_QUALITY,
379 result);
380 }
381 result = newResult;
382
383
384 /* this can sometimes be wrong (corrupt exiv2 data?).
385 Either way, we should get the data directly from
386 the specific file format parser (i.e. jpeg, tiff). */
387 // Exif Resolution
388 unsigned long xdim = 0;
389 unsigned long ydim = 0;
390 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
391 if (md != exifData.end()) xdim = md->toLong();
392 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
393 if (md != exifData.end()) ydim = md->toLong();
394 if (xdim != 0 && ydim != 0) {
395 std::ostringstream os;
396 os << xdim << "x" << ydim;
397 result = addKeyword(EXTRACTOR_SIZE,
398 strdup(os.str().c_str()),
399 result);
400 }
401 // White balance
402 // Todo: Implement this for other cameras
403
404 newResult = addExiv2Tag(exifData,
405 "Exif.CanonSi.WhiteBalance",
406 EXTRACTOR_WHITE_BALANCE,
407 result);
408 if (newResult == result) {
409 newResult = addExiv2Tag(exifData,
410 "Exif.Fujifilm.WhiteBalance",
411 EXTRACTOR_WHITE_BALANCE,
412 result);
413 }
414 if (newResult == result) {
415 newResult = addExiv2Tag(exifData,
416 "Exif.Sigma.WhiteBalance",
417 EXTRACTOR_WHITE_BALANCE,
418 result);
419 }
420 if (newResult == result) {
421 newResult = addExiv2Tag(exifData,
422 "Exif.Nikon1.WhiteBalance",
423 EXTRACTOR_WHITE_BALANCE,
424 result);
425 }
426 if (newResult == result) {
427 newResult = addExiv2Tag(exifData,
428 "Exif.Nikon2.WhiteBalance",
429 EXTRACTOR_WHITE_BALANCE,
430 result);
431 }
432 if (newResult == result) {
433 newResult = addExiv2Tag(exifData,
434 "Exif.Nikon3.WhiteBalance",
435 EXTRACTOR_WHITE_BALANCE,
436 result);
437 }
438 if (newResult == result) {
439 newResult = addExiv2Tag(exifData,
440 "Exif.Olympus.WhiteBalance",
441 EXTRACTOR_WHITE_BALANCE,
442 result);
443 }
444 if (newResult == result) {
445 newResult = addExiv2Tag(exifData,
446 "Exif.Panasonic.WhiteBalance",
447 EXTRACTOR_WHITE_BALANCE,
448 result);
449 }
450 result = newResult;
451
452 // Copyright
453 result = addExiv2Tag(exifData,
454 "Exif.Image.Copyright",
455 EXTRACTOR_COPYRIGHT,
456 result);
457
458 // Exif Comment
459 result = addExiv2Tag(exifData,
460 "Exif.Photo.UserComment",
461 EXTRACTOR_COMMENT,
462 result);
463 // GPS
464 result = addExiv2Tag(exifData,
465 "Exif.GPSInfo.GPSLatitudeRef",
466 EXTRACTOR_GPS_LATITUDE_REF,
467 result);
468 result = addExiv2Tag(exifData,
469 "Exif.GPSInfo.GPSLatitude",
470 EXTRACTOR_GPS_LATITUDE,
471 result);
472 result = addExiv2Tag(exifData,
473 "Exif.GPSInfo.GPSLongitudeRef",
474 EXTRACTOR_GPS_LONGITUDE_REF,
475 result);
476 result = addExiv2Tag(exifData,
477 "Exif.GPSInfo.GPSLongitude",
478 EXTRACTOR_GPS_LONGITUDE,
479 result);
480 }
481
482 Exiv2::IptcData &iptcData = image->iptcData();
483 if (! iptcData.empty()) {
484 result = addIptcData (iptcData,
485 "Iptc.Application2.Keywords",
486 EXTRACTOR_KEYWORDS,
487 result);
488 result = addIptcData (iptcData,
489 "Iptc.Application2.City",
490 EXTRACTOR_LOCATION_CITY,
491 result);
492 result = addIptcData (iptcData,
493 "Iptc.Application2.SubLocation",
494 EXTRACTOR_LOCATION_SUBLOCATION,
495 result);
496 result = addIptcData (iptcData,
497 "Iptc.Application2.CountryName",
498 EXTRACTOR_LOCATION_COUNTRY,
499 result);
500
501 }
300 502
301 // Image quality setting (compression) 503
302 // Todo: Implement this for other cameras 504 }
303 newResult = addExiv2Tag(exifData, 505 catch (const Exiv2::AnyError& e) {
304 "Exif.CanonCs.Quality",
305 EXTRACTOR_IMAGE_QUALITY,
306 result);
307 if (newResult == result) {
308 newResult = addExiv2Tag(exifData,
309 "Exif.Fujifilm.Quality",
310 EXTRACTOR_IMAGE_QUALITY,
311 result);
312 }
313 if (newResult == result) {
314 newResult = addExiv2Tag(exifData,
315 "Exif.Sigma.Quality",
316 EXTRACTOR_IMAGE_QUALITY,
317 result);
318 }
319 if (newResult == result) {
320 newResult = addExiv2Tag(exifData,
321 "Exif.Nikon1.Quality",
322 EXTRACTOR_IMAGE_QUALITY,
323 result);
324 }
325 if (newResult == result) {
326 newResult = addExiv2Tag(exifData,
327 "Exif.Nikon2.Quality",
328 EXTRACTOR_IMAGE_QUALITY,
329 result);
330 }
331 if (newResult == result) {
332 newResult = addExiv2Tag(exifData,
333 "Exif.Nikon3.Quality",
334 EXTRACTOR_IMAGE_QUALITY,
335 result);
336 }
337 if (newResult == result) {
338 newResult = addExiv2Tag(exifData,
339 "Exif.Olympus.Quality",
340 EXTRACTOR_IMAGE_QUALITY,
341 result);
342 }
343 if (newResult == result) {
344 newResult = addExiv2Tag(exifData,
345 "Exif.Panasonic.Quality",
346 EXTRACTOR_IMAGE_QUALITY,
347 result);
348 }
349 result = newResult;
350
351 /* this can sometimes be wrong (corrupt exiv2 data?).
352 Either way, we should get the data directly from
353 the specific file format parser (i.e. jpeg, tiff). */
354 // Exif Resolution
355 unsigned long xdim = 0;
356 unsigned long ydim = 0;
357 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
358 if (md != exifData.end()) xdim = md->toLong();
359 md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
360 if (md != exifData.end()) ydim = md->toLong();
361 if (xdim != 0 && ydim != 0) {
362 std::ostringstream os;
363 os << xdim << "x" << ydim;
364 result = addKeyword(EXTRACTOR_SIZE,
365 strdup(os.str().c_str()),
366 result);
367 }
368 // White balance
369 // Todo: Implement this for other cameras
370
371 newResult = addExiv2Tag(exifData,
372 "Exif.CanonSi.WhiteBalance",
373 EXTRACTOR_WHITE_BALANCE,
374 result);
375 if (newResult == result) {
376 newResult = addExiv2Tag(exifData,
377 "Exif.Fujifilm.WhiteBalance",
378 EXTRACTOR_WHITE_BALANCE,
379 result);
380 }
381 if (newResult == result) {
382 newResult = addExiv2Tag(exifData,
383 "Exif.Sigma.WhiteBalance",
384 EXTRACTOR_WHITE_BALANCE,
385 result);
386 }
387 if (newResult == result) {
388 newResult = addExiv2Tag(exifData,
389 "Exif.Nikon1.WhiteBalance",
390 EXTRACTOR_WHITE_BALANCE,
391 result);
392 }
393 if (newResult == result) {
394 newResult = addExiv2Tag(exifData,
395 "Exif.Nikon2.WhiteBalance",
396 EXTRACTOR_WHITE_BALANCE,
397 result);
398 }
399 if (newResult == result) {
400 newResult = addExiv2Tag(exifData,
401 "Exif.Nikon3.WhiteBalance",
402 EXTRACTOR_WHITE_BALANCE,
403 result);
404 }
405 if (newResult == result) {
406 newResult = addExiv2Tag(exifData,
407 "Exif.Olympus.WhiteBalance",
408 EXTRACTOR_WHITE_BALANCE,
409 result);
410 }
411 if (newResult == result) {
412 newResult = addExiv2Tag(exifData,
413 "Exif.Panasonic.WhiteBalance",
414 EXTRACTOR_WHITE_BALANCE,
415 result);
416 }
417 result = newResult;
418
419 // Copyright
420 result = addExiv2Tag(exifData,
421 "Exif.Image.Copyright",
422 EXTRACTOR_COPYRIGHT,
423 result);
424
425 // Exif Comment
426 result = addExiv2Tag(exifData,
427 "Exif.Photo.UserComment",
428 EXTRACTOR_COMMENT,
429 result);
430 }
431 catch (const Exiv2::AnyError& e) {
432#ifndef SUPPRESS_WARNINGS 506#ifndef SUPPRESS_WARNINGS
433 std::cout << "Caught Exiv2 exception '" << e << "'\n"; 507 std::cout << "Caught Exiv2 exception '" << e << "'\n";
434#endif 508#endif
435 }
436
437 return result;
438 } 509 }
439 510
511 return result;
512 }
440 513
441 514
442#if WORKAROUND_905 515#if WORKAROUND_905
443
444 struct X { 516 struct X {
445 unsigned char * data; 517 unsigned char * data;
446 size_t size; 518 size_t size;
@@ -470,5 +542,4 @@ extern "C" {
470 } 542 }
471 543
472#endif 544#endif
473
474} 545}