diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/include/extractor.h | 9 | ||||
-rw-r--r-- | src/main/extractor.c | 13 | ||||
-rw-r--r-- | src/plugins/exiv2/exiv2extractor.cc | 729 |
4 files changed, 421 insertions, 333 deletions
@@ -1,3 +1,6 @@ | |||
1 | Sat Dec 5 11:32:30 CET 2009 | ||
2 | Adding extraction of Iptc data using exiv2. | ||
3 | |||
1 | Sat Jul 4 23:05:22 CEST 2009 | 4 | Sat 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 | ||
86 | extern "C" { | ||
87 | 87 | ||
88 | #if WORKAROUND_905 | 88 | struct 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 | 119 | extern "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 | } |