/src/libexif/libexif/exif-entry.c
Line | Count | Source |
1 | | /* exif-entry.c |
2 | | * |
3 | | * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net> |
4 | | * |
5 | | * This library is free software; you can redistribute it and/or |
6 | | * modify it under the terms of the GNU Lesser General Public |
7 | | * License as published by the Free Software Foundation; either |
8 | | * version 2 of the License, or (at your option) any later version. |
9 | | * |
10 | | * This library is distributed in the hope that it will be useful, |
11 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | | * Lesser General Public License for more details. |
14 | | * |
15 | | * You should have received a copy of the GNU Lesser General Public |
16 | | * License along with this library; if not, write to the |
17 | | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | | * Boston, MA 02110-1301 USA. |
19 | | * |
20 | | * SPDX-License-Identifier: LGPL-2.0-or-later |
21 | | */ |
22 | | |
23 | | #include <config.h> |
24 | | |
25 | | #include <libexif/exif-entry.h> |
26 | | #include <libexif/exif-ifd.h> |
27 | | #include <libexif/exif-utils.h> |
28 | | #include <libexif/i18n.h> |
29 | | |
30 | | #include <libexif/exif-gps-ifd.h> |
31 | | |
32 | | #include <ctype.h> |
33 | | #include <stdlib.h> |
34 | | #include <stdio.h> |
35 | | #include <string.h> |
36 | | #include <time.h> |
37 | | #include <math.h> |
38 | | |
39 | | #ifndef M_PI |
40 | | #define M_PI 3.14159265358979323846 |
41 | | #endif |
42 | | |
43 | | struct _ExifEntryPrivate |
44 | | { |
45 | | unsigned int ref_count; |
46 | | |
47 | | ExifMem *mem; |
48 | | }; |
49 | | |
50 | | /* This function is hidden in exif-data.c */ |
51 | | ExifLog *exif_data_get_log (ExifData *); |
52 | | |
53 | | #ifndef NO_VERBOSE_TAG_STRINGS |
54 | | static void |
55 | | exif_entry_log (ExifEntry *e, ExifLogCode code, const char *format, ...) |
56 | 117k | { |
57 | 117k | va_list args; |
58 | 117k | ExifLog *l = NULL; |
59 | | |
60 | 117k | if (e && e->parent && e->parent->parent) |
61 | 117k | l = exif_data_get_log (e->parent->parent); |
62 | 117k | va_start (args, format); |
63 | 117k | exif_logv (l, code, "ExifEntry", format, args); |
64 | 117k | va_end (args); |
65 | 117k | } |
66 | | #else |
67 | | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L |
68 | | #define exif_entry_log(...) do { } while (0) |
69 | | #elif defined(__GNUC__) |
70 | | #define exif_entry_log(x...) do { } while (0) |
71 | | #else |
72 | | #define exif_entry_log (void) |
73 | | #endif |
74 | | #endif |
75 | | |
76 | | static void * |
77 | | exif_entry_alloc (ExifEntry *e, unsigned int i) |
78 | 121k | { |
79 | 121k | void *d; |
80 | 121k | ExifLog *l = NULL; |
81 | | |
82 | 121k | if (!e || !e->priv || !i) return NULL; |
83 | | |
84 | 121k | d = exif_mem_alloc (e->priv->mem, i); |
85 | 121k | if (d) return d; |
86 | | |
87 | 0 | if (e->parent && e->parent->parent) |
88 | 0 | l = exif_data_get_log (e->parent->parent); |
89 | 0 | EXIF_LOG_NO_MEMORY (l, "ExifEntry", i); |
90 | 0 | return NULL; |
91 | 121k | } |
92 | | |
93 | | static void * |
94 | | exif_entry_realloc (ExifEntry *e, void *d_orig, unsigned int i) |
95 | 305 | { |
96 | 305 | void *d; |
97 | 305 | ExifLog *l = NULL; |
98 | | |
99 | 305 | if (!e || !e->priv) return NULL; |
100 | | |
101 | 305 | if (!i) { exif_mem_free (e->priv->mem, d_orig); return NULL; } |
102 | | |
103 | 305 | d = exif_mem_realloc (e->priv->mem, d_orig, i); |
104 | 305 | if (d) return d; |
105 | | |
106 | 0 | if (e->parent && e->parent->parent) |
107 | 0 | l = exif_data_get_log (e->parent->parent); |
108 | 0 | EXIF_LOG_NO_MEMORY (l, "ExifEntry", i); |
109 | 0 | return NULL; |
110 | 305 | } |
111 | | |
112 | | ExifEntry * |
113 | | exif_entry_new (void) |
114 | 120k | { |
115 | 120k | ExifMem *mem = exif_mem_new_default (); |
116 | 120k | ExifEntry *e = exif_entry_new_mem (mem); |
117 | | |
118 | 120k | exif_mem_unref (mem); |
119 | | |
120 | 120k | return e; |
121 | 120k | } |
122 | | |
123 | | ExifEntry * |
124 | | exif_entry_new_mem (ExifMem *mem) |
125 | 824k | { |
126 | 824k | ExifEntry *e = NULL; |
127 | | |
128 | 824k | e = exif_mem_alloc (mem, sizeof (ExifEntry)); |
129 | 824k | if (!e) return NULL; |
130 | 824k | e->priv = exif_mem_alloc (mem, sizeof (ExifEntryPrivate)); |
131 | 824k | if (!e->priv) { exif_mem_free (mem, e); return NULL; } |
132 | 824k | e->priv->ref_count = 1; |
133 | | |
134 | 824k | e->priv->mem = mem; |
135 | 824k | exif_mem_ref (mem); |
136 | | |
137 | 824k | return e; |
138 | 824k | } |
139 | | |
140 | | void |
141 | | exif_entry_ref (ExifEntry *e) |
142 | 168k | { |
143 | 168k | if (!e) return; |
144 | | |
145 | 168k | e->priv->ref_count++; |
146 | 168k | } |
147 | | |
148 | | void |
149 | | exif_entry_unref (ExifEntry *e) |
150 | 993k | { |
151 | 993k | if (!e) return; |
152 | | |
153 | 993k | e->priv->ref_count--; |
154 | 993k | if (!e->priv->ref_count) |
155 | 824k | exif_entry_free (e); |
156 | 993k | } |
157 | | |
158 | | void |
159 | | exif_entry_free (ExifEntry *e) |
160 | 824k | { |
161 | 824k | if (!e) return; |
162 | | |
163 | 824k | if (e->priv) { |
164 | 824k | ExifMem *mem = e->priv->mem; |
165 | 824k | if (e->data) |
166 | 196k | exif_mem_free (mem, e->data); |
167 | 824k | exif_mem_free (mem, e->priv); |
168 | 824k | exif_mem_free (mem, e); |
169 | 824k | exif_mem_unref (mem); |
170 | 824k | } |
171 | 824k | } |
172 | | |
173 | | static void |
174 | | clear_entry (ExifEntry *e) |
175 | 0 | { |
176 | 0 | e->components = 0; |
177 | 0 | e->size = 0; |
178 | 0 | } |
179 | | |
180 | | /*! Get a value and convert it to an ExifShort. |
181 | | * \bug Not all types are converted that could be converted and no indication |
182 | | * is made when that occurs |
183 | | */ |
184 | | static inline ExifShort |
185 | | exif_get_short_convert (const unsigned char *buf, ExifFormat format, |
186 | | ExifByteOrder order) |
187 | 498k | { |
188 | 498k | switch (format) { |
189 | 2.64k | case EXIF_FORMAT_LONG: |
190 | 2.64k | return (ExifShort) exif_get_long (buf, order); |
191 | 690 | case EXIF_FORMAT_SLONG: |
192 | 690 | return (ExifShort) exif_get_slong (buf, order); |
193 | 0 | case EXIF_FORMAT_SHORT: |
194 | 0 | return (ExifShort) exif_get_short (buf, order); |
195 | 53.5k | case EXIF_FORMAT_SSHORT: |
196 | 53.5k | return (ExifShort) exif_get_sshort (buf, order); |
197 | 432k | case EXIF_FORMAT_BYTE: |
198 | 441k | case EXIF_FORMAT_SBYTE: |
199 | 441k | return (ExifShort) buf[0]; |
200 | 0 | default: |
201 | | /* Unsupported type */ |
202 | 0 | return (ExifShort) 0; |
203 | 498k | } |
204 | 498k | } |
205 | | |
206 | | void |
207 | | exif_entry_fix (ExifEntry *e) |
208 | 114k | { |
209 | 114k | unsigned int i, newsize; |
210 | 114k | unsigned char *newdata; |
211 | 114k | ExifByteOrder o; |
212 | 114k | ExifRational r; |
213 | 114k | ExifSRational sr; |
214 | | |
215 | 114k | if (!e || !e->priv) return; |
216 | | |
217 | 114k | switch (e->tag) { |
218 | | |
219 | | /* These tags all need to be of format SHORT. */ |
220 | 228 | case EXIF_TAG_YCBCR_SUB_SAMPLING: |
221 | 285 | case EXIF_TAG_SUBJECT_AREA: |
222 | 9.13k | case EXIF_TAG_COLOR_SPACE: |
223 | 9.28k | case EXIF_TAG_PLANAR_CONFIGURATION: |
224 | 9.31k | case EXIF_TAG_SENSING_METHOD: |
225 | 9.63k | case EXIF_TAG_ORIENTATION: |
226 | 9.96k | case EXIF_TAG_YCBCR_POSITIONING: |
227 | 10.0k | case EXIF_TAG_PHOTOMETRIC_INTERPRETATION: |
228 | 10.2k | case EXIF_TAG_CUSTOM_RENDERED: |
229 | 10.4k | case EXIF_TAG_EXPOSURE_MODE: |
230 | 10.6k | case EXIF_TAG_WHITE_BALANCE: |
231 | 10.7k | case EXIF_TAG_SCENE_CAPTURE_TYPE: |
232 | 10.8k | case EXIF_TAG_GAIN_CONTROL: |
233 | 11.0k | case EXIF_TAG_SATURATION: |
234 | 11.1k | case EXIF_TAG_CONTRAST: |
235 | 11.1k | case EXIF_TAG_SHARPNESS: |
236 | 11.3k | case EXIF_TAG_ISO_SPEED_RATINGS: |
237 | 11.3k | switch (e->format) { |
238 | 90 | case EXIF_FORMAT_LONG: |
239 | 156 | case EXIF_FORMAT_SLONG: |
240 | 415 | case EXIF_FORMAT_BYTE: |
241 | 594 | case EXIF_FORMAT_SBYTE: |
242 | 710 | case EXIF_FORMAT_SSHORT: |
243 | 710 | if (!e->parent || !e->parent->parent) break; |
244 | 710 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
245 | 710 | _("Tag '%s' was of format '%s' (which is " |
246 | 710 | "against specification) and has been " |
247 | 710 | "changed to format '%s'."), |
248 | 710 | exif_tag_get_name_in_ifd(e->tag, |
249 | 710 | exif_entry_get_ifd(e)), |
250 | 710 | exif_format_get_name (e->format), |
251 | 710 | exif_format_get_name (EXIF_FORMAT_SHORT)); |
252 | | |
253 | 710 | o = exif_data_get_byte_order (e->parent->parent); |
254 | 710 | newsize = e->components * exif_format_get_size (EXIF_FORMAT_SHORT); |
255 | 710 | newdata = exif_entry_alloc (e, newsize); |
256 | 710 | if (!newdata) { |
257 | 0 | exif_entry_log (e, EXIF_LOG_CODE_NO_MEMORY, |
258 | 0 | "Could not allocate %lu byte(s).", (unsigned long)newsize); |
259 | 0 | break; |
260 | 0 | } |
261 | | |
262 | 499k | for (i = 0; i < e->components; i++) |
263 | 498k | exif_set_short ( |
264 | 498k | newdata + i * |
265 | 498k | exif_format_get_size ( |
266 | 498k | EXIF_FORMAT_SHORT), o, |
267 | 498k | exif_get_short_convert ( |
268 | 498k | e->data + i * |
269 | 498k | exif_format_get_size (e->format), |
270 | 498k | e->format, o)); |
271 | | |
272 | 710 | exif_mem_free (e->priv->mem, e->data); |
273 | 710 | e->data = newdata; |
274 | 710 | e->size = newsize; |
275 | 710 | e->format = EXIF_FORMAT_SHORT; |
276 | 710 | break; |
277 | 10.3k | case EXIF_FORMAT_SHORT: |
278 | | /* No conversion necessary */ |
279 | 10.3k | break; |
280 | 283 | default: |
281 | 283 | exif_entry_log (e, EXIF_LOG_CODE_CORRUPT_DATA, |
282 | 283 | _("Tag '%s' is of format '%s' (which is " |
283 | 283 | "against specification) but cannot be changed " |
284 | 283 | "to format '%s'."), |
285 | 283 | exif_tag_get_name_in_ifd(e->tag, |
286 | 283 | exif_entry_get_ifd(e)), |
287 | 283 | exif_format_get_name (e->format), |
288 | 283 | exif_format_get_name (EXIF_FORMAT_SHORT)); |
289 | 283 | break; |
290 | 11.3k | } |
291 | 11.3k | break; |
292 | | |
293 | | /* All these tags need to be of format 'Rational'. */ |
294 | 11.3k | case EXIF_TAG_FNUMBER: |
295 | 835 | case EXIF_TAG_APERTURE_VALUE: |
296 | 1.16k | case EXIF_TAG_EXPOSURE_TIME: |
297 | 1.70k | case EXIF_TAG_FOCAL_LENGTH: |
298 | 1.70k | switch (e->format) { |
299 | 119 | case EXIF_FORMAT_SRATIONAL: |
300 | 119 | if (!e->parent || !e->parent->parent) break; |
301 | 119 | o = exif_data_get_byte_order (e->parent->parent); |
302 | 10.4k | for (i = 0; i < e->components; i++) { |
303 | 10.3k | sr = exif_get_srational (e->data + i * |
304 | 10.3k | exif_format_get_size ( |
305 | 10.3k | EXIF_FORMAT_SRATIONAL), o); |
306 | 10.3k | r.numerator = (ExifLong) sr.numerator; |
307 | 10.3k | r.denominator = (ExifLong) sr.denominator; |
308 | 10.3k | exif_set_rational (e->data + i * |
309 | 10.3k | exif_format_get_size ( |
310 | 10.3k | EXIF_FORMAT_RATIONAL), o, r); |
311 | 10.3k | } |
312 | 119 | e->format = EXIF_FORMAT_RATIONAL; |
313 | 119 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
314 | 119 | _("Tag '%s' was of format '%s' (which is " |
315 | 119 | "against specification) and has been " |
316 | 119 | "changed to format '%s'."), |
317 | 119 | exif_tag_get_name_in_ifd(e->tag, |
318 | 119 | exif_entry_get_ifd(e)), |
319 | 119 | exif_format_get_name (EXIF_FORMAT_SRATIONAL), |
320 | 119 | exif_format_get_name (EXIF_FORMAT_RATIONAL)); |
321 | 119 | break; |
322 | 1.59k | default: |
323 | 1.59k | break; |
324 | 1.70k | } |
325 | 1.70k | break; |
326 | | |
327 | | /* All these tags need to be of format 'SRational'. */ |
328 | 1.70k | case EXIF_TAG_EXPOSURE_BIAS_VALUE: |
329 | 966 | case EXIF_TAG_BRIGHTNESS_VALUE: |
330 | 1.52k | case EXIF_TAG_SHUTTER_SPEED_VALUE: |
331 | 1.52k | switch (e->format) { |
332 | 554 | case EXIF_FORMAT_RATIONAL: |
333 | 554 | if (!e->parent || !e->parent->parent) break; |
334 | 554 | o = exif_data_get_byte_order (e->parent->parent); |
335 | 25.7k | for (i = 0; i < e->components; i++) { |
336 | 25.2k | r = exif_get_rational (e->data + i * |
337 | 25.2k | exif_format_get_size ( |
338 | 25.2k | EXIF_FORMAT_RATIONAL), o); |
339 | 25.2k | sr.numerator = (ExifLong) r.numerator; |
340 | 25.2k | sr.denominator = (ExifLong) r.denominator; |
341 | 25.2k | exif_set_srational (e->data + i * |
342 | 25.2k | exif_format_get_size ( |
343 | 25.2k | EXIF_FORMAT_SRATIONAL), o, sr); |
344 | 25.2k | } |
345 | 554 | e->format = EXIF_FORMAT_SRATIONAL; |
346 | 554 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
347 | 554 | _("Tag '%s' was of format '%s' (which is " |
348 | 554 | "against specification) and has been " |
349 | 554 | "changed to format '%s'."), |
350 | 554 | exif_tag_get_name_in_ifd(e->tag, |
351 | 554 | exif_entry_get_ifd(e)), |
352 | 554 | exif_format_get_name (EXIF_FORMAT_RATIONAL), |
353 | 554 | exif_format_get_name (EXIF_FORMAT_SRATIONAL)); |
354 | 554 | break; |
355 | 968 | default: |
356 | 968 | break; |
357 | 1.52k | } |
358 | 1.52k | break; |
359 | | |
360 | 1.52k | case EXIF_TAG_USER_COMMENT: |
361 | | |
362 | | /* Format needs to be UNDEFINED. */ |
363 | 595 | if (e->format != EXIF_FORMAT_UNDEFINED) { |
364 | 209 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
365 | 209 | _("Tag 'UserComment' had invalid format '%s'. " |
366 | 209 | "Format has been set to 'undefined'."), |
367 | 209 | exif_format_get_name (e->format)); |
368 | 209 | e->format = EXIF_FORMAT_UNDEFINED; |
369 | 209 | } |
370 | | |
371 | | /* Some packages like Canon ZoomBrowser EX 4.5 store |
372 | | only one zero byte followed by 7 bytes of rubbish */ |
373 | 595 | if ((e->size >= 8) && (e->data[0] == 0)) { |
374 | 125 | memcpy(e->data, "\0\0\0\0\0\0\0\0", 8); |
375 | 125 | } |
376 | | |
377 | | /* There need to be at least 8 bytes. */ |
378 | 595 | if (e->size < 8) { |
379 | 22 | e->data = exif_entry_realloc (e, e->data, 8 + e->size); |
380 | 22 | if (!e->data) { |
381 | 0 | clear_entry(e); |
382 | 0 | return; |
383 | 0 | } |
384 | | |
385 | | /* Assume ASCII */ |
386 | 22 | memmove (e->data + 8, e->data, e->size); |
387 | 22 | memcpy (e->data, "ASCII\0\0\0", 8); |
388 | 22 | e->size += 8; |
389 | 22 | e->components += 8; |
390 | 22 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
391 | 22 | _("Tag 'UserComment' has been expanded to at " |
392 | 22 | "least 8 bytes in order to follow the " |
393 | 22 | "specification.")); |
394 | 22 | break; |
395 | 22 | } |
396 | | |
397 | | /* |
398 | | * If the first 8 bytes are empty and real data starts |
399 | | * afterwards, let's assume ASCII and claim the 8 first |
400 | | * bytes for the format specifyer. |
401 | | */ |
402 | 27.7k | for (i = 0; (i < e->size) && !e->data[i]; i++); |
403 | 1.16k | if (!i) for ( ; (i < e->size) && (e->data[i] == ' '); i++); |
404 | 573 | if ((i >= 8) && (i < e->size)) { |
405 | 115 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
406 | 115 | _("Tag 'UserComment' is not empty but does not " |
407 | 115 | "start with a format identifier. " |
408 | 115 | "This has been fixed.")); |
409 | 115 | memcpy (e->data, "ASCII\0\0\0", 8); |
410 | 115 | break; |
411 | 115 | } |
412 | | |
413 | | /* |
414 | | * First 8 bytes need to follow the specification. If they don't, |
415 | | * assume ASCII. |
416 | | */ |
417 | 458 | if (memcmp (e->data, "ASCII\0\0\0" , 8) && |
418 | 313 | memcmp (e->data, "UNICODE\0" , 8) && |
419 | 306 | memcmp (e->data, "JIS\0\0\0\0\0" , 8) && |
420 | 301 | memcmp (e->data, "\0\0\0\0\0\0\0\0", 8)) { |
421 | 283 | e->data = exif_entry_realloc (e, e->data, 8 + e->size); |
422 | 283 | if (!e->data) { |
423 | 0 | clear_entry(e); |
424 | 0 | break; |
425 | 0 | } |
426 | | |
427 | | /* Assume ASCII */ |
428 | 283 | memmove (e->data + 8, e->data, e->size); |
429 | 283 | memcpy (e->data, "ASCII\0\0\0", 8); |
430 | 283 | e->size += 8; |
431 | 283 | e->components += 8; |
432 | 283 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
433 | 283 | _("Tag 'UserComment' did not start with a " |
434 | 283 | "format identifier. This has been fixed.")); |
435 | 283 | break; |
436 | 283 | } |
437 | | |
438 | 175 | break; |
439 | 99.1k | default: |
440 | 99.1k | break; |
441 | 114k | } |
442 | 114k | } |
443 | | |
444 | | /*! Format the value of an ExifEntry for human display in a generic way. |
445 | | * The output is localized. The formatting is independent of the tag number |
446 | | * and is based entirely on the data type. |
447 | | * \pre The ExifEntry is already a member of an ExifData. |
448 | | * \param[in] e EXIF entry |
449 | | * \param[out] val buffer in which to store value |
450 | | * \param[in] maxlen the length of the buffer val |
451 | | */ |
452 | | static void |
453 | | exif_entry_format_value(ExifEntry *e, char *val, size_t maxlen) |
454 | 73.4k | { |
455 | 73.4k | ExifByte v_byte; |
456 | 73.4k | ExifShort v_short; |
457 | 73.4k | ExifSShort v_sshort; |
458 | 73.4k | ExifLong v_long; |
459 | 73.4k | ExifRational v_rat; |
460 | 73.4k | ExifSRational v_srat; |
461 | 73.4k | ExifSLong v_slong; |
462 | 73.4k | unsigned int i; |
463 | 73.4k | size_t len; |
464 | 73.4k | const ExifByteOrder o = exif_data_get_byte_order (e->parent->parent); |
465 | | |
466 | 73.4k | if (!e->size || !maxlen) |
467 | 0 | return; |
468 | 73.4k | switch (e->format) { |
469 | 4.43k | case EXIF_FORMAT_UNDEFINED: |
470 | 4.43k | snprintf (val, maxlen, _("%i bytes undefined data"), e->size); |
471 | 4.43k | break; |
472 | 4.52k | case EXIF_FORMAT_BYTE: |
473 | 7.47k | case EXIF_FORMAT_SBYTE: |
474 | 7.47k | v_byte = e->data[0]; |
475 | 7.47k | snprintf (val, maxlen, "0x%02x", v_byte); |
476 | 7.47k | len = strlen (val); |
477 | 267k | for (i = 1; i < e->components; i++) { |
478 | 259k | v_byte = e->data[i]; |
479 | 259k | snprintf (val+len, maxlen-len, ", 0x%02x", v_byte); |
480 | 259k | len += strlen (val+len); |
481 | 259k | if (len >= maxlen-1) break; |
482 | 259k | } |
483 | 7.47k | break; |
484 | 5.20k | case EXIF_FORMAT_SHORT: |
485 | 5.20k | v_short = exif_get_short (e->data, o); |
486 | 5.20k | snprintf (val, maxlen, "%u", v_short); |
487 | 5.20k | len = strlen (val); |
488 | 244k | for (i = 1; i < e->components; i++) { |
489 | 239k | v_short = exif_get_short (e->data + |
490 | 239k | exif_format_get_size (e->format) * i, o); |
491 | 239k | snprintf (val+len, maxlen-len, ", %u", v_short); |
492 | 239k | len += strlen (val+len); |
493 | 239k | if (len >= maxlen-1) break; |
494 | 239k | } |
495 | 5.20k | break; |
496 | 1.02k | case EXIF_FORMAT_SSHORT: |
497 | 1.02k | v_sshort = exif_get_sshort (e->data, o); |
498 | 1.02k | snprintf (val, maxlen, "%i", v_sshort); |
499 | 1.02k | len = strlen (val); |
500 | 98.7k | for (i = 1; i < e->components; i++) { |
501 | 97.8k | v_sshort = exif_get_short (e->data + |
502 | 97.8k | exif_format_get_size (e->format) * |
503 | 97.8k | i, o); |
504 | 97.8k | snprintf (val+len, maxlen-len, ", %i", v_sshort); |
505 | 97.8k | len += strlen (val+len); |
506 | 97.8k | if (len >= maxlen-1) break; |
507 | 97.8k | } |
508 | 1.02k | break; |
509 | 2.12k | case EXIF_FORMAT_LONG: |
510 | 2.12k | v_long = exif_get_long (e->data, o); |
511 | 2.12k | snprintf (val, maxlen, "%lu", (unsigned long) v_long); |
512 | 2.12k | len = strlen (val); |
513 | 104k | for (i = 1; i < e->components; i++) { |
514 | 102k | v_long = exif_get_long (e->data + |
515 | 102k | exif_format_get_size (e->format) * |
516 | 102k | i, o); |
517 | 102k | snprintf (val+len, maxlen-len, ", %lu", (unsigned long) v_long); |
518 | 102k | len += strlen (val+len); |
519 | 102k | if (len >= maxlen-1) break; |
520 | 102k | } |
521 | 2.12k | break; |
522 | 1.45k | case EXIF_FORMAT_SLONG: |
523 | 1.45k | v_slong = exif_get_slong (e->data, o); |
524 | 1.45k | snprintf (val, maxlen, "%li", (long) v_slong); |
525 | 1.45k | len = strlen (val); |
526 | 94.4k | for (i = 1; i < e->components; i++) { |
527 | 93.1k | v_slong = exif_get_slong (e->data + |
528 | 93.1k | exif_format_get_size (e->format) * i, o); |
529 | 93.1k | snprintf (val+len, maxlen-len, ", %li", (long) v_slong); |
530 | 93.1k | len += strlen (val+len); |
531 | 93.1k | if (len >= maxlen-1) break; |
532 | 93.1k | } |
533 | 1.45k | break; |
534 | 11.9k | case EXIF_FORMAT_ASCII: |
535 | 11.9k | strncpy (val, (char *) e->data, MIN (maxlen-1, e->size)); |
536 | 11.9k | val[MIN (maxlen-1, e->size)] = 0; |
537 | 11.9k | break; |
538 | 37.8k | case EXIF_FORMAT_RATIONAL: |
539 | 37.8k | len = 0; |
540 | 147k | for (i = 0; i < e->components; i++) { |
541 | 109k | if (i > 0) { |
542 | 71.9k | snprintf (val+len, maxlen-len, ", "); |
543 | 71.9k | len += strlen (val+len); |
544 | 71.9k | } |
545 | 109k | v_rat = exif_get_rational ( |
546 | 109k | e->data + 8 * i, o); |
547 | 109k | if (v_rat.denominator) { |
548 | | /* |
549 | | * Choose the number of significant digits to |
550 | | * display based on the size of the denominator. |
551 | | * It is scaled so that denominators within the |
552 | | * range 13..120 will show 2 decimal points. |
553 | | */ |
554 | 104k | int decimals = (int)(log10(v_rat.denominator)-0.08+1.0); |
555 | 104k | snprintf (val+len, maxlen-len, "%2.*f", |
556 | 104k | decimals, |
557 | 104k | (double) v_rat.numerator / |
558 | 104k | (double) v_rat.denominator); |
559 | 104k | } else |
560 | 5.72k | snprintf (val+len, maxlen-len, "%lu/%lu", |
561 | 5.72k | (unsigned long) v_rat.numerator, |
562 | 5.72k | (unsigned long) v_rat.denominator); |
563 | 109k | len += strlen (val+len); |
564 | 109k | if (len >= maxlen-1) break; |
565 | 109k | } |
566 | 37.8k | break; |
567 | 1.16k | case EXIF_FORMAT_SRATIONAL: |
568 | 1.16k | len = 0; |
569 | 60.3k | for (i = 0; i < e->components; i++) { |
570 | 59.3k | if (i > 0) { |
571 | 58.1k | snprintf (val+len, maxlen-len, ", "); |
572 | 58.1k | len += strlen (val+len); |
573 | 58.1k | } |
574 | 59.3k | v_srat = exif_get_srational ( |
575 | 59.3k | e->data + 8 * i, o); |
576 | 59.3k | if (v_srat.denominator && v_srat.denominator > INT32_MIN) { |
577 | 53.6k | int decimals = (int)(log10(abs(v_srat.denominator))-0.08+1.0); |
578 | 53.6k | snprintf (val+len, maxlen-len, "%2.*f", |
579 | 53.6k | decimals, |
580 | 53.6k | (double) v_srat.numerator / |
581 | 53.6k | (double) v_srat.denominator); |
582 | 53.6k | } else |
583 | 5.65k | snprintf (val+len, maxlen-len, "%li/%li", |
584 | 5.65k | (long) v_srat.numerator, |
585 | 5.65k | (long) v_srat.denominator); |
586 | 59.3k | len += strlen (val+len); |
587 | 59.3k | if (len >= maxlen-1) break; |
588 | 59.3k | } |
589 | 1.16k | break; |
590 | 226 | case EXIF_FORMAT_DOUBLE: |
591 | 822 | case EXIF_FORMAT_FLOAT: |
592 | 822 | default: |
593 | 822 | snprintf (val, maxlen, _("%i bytes unsupported data type"), |
594 | 822 | e->size); |
595 | 822 | break; |
596 | 73.4k | } |
597 | 73.4k | } |
598 | | |
599 | | void |
600 | | exif_entry_dump (ExifEntry *e, unsigned int indent) |
601 | 0 | { |
602 | 0 | char buf[1024]; |
603 | 0 | char value[1024]; |
604 | 0 | unsigned int l; |
605 | |
|
606 | 0 | if (!e) |
607 | 0 | return; |
608 | | |
609 | 0 | l = MIN(sizeof(buf)-1, 2*indent); |
610 | 0 | memset(buf, ' ', l); |
611 | 0 | buf[l] = '\0'; |
612 | |
|
613 | 0 | printf ("%sTag: 0x%x ('%s')\n", buf, e->tag, |
614 | 0 | exif_tag_get_name_in_ifd (e->tag, exif_entry_get_ifd(e))); |
615 | 0 | printf ("%s Format: %i ('%s')\n", buf, e->format, |
616 | 0 | exif_format_get_name (e->format)); |
617 | 0 | printf ("%s Components: %i\n", buf, (int) e->components); |
618 | 0 | printf ("%s Size: %i\n", buf, e->size); |
619 | 0 | printf ("%s Value: %s\n", buf, exif_entry_get_value (e, value, sizeof(value))); |
620 | 0 | } |
621 | | |
622 | | /*! Check if a string consists entirely of a single, repeated character. |
623 | | * Up to first n bytes are checked. |
624 | | * |
625 | | * \param[in] data pointer of string to check |
626 | | * \param[in] ch character to match |
627 | | * \param[in] n maximum number of characters to match |
628 | | * |
629 | | * \return 0 if the string matches or is of zero length, nonzero otherwise |
630 | | */ |
631 | | static int |
632 | | match_repeated_char(const unsigned char *data, unsigned char ch, size_t n) |
633 | 373 | { |
634 | 373 | int i; |
635 | 1.28k | for (i=n; i; --i, ++data) { |
636 | 1.22k | if (*data == 0) { |
637 | 92 | i = 0; /* all bytes before NUL matched */ |
638 | 92 | break; |
639 | 92 | } |
640 | 1.13k | if (*data != ch) |
641 | 229 | break; |
642 | 1.13k | } |
643 | 373 | return i; |
644 | 373 | } |
645 | | |
646 | 78.0k | #define CF(entry,target,v,maxlen) \ |
647 | 78.0k | { \ |
648 | 78.0k | if (entry->format != target) { \ |
649 | 1.44k | exif_entry_log (entry, EXIF_LOG_CODE_CORRUPT_DATA, \ |
650 | 1.44k | _("The tag '%s' contains data of an invalid " \ |
651 | 1.44k | "format ('%s', expected '%s')."), \ |
652 | 1.44k | exif_tag_get_name (entry->tag), \ |
653 | 1.44k | exif_format_get_name (entry->format), \ |
654 | 1.44k | exif_format_get_name (target)); \ |
655 | 1.44k | break; \ |
656 | 1.44k | } \ |
657 | 78.0k | } |
658 | | |
659 | 75.9k | #define CC(entry,target,v,maxlen) \ |
660 | 75.9k | { \ |
661 | 75.9k | if (entry->components != target) { \ |
662 | 1.00k | exif_entry_log (entry, EXIF_LOG_CODE_CORRUPT_DATA, \ |
663 | 1.00k | _("The tag '%s' contains an invalid number of " \ |
664 | 1.00k | "components (%i, expected %i)."), \ |
665 | 1.00k | exif_tag_get_name (entry->tag), \ |
666 | 1.00k | (int) entry->components, (int) target); \ |
667 | 1.00k | break; \ |
668 | 1.00k | } \ |
669 | 75.9k | } |
670 | | |
671 | | static const struct { |
672 | | ExifTag tag; |
673 | | const char *strings[10]; |
674 | | } list[] = { |
675 | | #ifndef NO_VERBOSE_TAG_DATA |
676 | | { EXIF_TAG_PLANAR_CONFIGURATION, |
677 | | { N_("Chunky format"), N_("Planar format"), NULL}}, |
678 | | { EXIF_TAG_SENSING_METHOD, |
679 | | { "", N_("Not defined"), N_("One-chip color area sensor"), |
680 | | N_("Two-chip color area sensor"), N_("Three-chip color area sensor"), |
681 | | N_("Color sequential area sensor"), "", N_("Trilinear sensor"), |
682 | | N_("Color sequential linear sensor"), NULL}}, |
683 | | { EXIF_TAG_ORIENTATION, |
684 | | { "", N_("Top-left"), N_("Top-right"), N_("Bottom-right"), |
685 | | N_("Bottom-left"), N_("Left-top"), N_("Right-top"), |
686 | | N_("Right-bottom"), N_("Left-bottom"), NULL}}, |
687 | | { EXIF_TAG_YCBCR_POSITIONING, |
688 | | { "", N_("Centered"), N_("Co-sited"), NULL}}, |
689 | | { EXIF_TAG_PHOTOMETRIC_INTERPRETATION, |
690 | | { N_("Reversed mono"), N_("Normal mono"), N_("RGB"), N_("Palette"), "", |
691 | | N_("CMYK"), N_("YCbCr"), "", N_("CieLAB"), NULL}}, |
692 | | { EXIF_TAG_CUSTOM_RENDERED, |
693 | | { N_("Normal process"), N_("Custom process"), NULL}}, |
694 | | { EXIF_TAG_EXPOSURE_MODE, |
695 | | { N_("Auto exposure"), N_("Manual exposure"), N_("Auto bracket"), NULL}}, |
696 | | { EXIF_TAG_WHITE_BALANCE, |
697 | | { N_("Auto white balance"), N_("Manual white balance"), NULL}}, |
698 | | { EXIF_TAG_SCENE_CAPTURE_TYPE, |
699 | | { N_("Standard"), N_("Landscape"), N_("Portrait"), |
700 | | N_("Night scene"), NULL}}, |
701 | | { EXIF_TAG_GAIN_CONTROL, |
702 | | { N_("Normal"), N_("Low gain up"), N_("High gain up"), |
703 | | N_("Low gain down"), N_("High gain down"), NULL}}, |
704 | | { EXIF_TAG_SATURATION, |
705 | | { N_("Normal"), N_("Low saturation"), N_("High saturation"), NULL}}, |
706 | | { EXIF_TAG_CONTRAST , {N_("Normal"), N_("Soft"), N_("Hard"), NULL}}, |
707 | | { EXIF_TAG_SHARPNESS, {N_("Normal"), N_("Soft"), N_("Hard"), NULL}}, |
708 | | #endif |
709 | | { 0, {NULL}} |
710 | | }; |
711 | | |
712 | | static const struct { |
713 | | ExifTag tag; |
714 | | struct { |
715 | | ExifShort index; |
716 | | const char *values[4]; /*!< list of progressively shorter string |
717 | | descriptions; the longest one that fits will be |
718 | | selected */ |
719 | | } elem[25]; |
720 | | } list2[] = { |
721 | | #ifndef NO_VERBOSE_TAG_DATA |
722 | | { EXIF_TAG_METERING_MODE, |
723 | | { { 0, {N_("Unknown"), NULL}}, |
724 | | { 1, {N_("Average"), N_("Avg"), NULL}}, |
725 | | { 2, {N_("Center-weighted average"), N_("Center-weight"), NULL}}, |
726 | | { 3, {N_("Spot"), NULL}}, |
727 | | { 4, {N_("Multi spot"), NULL}}, |
728 | | { 5, {N_("Pattern"), NULL}}, |
729 | | { 6, {N_("Partial"), NULL}}, |
730 | | {255, {N_("Other"), NULL}}, |
731 | | { 0, {NULL}}}}, |
732 | | { EXIF_TAG_COMPRESSION, |
733 | | { {1, {N_("Uncompressed"), NULL}}, |
734 | | {5, {N_("LZW compression"), NULL}}, |
735 | | {6, {N_("JPEG compression"), NULL}}, |
736 | | {7, {N_("JPEG compression"), NULL}}, |
737 | | {8, {N_("Deflate/ZIP compression"), NULL}}, |
738 | | {32773, {N_("PackBits compression"), NULL}}, |
739 | | {0, {NULL}}}}, |
740 | | { EXIF_TAG_LIGHT_SOURCE, |
741 | | { { 0, {N_("Unknown"), NULL}}, |
742 | | { 1, {N_("Daylight"), NULL}}, |
743 | | { 2, {N_("Fluorescent"), NULL}}, |
744 | | { 3, {N_("Tungsten incandescent light"), N_("Tungsten"), NULL}}, |
745 | | { 4, {N_("Flash"), NULL}}, |
746 | | { 9, {N_("Fine weather"), NULL}}, |
747 | | { 10, {N_("Cloudy weather"), N_("Cloudy"), NULL}}, |
748 | | { 11, {N_("Shade"), NULL}}, |
749 | | { 12, {N_("Daylight fluorescent"), NULL}}, |
750 | | { 13, {N_("Day white fluorescent"), NULL}}, |
751 | | { 14, {N_("Cool white fluorescent"), NULL}}, |
752 | | { 15, {N_("White fluorescent"), NULL}}, |
753 | | { 17, {N_("Standard light A"), NULL}}, |
754 | | { 18, {N_("Standard light B"), NULL}}, |
755 | | { 19, {N_("Standard light C"), NULL}}, |
756 | | { 20, {N_("D55"), NULL}}, |
757 | | { 21, {N_("D65"), NULL}}, |
758 | | { 22, {N_("D75"), NULL}}, |
759 | | { 24, {N_("ISO studio tungsten"),NULL}}, |
760 | | {255, {N_("Other"), NULL}}, |
761 | | { 0, {NULL}}}}, |
762 | | { EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, |
763 | | { {2, {N_("Inch"), N_("in"), NULL}}, |
764 | | {3, {N_("Centimeter"), N_("cm"), NULL}}, |
765 | | {0, {NULL}}}}, |
766 | | { EXIF_TAG_RESOLUTION_UNIT, |
767 | | { {2, {N_("Inch"), N_("in"), NULL}}, |
768 | | {3, {N_("Centimeter"), N_("cm"), NULL}}, |
769 | | {0, {NULL}}}}, |
770 | | { EXIF_TAG_EXPOSURE_PROGRAM, |
771 | | { {0, {N_("Not defined"), NULL}}, |
772 | | {1, {N_("Manual"), NULL}}, |
773 | | {2, {N_("Normal program"), N_("Normal"), NULL}}, |
774 | | {3, {N_("Aperture priority"), N_("Aperture"), NULL}}, |
775 | | {4, {N_("Shutter priority"),N_("Shutter"), NULL}}, |
776 | | {5, {N_("Creative program (biased toward depth of field)"), |
777 | | N_("Creative"), NULL}}, |
778 | | {6, {N_("Creative program (biased toward fast shutter speed)"), |
779 | | N_("Action"), NULL}}, |
780 | | {7, {N_("Portrait mode (for closeup photos with the background out " |
781 | | "of focus)"), N_("Portrait"), NULL}}, |
782 | | {8, {N_("Landscape mode (for landscape photos with the background " |
783 | | "in focus)"), N_("Landscape"), NULL}}, |
784 | | {0, {NULL}}}}, |
785 | | { EXIF_TAG_SENSITIVITY_TYPE, |
786 | | { {0, {N_("Unknown"), NULL}}, |
787 | | {1, {N_("Standard output sensitivity (SOS)"), NULL}}, |
788 | | {2, {N_("Recommended exposure index (REI)"), NULL}}, |
789 | | {3, {N_("ISO speed"), NULL}}, |
790 | | {4, {N_("Standard output sensitivity (SOS) and recommended exposure index (REI)"), NULL}}, |
791 | | {5, {N_("Standard output sensitivity (SOS) and ISO speed"), NULL}}, |
792 | | {6, {N_("Recommended exposure index (REI) and ISO speed"), NULL}}, |
793 | | {7, {N_("Standard output sensitivity (SOS) and recommended exposure index (REI) and ISO speed"), NULL}}, |
794 | | {0, {NULL}}}}, |
795 | | { EXIF_TAG_FLASH, |
796 | | { {0x0000, {N_("Flash did not fire"), N_("No flash"), NULL}}, |
797 | | {0x0001, {N_("Flash fired"), N_("Flash"), N_("Yes"), NULL}}, |
798 | | {0x0005, {N_("Strobe return light not detected"), N_("Without strobe"), |
799 | | NULL}}, |
800 | | {0x0007, {N_("Strobe return light detected"), N_("With strobe"), NULL}}, |
801 | | {0x0008, {N_("Flash did not fire"), NULL}}, /* Olympus E-330 */ |
802 | | {0x0009, {N_("Flash fired, compulsory flash mode"), NULL}}, |
803 | | {0x000d, {N_("Flash fired, compulsory flash mode, return light " |
804 | | "not detected"), NULL}}, |
805 | | {0x000f, {N_("Flash fired, compulsory flash mode, return light " |
806 | | "detected"), NULL}}, |
807 | | {0x0010, {N_("Flash did not fire, compulsory flash mode"), NULL}}, |
808 | | {0x0018, {N_("Flash did not fire, auto mode"), NULL}}, |
809 | | {0x0019, {N_("Flash fired, auto mode"), NULL}}, |
810 | | {0x001d, {N_("Flash fired, auto mode, return light not detected"), |
811 | | NULL}}, |
812 | | {0x001f, {N_("Flash fired, auto mode, return light detected"), NULL}}, |
813 | | {0x0020, {N_("No flash function"),NULL}}, |
814 | | {0x0041, {N_("Flash fired, red-eye reduction mode"), NULL}}, |
815 | | {0x0045, {N_("Flash fired, red-eye reduction mode, return light " |
816 | | "not detected"), NULL}}, |
817 | | {0x0047, {N_("Flash fired, red-eye reduction mode, return light " |
818 | | "detected"), NULL}}, |
819 | | {0x0049, {N_("Flash fired, compulsory flash mode, red-eye reduction " |
820 | | "mode"), NULL}}, |
821 | | {0x004d, {N_("Flash fired, compulsory flash mode, red-eye reduction " |
822 | | "mode, return light not detected"), NULL}}, |
823 | | {0x004f, {N_("Flash fired, compulsory flash mode, red-eye reduction mode, " |
824 | | "return light detected"), NULL}}, |
825 | | {0x0058, {N_("Flash did not fire, auto mode, red-eye reduction mode"), NULL}}, |
826 | | {0x0059, {N_("Flash fired, auto mode, red-eye reduction mode"), NULL}}, |
827 | | {0x005d, {N_("Flash fired, auto mode, return light not detected, " |
828 | | "red-eye reduction mode"), NULL}}, |
829 | | {0x005f, {N_("Flash fired, auto mode, return light detected, " |
830 | | "red-eye reduction mode"), NULL}}, |
831 | | {0x0000, {NULL}}}}, |
832 | | { EXIF_TAG_SUBJECT_DISTANCE_RANGE, |
833 | | { {0, {N_("Unknown"), N_("?"), NULL}}, |
834 | | {1, {N_("Macro"), NULL}}, |
835 | | {2, {N_("Close view"), N_("Close"), NULL}}, |
836 | | {3, {N_("Distant view"), N_("Distant"), NULL}}, |
837 | | {0, {NULL}}}}, |
838 | | { EXIF_TAG_COLOR_SPACE, |
839 | | { {1, {N_("sRGB"), NULL}}, |
840 | | {2, {N_("Adobe RGB"), NULL}}, |
841 | | {0xffff, {N_("Uncalibrated"), NULL}}, |
842 | | {0x0000, {NULL}}}}, |
843 | | { EXIF_TAG_COMPOSITE_IMAGE, |
844 | | { {0, {N_("Unknown"), NULL}}, |
845 | | {1, {N_("Not a composite image"), NULL}}, |
846 | | {2, {N_("General composite image"), NULL}}, |
847 | | {3, {N_("Composite image captured while shooting"), NULL}}, |
848 | | {0, {NULL}}}}, |
849 | | #endif |
850 | | {0, { { 0, {NULL}}} } |
851 | | }; |
852 | | |
853 | | const char * |
854 | | exif_entry_get_value (ExifEntry *e, char *val, unsigned int maxlen) |
855 | 151k | { |
856 | 151k | unsigned int i, j, k; |
857 | 151k | ExifShort v_short, v_short2, v_short3, v_short4; |
858 | 151k | ExifByte v_byte; |
859 | 151k | ExifRational v_rat; |
860 | 151k | ExifSRational v_srat; |
861 | 151k | char b[64]; |
862 | 151k | const char *c; |
863 | 151k | ExifByteOrder o; |
864 | 151k | double d; |
865 | 151k | ExifEntry *entry; |
866 | 151k | static const struct { |
867 | 151k | char label[5]; |
868 | 151k | char major, minor; |
869 | 151k | } versions[] = { |
870 | 151k | {"0110", 1, 1}, |
871 | 151k | {"0120", 1, 2}, |
872 | 151k | {"0200", 2, 0}, |
873 | 151k | {"0210", 2, 1}, |
874 | 151k | {"0220", 2, 2}, |
875 | 151k | {"0221", 2, 21}, |
876 | 151k | {"0230", 2, 3}, |
877 | 151k | {"0231", 2, 31}, |
878 | 151k | {"0232", 2, 32}, |
879 | 151k | {"" , 0, 0} |
880 | 151k | }; |
881 | | |
882 | 151k | (void) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); |
883 | | |
884 | 151k | if (!e || !e->parent || !e->parent->parent || !maxlen || !val) |
885 | 0 | return val; |
886 | | |
887 | | /* make sure the returned string is zero terminated */ |
888 | | /* FIXME: this is inefficient in the case of long buffers and should |
889 | | * instead be taken care of on each write instead. */ |
890 | 151k | memset (val, 0, maxlen); |
891 | | |
892 | | /* We need the byte order */ |
893 | 151k | o = exif_data_get_byte_order (e->parent->parent); |
894 | | |
895 | | /* Sanity check */ |
896 | 151k | if (e->size != e->components * exif_format_get_size (e->format)) { |
897 | 58 | snprintf (val, maxlen, _("Invalid size of entry (%i, " |
898 | 58 | "expected %li x %i)."), e->size, e->components, |
899 | 58 | exif_format_get_size (e->format)); |
900 | 58 | return val; |
901 | 58 | } |
902 | | |
903 | 150k | switch (e->tag) { |
904 | 492 | case EXIF_TAG_USER_COMMENT: |
905 | | |
906 | | /* |
907 | | * The specification says UNDEFINED, but some |
908 | | * manufacturers don't care and use ASCII. If this is the |
909 | | * case here, only refuse to read it if there is no chance |
910 | | * of finding readable data. |
911 | | */ |
912 | 492 | if ((e->format != EXIF_FORMAT_ASCII) || |
913 | 72 | (e->size <= 8) || |
914 | 64 | ( memcmp (e->data, "ASCII\0\0\0" , 8) && |
915 | 62 | memcmp (e->data, "UNICODE\0" , 8) && |
916 | 60 | memcmp (e->data, "JIS\0\0\0\0\0", 8) && |
917 | 58 | memcmp (e->data, "\0\0\0\0\0\0\0\0", 8))) |
918 | 479 | CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen) |
919 | | |
920 | | /* |
921 | | * Note that, according to the specification (V2.1, p 40), |
922 | | * the user comment field does not have to be |
923 | | * NULL terminated. |
924 | | */ |
925 | 408 | if ((e->size >= 8) && !memcmp (e->data, "ASCII\0\0\0", 8)) { |
926 | 231 | strncpy (val, (char *) e->data + 8, MIN (e->size - 8, maxlen-1)); |
927 | 231 | break; |
928 | 231 | } |
929 | 177 | if ((e->size >= 8) && !memcmp (e->data, "UNICODE\0", 8)) { |
930 | 4 | strncpy (val, _("Unsupported UNICODE string"), maxlen-1); |
931 | | /* FIXME: use iconv to convert into the locale encoding. |
932 | | * EXIF 2.2 implies (but does not say) that this encoding is |
933 | | * UCS-2. |
934 | | */ |
935 | 4 | break; |
936 | 4 | } |
937 | 173 | if ((e->size >= 8) && !memcmp (e->data, "JIS\0\0\0\0\0", 8)) { |
938 | 3 | strncpy (val, _("Unsupported JIS string"), maxlen-1); |
939 | | /* FIXME: use iconv to convert into the locale encoding */ |
940 | 3 | break; |
941 | 3 | } |
942 | | |
943 | | /* Check if there is really some information in the tag. */ |
944 | 36.0k | for (i = 0; (i < e->size) && |
945 | 36.0k | (!e->data[i] || (e->data[i] == ' ')); i++); |
946 | 170 | if (i == e->size) break; |
947 | | |
948 | | /* |
949 | | * If we reach this point, the tag does not |
950 | | * comply with the standard but seems to contain data. |
951 | | * Print as much as possible. |
952 | | * Note: make sure we do not overwrite the final \0 at maxlen-1 |
953 | | */ |
954 | 156 | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
955 | 156 | _("Tag UserComment contains data but is " |
956 | 156 | "against specification.")); |
957 | 112k | for (j = 0; (i < e->size) && (j < maxlen-1); i++, j++) { |
958 | 112k | exif_entry_log (e, EXIF_LOG_CODE_DEBUG, |
959 | 112k | _("Byte at position %i: 0x%02x"), i, e->data[i]); |
960 | 112k | val[j] = isprint (e->data[i]) ? e->data[i] : '.'; |
961 | 112k | } |
962 | 156 | break; |
963 | | |
964 | 17.1k | case EXIF_TAG_EXIF_VERSION: |
965 | 17.1k | CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen) |
966 | 17.1k | CC (e, 4, val, maxlen) |
967 | 17.1k | strncpy (val, _("Unknown Exif Version"), maxlen-1); |
968 | 69.0k | for (i = 0; *versions[i].label; i++) { |
969 | 68.9k | if (!memcmp (e->data, versions[i].label, 4)) { |
970 | 17.1k | snprintf (val, maxlen, |
971 | 17.1k | _("Exif Version %d.%d"), |
972 | 17.1k | versions[i].major, |
973 | 17.1k | versions[i].minor); |
974 | 17.1k | break; |
975 | 17.1k | } |
976 | 68.9k | } |
977 | 17.1k | break; |
978 | 17.1k | case EXIF_TAG_FLASH_PIX_VERSION: |
979 | 17.1k | CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen) |
980 | 17.1k | CC (e, 4, val, maxlen) |
981 | 17.1k | if (!memcmp (e->data, "0100", 4)) |
982 | 17.0k | strncpy (val, _("FlashPix Version 1.0"), maxlen-1); |
983 | 57 | else if (!memcmp (e->data, "0101", 4)) |
984 | 5 | strncpy (val, _("FlashPix Version 1.01"), maxlen-1); |
985 | 52 | else |
986 | 52 | strncpy (val, _("Unknown FlashPix Version"), maxlen-1); |
987 | 17.1k | break; |
988 | 217 | case EXIF_TAG_COPYRIGHT: |
989 | 217 | CF (e, EXIF_FORMAT_ASCII, val, maxlen) |
990 | | |
991 | | /* |
992 | | * First part: Photographer. |
993 | | * Some cameras store a string like " " here. Ignore it. |
994 | | * Remember that a corrupted tag might not be NUL-terminated |
995 | | */ |
996 | 198 | if (e->size && e->data && match_repeated_char(e->data, ' ', e->size)) |
997 | 126 | strncpy (val, (char *) e->data, MIN (maxlen-1, e->size)); |
998 | 72 | else |
999 | 72 | strncpy (val, _("[None]"), maxlen-1); |
1000 | 198 | strncat (val, " ", maxlen-1 - strlen (val)); |
1001 | 198 | strncat (val, _("(Photographer)"), maxlen-1 - strlen (val)); |
1002 | | |
1003 | | /* Second part: Editor. */ |
1004 | 198 | strncat (val, " - ", maxlen-1 - strlen (val)); |
1005 | 198 | k = 0; |
1006 | 198 | if (e->size && e->data) { |
1007 | 198 | const unsigned char *tagdata = memchr(e->data, 0, e->size); |
1008 | 198 | if (tagdata++) { |
1009 | 175 | unsigned int editor_ofs = tagdata - e->data; |
1010 | 175 | unsigned int remaining = e->size - editor_ofs; |
1011 | 175 | if (match_repeated_char(tagdata, ' ', remaining)) { |
1012 | 103 | strncat (val, (const char*)tagdata, MIN (maxlen-1 - strlen (val), remaining)); |
1013 | 103 | ++k; |
1014 | 103 | } |
1015 | 175 | } |
1016 | 198 | } |
1017 | 198 | if (!k) |
1018 | 95 | strncat (val, _("[None]"), maxlen-1 - strlen (val)); |
1019 | 198 | strncat (val, " ", maxlen-1 - strlen (val)); |
1020 | 198 | strncat (val, _("(Editor)"), maxlen-1 - strlen (val)); |
1021 | | |
1022 | 198 | break; |
1023 | 305 | case EXIF_TAG_FNUMBER: |
1024 | 305 | CF (e, EXIF_FORMAT_RATIONAL, val, maxlen) |
1025 | 291 | CC (e, 1, val, maxlen) |
1026 | 280 | v_rat = exif_get_rational (e->data, o); |
1027 | 280 | if (!v_rat.denominator) { |
1028 | 49 | exif_entry_format_value(e, val, maxlen); |
1029 | 49 | break; |
1030 | 49 | } |
1031 | 231 | d = (double) v_rat.numerator / (double) v_rat.denominator; |
1032 | 231 | snprintf (val, maxlen, "f/%.01f", d); |
1033 | 231 | break; |
1034 | 371 | case EXIF_TAG_APERTURE_VALUE: |
1035 | 638 | case EXIF_TAG_MAX_APERTURE_VALUE: |
1036 | 638 | CF (e, EXIF_FORMAT_RATIONAL, val, maxlen) |
1037 | 609 | CC (e, 1, val, maxlen) |
1038 | 542 | v_rat = exif_get_rational (e->data, o); |
1039 | 542 | if (!v_rat.denominator || (0x80000000 == v_rat.numerator)) { |
1040 | 115 | exif_entry_format_value(e, val, maxlen); |
1041 | 115 | break; |
1042 | 115 | } |
1043 | 427 | d = (double) v_rat.numerator / (double) v_rat.denominator; |
1044 | 427 | snprintf (val, maxlen, _("%.02f EV"), d); |
1045 | 427 | snprintf (b, sizeof (b), _(" (f/%.01f)"), pow (2, d / 2.)); |
1046 | 427 | strncat (val, b, maxlen-1 - strlen (val)); |
1047 | 427 | break; |
1048 | 608 | case EXIF_TAG_FOCAL_LENGTH: |
1049 | 608 | CF (e, EXIF_FORMAT_RATIONAL, val, maxlen) |
1050 | 591 | CC (e, 1, val, maxlen) |
1051 | 561 | v_rat = exif_get_rational (e->data, o); |
1052 | 561 | if (!v_rat.denominator) { |
1053 | 82 | exif_entry_format_value(e, val, maxlen); |
1054 | 82 | break; |
1055 | 82 | } |
1056 | | |
1057 | | /* |
1058 | | * For calculation of the 35mm equivalent, |
1059 | | * Minolta cameras need a multiplier that depends on the |
1060 | | * camera model. |
1061 | | */ |
1062 | 479 | d = 0.; |
1063 | 479 | entry = exif_content_get_entry ( |
1064 | 479 | e->parent->parent->ifd[EXIF_IFD_0], EXIF_TAG_MAKE); |
1065 | 479 | if (entry && entry->data && entry->size >= 7 && |
1066 | 251 | !strncmp ((char *)entry->data, "Minolta", 7)) { |
1067 | 146 | entry = exif_content_get_entry ( |
1068 | 146 | e->parent->parent->ifd[EXIF_IFD_0], |
1069 | 146 | EXIF_TAG_MODEL); |
1070 | 146 | if (entry && entry->data && entry->size >= 8) { |
1071 | 142 | if (!strncmp ((char *)entry->data, "DiMAGE 7", 8)) |
1072 | 2 | d = 3.9; |
1073 | 140 | else if (!strncmp ((char *)entry->data, "DiMAGE 5", 8)) |
1074 | 2 | d = 4.9; |
1075 | 142 | } |
1076 | 146 | } |
1077 | 479 | if (d) |
1078 | 4 | snprintf (b, sizeof (b), _(" (35 equivalent: %.0f mm)"), |
1079 | 4 | (d * (double) v_rat.numerator / |
1080 | 4 | (double) v_rat.denominator)); |
1081 | 475 | else |
1082 | 475 | b[0] = 0; |
1083 | | |
1084 | 479 | d = (double) v_rat.numerator / (double) v_rat.denominator; |
1085 | 479 | snprintf (val, maxlen, "%.1f mm", d); |
1086 | 479 | strncat (val, b, maxlen-1 - strlen (val)); |
1087 | 479 | break; |
1088 | 315 | case EXIF_TAG_SUBJECT_DISTANCE: |
1089 | 315 | CF (e, EXIF_FORMAT_RATIONAL, val, maxlen) |
1090 | 297 | CC (e, 1, val, maxlen) |
1091 | 271 | v_rat = exif_get_rational (e->data, o); |
1092 | 271 | if (!v_rat.denominator) { |
1093 | 74 | exif_entry_format_value(e, val, maxlen); |
1094 | 74 | break; |
1095 | 74 | } |
1096 | 197 | d = (double) v_rat.numerator / (double) v_rat.denominator; |
1097 | 197 | snprintf (val, maxlen, "%.1f m", d); |
1098 | 197 | break; |
1099 | 309 | case EXIF_TAG_EXPOSURE_TIME: |
1100 | 309 | CF (e, EXIF_FORMAT_RATIONAL, val, maxlen) |
1101 | 298 | CC (e, 1, val, maxlen) |
1102 | 284 | v_rat = exif_get_rational (e->data, o); |
1103 | 284 | if (!v_rat.denominator) { |
1104 | 67 | exif_entry_format_value(e, val, maxlen); |
1105 | 67 | break; |
1106 | 67 | } |
1107 | 217 | d = (double) v_rat.numerator / (double) v_rat.denominator; |
1108 | 217 | if (d < 1 && d) |
1109 | 121 | snprintf (val, maxlen, _("1/%.0f"), 1. / d); |
1110 | 96 | else |
1111 | 96 | snprintf (val, maxlen, "%.0f", d); |
1112 | 217 | strncat (val, _(" sec."), maxlen-1 - strlen (val)); |
1113 | 217 | break; |
1114 | 378 | case EXIF_TAG_SHUTTER_SPEED_VALUE: |
1115 | 378 | CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen) |
1116 | 355 | CC (e, 1, val, maxlen) |
1117 | 342 | v_srat = exif_get_srational (e->data, o); |
1118 | 342 | if (!v_srat.denominator) { |
1119 | 76 | exif_entry_format_value(e, val, maxlen); |
1120 | 76 | break; |
1121 | 76 | } |
1122 | 266 | d = (double) v_srat.numerator / (double) v_srat.denominator; |
1123 | 266 | snprintf (val, maxlen, _("%.02f EV"), d); |
1124 | 266 | if (pow (2, d)) |
1125 | 249 | d = 1. / pow (2, d); |
1126 | 266 | if (d < 1 && d) |
1127 | 131 | snprintf (b, sizeof (b), _(" (1/%.0f sec.)"), 1. / d); |
1128 | 135 | else |
1129 | 135 | snprintf (b, sizeof (b), _(" (%.0f sec.)"), d); |
1130 | 266 | strncat (val, b, maxlen-1 - strlen (val)); |
1131 | 266 | break; |
1132 | 323 | case EXIF_TAG_BRIGHTNESS_VALUE: |
1133 | 323 | CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen) |
1134 | 271 | CC (e, 1, val, maxlen) |
1135 | 237 | v_srat = exif_get_srational (e->data, o); |
1136 | 237 | if (!v_srat.denominator) { |
1137 | 62 | exif_entry_format_value(e, val, maxlen); |
1138 | 62 | break; |
1139 | 62 | } |
1140 | 175 | d = (double) v_srat.numerator / (double) v_srat.denominator; |
1141 | 175 | snprintf (val, maxlen, _("%.02f EV"), d); |
1142 | 175 | snprintf (b, sizeof (b), _(" (%.02f cd/m^2)"), |
1143 | 175 | 1. / (M_PI * 0.3048 * 0.3048) * pow (2, d)); |
1144 | 175 | strncat (val, b, maxlen-1 - strlen (val)); |
1145 | 175 | break; |
1146 | 81 | case EXIF_TAG_FILE_SOURCE: |
1147 | 81 | CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen) |
1148 | 71 | CC (e, 1, val, maxlen) |
1149 | 67 | v_byte = e->data[0]; |
1150 | 67 | if (v_byte == 3) |
1151 | 39 | strncpy (val, _("DSC"), maxlen-1); |
1152 | 28 | else |
1153 | 28 | snprintf (val, maxlen, _("Internal error (unknown " |
1154 | 28 | "value %i)"), v_byte); |
1155 | 67 | break; |
1156 | 225 | case EXIF_TAG_COMPONENTS_CONFIGURATION: |
1157 | 225 | CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen) |
1158 | 214 | CC (e, 4, val, maxlen) |
1159 | 915 | for (i = 0; i < 4; i++) { |
1160 | 732 | switch (e->data[i]) { |
1161 | 170 | case 0: c = _("-"); break; |
1162 | 125 | case 1: c = _("Y"); break; |
1163 | 126 | case 2: c = _("Cb"); break; |
1164 | 135 | case 3: c = _("Cr"); break; |
1165 | 8 | case 4: c = _("R"); break; |
1166 | 10 | case 5: c = _("G"); break; |
1167 | 12 | case 6: c = _("B"); break; |
1168 | 146 | default: c = _("Reserved"); break; |
1169 | 732 | } |
1170 | 732 | strncat (val, c, maxlen-1 - strlen (val)); |
1171 | 732 | if (i < 3) |
1172 | 549 | strncat (val, " ", maxlen-1 - strlen (val)); |
1173 | 732 | } |
1174 | 183 | break; |
1175 | 369 | case EXIF_TAG_EXPOSURE_BIAS_VALUE: |
1176 | 369 | CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen) |
1177 | 352 | CC (e, 1, val, maxlen) |
1178 | 336 | v_srat = exif_get_srational (e->data, o); |
1179 | 336 | if (!v_srat.denominator) { |
1180 | 72 | exif_entry_format_value(e, val, maxlen); |
1181 | 72 | break; |
1182 | 72 | } |
1183 | 264 | d = (double) v_srat.numerator / (double) v_srat.denominator; |
1184 | 264 | snprintf (val, maxlen, _("%.02f EV"), d); |
1185 | 264 | break; |
1186 | 79 | case EXIF_TAG_SCENE_TYPE: |
1187 | 79 | CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen) |
1188 | 75 | CC (e, 1, val, maxlen) |
1189 | 60 | v_byte = e->data[0]; |
1190 | 60 | if (v_byte == 1) |
1191 | 40 | strncpy (val, _("Directly photographed"), maxlen-1); |
1192 | 20 | else |
1193 | 20 | snprintf (val, maxlen, _("Internal error (unknown " |
1194 | 20 | "value %i)"), v_byte); |
1195 | 60 | break; |
1196 | 218 | case EXIF_TAG_YCBCR_SUB_SAMPLING: |
1197 | 218 | CF (e, EXIF_FORMAT_SHORT, val, maxlen) |
1198 | 159 | CC (e, 2, val, maxlen) |
1199 | 96 | v_short = exif_get_short (e->data, o); |
1200 | 96 | v_short2 = exif_get_short ( |
1201 | 96 | e->data + exif_format_get_size (e->format), |
1202 | 96 | o); |
1203 | 96 | if ((v_short == 2) && (v_short2 == 1)) |
1204 | 7 | strncpy (val, _("YCbCr4:2:2"), maxlen-1); |
1205 | 89 | else if ((v_short == 2) && (v_short2 == 2)) |
1206 | 6 | strncpy (val, _("YCbCr4:2:0"), maxlen-1); |
1207 | 83 | else |
1208 | 83 | snprintf (val, maxlen, "%u, %u", v_short, v_short2); |
1209 | 96 | break; |
1210 | 40 | case EXIF_TAG_SUBJECT_AREA: |
1211 | 40 | CF (e, EXIF_FORMAT_SHORT, val, maxlen) |
1212 | 34 | switch (e->components) { |
1213 | 3 | case 2: |
1214 | 3 | v_short = exif_get_short (e->data, o); |
1215 | 3 | v_short2 = exif_get_short (e->data + 2, o); |
1216 | 3 | snprintf (val, maxlen, "(x,y) = (%i,%i)", |
1217 | 3 | v_short, v_short2); |
1218 | 3 | break; |
1219 | 3 | case 3: |
1220 | 3 | v_short = exif_get_short (e->data, o); |
1221 | 3 | v_short2 = exif_get_short (e->data + 2, o); |
1222 | 3 | v_short3 = exif_get_short (e->data + 4, o); |
1223 | 3 | snprintf (val, maxlen, _("Within distance %i of " |
1224 | 3 | "(x,y) = (%i,%i)"), v_short3, v_short, |
1225 | 3 | v_short2); |
1226 | 3 | break; |
1227 | 16 | case 4: |
1228 | 16 | v_short = exif_get_short (e->data, o); |
1229 | 16 | v_short2 = exif_get_short (e->data + 2, o); |
1230 | 16 | v_short3 = exif_get_short (e->data + 4, o); |
1231 | 16 | v_short4 = exif_get_short (e->data + 6, o); |
1232 | 16 | snprintf (val, maxlen, _("Within rectangle " |
1233 | 16 | "(width %i, height %i) around " |
1234 | 16 | "(x,y) = (%i,%i)"), v_short3, v_short4, |
1235 | 16 | v_short, v_short2); |
1236 | 16 | break; |
1237 | 12 | default: |
1238 | 12 | snprintf (val, maxlen, _("Unexpected number " |
1239 | 12 | "of components (%li, expected 2, 3, or 4)."), |
1240 | 12 | e->components); |
1241 | 34 | } |
1242 | 34 | break; |
1243 | 425 | case EXIF_TAG_GPS_VERSION_ID: |
1244 | | /* This is only valid in the GPS IFD */ |
1245 | 425 | CF (e, EXIF_FORMAT_BYTE, val, maxlen) |
1246 | 90 | CC (e, 4, val, maxlen) |
1247 | 5 | v_byte = e->data[0]; |
1248 | 5 | snprintf (val, maxlen, "%u", v_byte); |
1249 | 20 | for (i = 1; i < e->components; i++) { |
1250 | 15 | v_byte = e->data[i]; |
1251 | 15 | snprintf (b, sizeof (b), ".%u", v_byte); |
1252 | 15 | strncat (val, b, maxlen-1 - strlen (val)); |
1253 | 15 | } |
1254 | 5 | break; |
1255 | 539 | case EXIF_TAG_INTEROPERABILITY_VERSION: |
1256 | | /* a.k.a. case EXIF_TAG_GPS_LATITUDE: */ |
1257 | | /* This tag occurs in EXIF_IFD_INTEROPERABILITY */ |
1258 | 539 | if (e->format == EXIF_FORMAT_UNDEFINED) { |
1259 | 92 | strncpy (val, (char *) e->data, MIN (maxlen-1, e->size)); |
1260 | 92 | break; |
1261 | 92 | } |
1262 | | /* EXIF_TAG_GPS_LATITUDE is the same numerically as |
1263 | | * EXIF_TAG_INTEROPERABILITY_VERSION but in EXIF_IFD_GPS |
1264 | | */ |
1265 | 447 | exif_entry_format_value(e, val, maxlen); |
1266 | 447 | break; |
1267 | 162 | case EXIF_TAG_GPS_ALTITUDE_REF: |
1268 | | /* This is only valid in the GPS IFD */ |
1269 | 162 | CF (e, EXIF_FORMAT_BYTE, val, maxlen) |
1270 | 80 | CC (e, 1, val, maxlen) |
1271 | 35 | v_byte = e->data[0]; |
1272 | 35 | if (v_byte == 0) |
1273 | 16 | strncpy (val, _("Sea level"), maxlen-1); |
1274 | 19 | else if (v_byte == 1) |
1275 | 3 | strncpy (val, _("Sea level reference"), maxlen-1); |
1276 | 16 | else |
1277 | 16 | snprintf (val, maxlen, _("Internal error (unknown " |
1278 | 16 | "value %i)"), v_byte); |
1279 | 35 | break; |
1280 | 783 | case EXIF_TAG_GPS_TIME_STAMP: |
1281 | | /* This is only valid in the GPS IFD */ |
1282 | 783 | CF (e, EXIF_FORMAT_RATIONAL, val, maxlen) |
1283 | 611 | CC (e, 3, val, maxlen) |
1284 | | |
1285 | 601 | v_rat = exif_get_rational (e->data, o); |
1286 | 601 | if (!v_rat.denominator) { |
1287 | 79 | exif_entry_format_value(e, val, maxlen); |
1288 | 79 | break; |
1289 | 79 | } |
1290 | 522 | i = v_rat.numerator / v_rat.denominator; |
1291 | | |
1292 | 522 | v_rat = exif_get_rational (e->data + |
1293 | 522 | exif_format_get_size (e->format), |
1294 | 522 | o); |
1295 | 522 | if (!v_rat.denominator) { |
1296 | 55 | exif_entry_format_value(e, val, maxlen); |
1297 | 55 | break; |
1298 | 55 | } |
1299 | 467 | j = v_rat.numerator / v_rat.denominator; |
1300 | | |
1301 | 467 | v_rat = exif_get_rational (e->data + |
1302 | 467 | 2*exif_format_get_size (e->format), |
1303 | 467 | o); |
1304 | 467 | if (!v_rat.denominator) { |
1305 | 80 | exif_entry_format_value(e, val, maxlen); |
1306 | 80 | break; |
1307 | 80 | } |
1308 | 387 | d = (double) v_rat.numerator / (double) v_rat.denominator; |
1309 | 387 | snprintf (val, maxlen, "%02u:%02u:%05.2f", i, j, d); |
1310 | 387 | break; |
1311 | | |
1312 | 229 | case EXIF_TAG_METERING_MODE: |
1313 | 884 | case EXIF_TAG_COMPRESSION: |
1314 | 990 | case EXIF_TAG_LIGHT_SOURCE: |
1315 | 1.01k | case EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT: |
1316 | 18.7k | case EXIF_TAG_RESOLUTION_UNIT: |
1317 | 18.8k | case EXIF_TAG_EXPOSURE_PROGRAM: |
1318 | 18.8k | case EXIF_TAG_SENSITIVITY_TYPE: |
1319 | 19.0k | case EXIF_TAG_FLASH: |
1320 | 19.0k | case EXIF_TAG_SUBJECT_DISTANCE_RANGE: |
1321 | 36.2k | case EXIF_TAG_COLOR_SPACE: |
1322 | 36.2k | case EXIF_TAG_COMPOSITE_IMAGE: |
1323 | 36.2k | CF (e,EXIF_FORMAT_SHORT, val, maxlen) |
1324 | 36.0k | CC (e, 1, val, maxlen) |
1325 | 35.9k | v_short = exif_get_short (e->data, o); |
1326 | | |
1327 | | /* Search the tag */ |
1328 | 263k | for (i = 0; list2[i].tag && (list2[i].tag != e->tag); i++); |
1329 | 35.9k | if (!list2[i].tag) { |
1330 | 0 | snprintf (val, maxlen, _("Internal error (unknown " |
1331 | 0 | "value %i)"), v_short); |
1332 | 0 | break; |
1333 | 0 | } |
1334 | | |
1335 | | /* Find the value */ |
1336 | 73.6k | for (j = 0; list2[i].elem[j].values[0] && |
1337 | 73.4k | (list2[i].elem[j].index < v_short); j++); |
1338 | 35.9k | if (list2[i].elem[j].index != v_short) { |
1339 | 789 | snprintf (val, maxlen, _("Internal error (unknown " |
1340 | 789 | "value %i)"), v_short); |
1341 | 789 | break; |
1342 | 789 | } |
1343 | | |
1344 | | /* Find a short enough value */ |
1345 | 35.1k | memset (val, 0, maxlen); |
1346 | 88.2k | for (k = 0; list2[i].elem[j].values[k]; k++) { |
1347 | 53.0k | size_t l = strlen (_(list2[i].elem[j].values[k])); |
1348 | 53.0k | if ((maxlen > l) && (strlen (val) < l)) |
1349 | 35.1k | strncpy (val, _(list2[i].elem[j].values[k]), maxlen-1); |
1350 | 53.0k | } |
1351 | 35.1k | if (!val[0]) snprintf (val, maxlen, "%i", v_short); |
1352 | | |
1353 | 35.1k | break; |
1354 | | |
1355 | 110 | case EXIF_TAG_PLANAR_CONFIGURATION: |
1356 | 137 | case EXIF_TAG_SENSING_METHOD: |
1357 | 369 | case EXIF_TAG_ORIENTATION: |
1358 | 610 | case EXIF_TAG_YCBCR_POSITIONING: |
1359 | 689 | case EXIF_TAG_PHOTOMETRIC_INTERPRETATION: |
1360 | 816 | case EXIF_TAG_CUSTOM_RENDERED: |
1361 | 937 | case EXIF_TAG_EXPOSURE_MODE: |
1362 | 1.07k | case EXIF_TAG_WHITE_BALANCE: |
1363 | 1.16k | case EXIF_TAG_SCENE_CAPTURE_TYPE: |
1364 | 1.23k | case EXIF_TAG_GAIN_CONTROL: |
1365 | 1.35k | case EXIF_TAG_SATURATION: |
1366 | 1.42k | case EXIF_TAG_CONTRAST: |
1367 | 1.47k | case EXIF_TAG_SHARPNESS: |
1368 | 1.47k | CF (e, EXIF_FORMAT_SHORT, val, maxlen) |
1369 | 1.19k | CC (e, 1, val, maxlen) |
1370 | 789 | v_short = exif_get_short (e->data, o); |
1371 | | |
1372 | | /* Search the tag */ |
1373 | 5.13k | for (i = 0; list[i].tag && (list[i].tag != e->tag); i++); |
1374 | 789 | if (!list[i].tag) { |
1375 | 0 | snprintf (val, maxlen, _("Internal error (unknown " |
1376 | 0 | "value %i)"), v_short); |
1377 | 0 | break; |
1378 | 0 | } |
1379 | | |
1380 | | /* Find the value */ |
1381 | 2.26k | for (j = 0; list[i].strings[j] && (j < v_short); j++); |
1382 | 789 | if (!list[i].strings[j]) |
1383 | 205 | snprintf (val, maxlen, "%i", v_short); |
1384 | 584 | else if (!*list[i].strings[j]) |
1385 | 39 | snprintf (val, maxlen, _("Unknown value %i"), v_short); |
1386 | 545 | else |
1387 | 545 | strncpy (val, _(list[i].strings[j]), maxlen-1); |
1388 | 789 | break; |
1389 | | |
1390 | 39 | case EXIF_TAG_XP_TITLE: |
1391 | 79 | case EXIF_TAG_XP_COMMENT: |
1392 | 120 | case EXIF_TAG_XP_AUTHOR: |
1393 | 176 | case EXIF_TAG_XP_KEYWORDS: |
1394 | 217 | case EXIF_TAG_XP_SUBJECT: |
1395 | 217 | { |
1396 | 217 | unsigned char *utf16; |
1397 | | |
1398 | | /* Sanity check the size to prevent overflow. Note EXIF files are 64kb at most. */ |
1399 | 217 | if (e->size >= 65536 - sizeof(uint16_t)*2) break; |
1400 | | |
1401 | | /* The tag may not be U+0000-terminated , so make a local |
1402 | | U+0000-terminated copy before converting it */ |
1403 | 217 | utf16 = exif_mem_alloc (e->priv->mem, e->size+sizeof(uint16_t)+1); |
1404 | 217 | if (!utf16) break; |
1405 | 217 | memcpy(utf16, e->data, e->size); |
1406 | | |
1407 | | /* NUL terminate the string. If the size is odd (which isn't possible |
1408 | | * for a valid UTF16 string), then this will overwrite the high byte of |
1409 | | * the final half word, plus add a full zero NUL word at the end. |
1410 | | */ |
1411 | 217 | utf16[e->size] = 0; |
1412 | 217 | utf16[e->size+1] = 0; |
1413 | 217 | utf16[e->size+2] = 0; |
1414 | | |
1415 | | /* Warning! The texts are converted from UTF16 to UTF8 */ |
1416 | | /* FIXME: use iconv to convert into the locale encoding */ |
1417 | 217 | exif_convert_utf16_to_utf8(val, utf16, maxlen); |
1418 | 217 | exif_mem_free(e->priv->mem, utf16); |
1419 | 217 | break; |
1420 | 217 | } |
1421 | | |
1422 | 72.1k | default: |
1423 | | /* Use a generic value formatting */ |
1424 | 72.1k | exif_entry_format_value(e, val, maxlen); |
1425 | 150k | } |
1426 | | |
1427 | 150k | return val; |
1428 | 150k | } |
1429 | | |
1430 | | static |
1431 | 0 | void exif_entry_initialize_gps(ExifEntry *e, ExifTag tag) { |
1432 | 0 | const ExifGPSIfdTagInfo* info = exif_get_gps_tag_info(tag); |
1433 | |
|
1434 | 0 | if(!info) { |
1435 | 0 | e->components = 0; |
1436 | 0 | e->format = EXIF_FORMAT_UNDEFINED; |
1437 | 0 | e->size = 0; |
1438 | 0 | e->data = NULL; |
1439 | 0 | return; |
1440 | 0 | } |
1441 | | |
1442 | 0 | e->format = info->format; |
1443 | 0 | e->components = info->components; |
1444 | |
|
1445 | 0 | if(info->components == 0) { |
1446 | | /* No pre-allocation */ |
1447 | 0 | e->size = 0; |
1448 | 0 | e->data = NULL; |
1449 | 0 | } else { |
1450 | 0 | int hasDefault = (info->default_size && info->default_value); |
1451 | 0 | int allocSize = hasDefault ? info->default_size : (exif_format_get_size (e->format) * e->components); |
1452 | 0 | e->size = allocSize; |
1453 | 0 | e->data = exif_entry_alloc (e, e->size); |
1454 | 0 | if(!e->data) { |
1455 | 0 | clear_entry(e); |
1456 | 0 | return; |
1457 | 0 | } |
1458 | 0 | if(hasDefault) { |
1459 | 0 | memcpy(e->data, info->default_value, info->default_size); |
1460 | 0 | } |
1461 | 0 | } |
1462 | 0 | } |
1463 | | |
1464 | | /*! |
1465 | | * \bug Log and report failed exif_mem_malloc() calls. |
1466 | | */ |
1467 | | void |
1468 | | exif_entry_initialize (ExifEntry *e, ExifTag tag) |
1469 | 120k | { |
1470 | 120k | ExifRational r; |
1471 | 120k | ExifByteOrder o; |
1472 | | |
1473 | 120k | if (!e || !e->parent || e->data || !e->parent->parent) |
1474 | 0 | return; |
1475 | | /* We need the byte order */ |
1476 | 120k | o = exif_data_get_byte_order (e->parent->parent); |
1477 | | |
1478 | 120k | e->tag = tag; |
1479 | | |
1480 | 120k | if(exif_entry_get_ifd(e) == EXIF_IFD_GPS) { |
1481 | 0 | exif_entry_initialize_gps(e, tag); |
1482 | 0 | return; |
1483 | 0 | } |
1484 | | |
1485 | 120k | switch (tag) { |
1486 | | |
1487 | | /* LONG, 1 component, no default */ |
1488 | 0 | case EXIF_TAG_PIXEL_X_DIMENSION: |
1489 | 0 | case EXIF_TAG_PIXEL_Y_DIMENSION: |
1490 | 0 | case EXIF_TAG_EXIF_IFD_POINTER: |
1491 | 0 | case EXIF_TAG_GPS_INFO_IFD_POINTER: |
1492 | 0 | case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: |
1493 | 0 | case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: |
1494 | 0 | case EXIF_TAG_JPEG_INTERCHANGE_FORMAT: |
1495 | 0 | case EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY: |
1496 | 0 | case EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX: |
1497 | 0 | case EXIF_TAG_ISO_SPEED: |
1498 | 0 | case EXIF_TAG_ISO_SPEEDLatitudeYYY: |
1499 | 0 | case EXIF_TAG_ISO_SPEEDLatitudeZZZ: |
1500 | 0 | e->components = 1; |
1501 | 0 | e->format = EXIF_FORMAT_LONG; |
1502 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1503 | 0 | e->data = exif_entry_alloc (e, e->size); |
1504 | 0 | if (!e->data) { clear_entry(e); break; } |
1505 | 0 | break; |
1506 | | |
1507 | | /* SHORT, 1 component, no default */ |
1508 | 0 | case EXIF_TAG_SUBJECT_LOCATION: |
1509 | 0 | case EXIF_TAG_SENSING_METHOD: |
1510 | 0 | case EXIF_TAG_PHOTOMETRIC_INTERPRETATION: |
1511 | 592 | case EXIF_TAG_COMPRESSION: |
1512 | 592 | case EXIF_TAG_EXPOSURE_MODE: |
1513 | 592 | case EXIF_TAG_WHITE_BALANCE: |
1514 | 592 | case EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM: |
1515 | 592 | case EXIF_TAG_GAIN_CONTROL: |
1516 | 592 | case EXIF_TAG_SUBJECT_DISTANCE_RANGE: |
1517 | 592 | case EXIF_TAG_FLASH: |
1518 | 592 | case EXIF_TAG_ISO_SPEED_RATINGS: |
1519 | 592 | case EXIF_TAG_SENSITIVITY_TYPE: |
1520 | 592 | case EXIF_TAG_COMPOSITE_IMAGE: |
1521 | | |
1522 | | /* SHORT, 1 component, default 0 */ |
1523 | 592 | case EXIF_TAG_IMAGE_WIDTH: |
1524 | 592 | case EXIF_TAG_IMAGE_LENGTH: |
1525 | 592 | case EXIF_TAG_EXPOSURE_PROGRAM: |
1526 | 592 | case EXIF_TAG_LIGHT_SOURCE: |
1527 | 592 | case EXIF_TAG_METERING_MODE: |
1528 | 592 | case EXIF_TAG_CUSTOM_RENDERED: |
1529 | 592 | case EXIF_TAG_SCENE_CAPTURE_TYPE: |
1530 | 592 | case EXIF_TAG_CONTRAST: |
1531 | 592 | case EXIF_TAG_SATURATION: |
1532 | 592 | case EXIF_TAG_SHARPNESS: |
1533 | 592 | e->components = 1; |
1534 | 592 | e->format = EXIF_FORMAT_SHORT; |
1535 | 592 | e->size = exif_format_get_size (e->format) * e->components; |
1536 | 592 | e->data = exif_entry_alloc (e, e->size); |
1537 | 592 | if (!e->data) { clear_entry(e); break; } |
1538 | 592 | exif_set_short (e->data, o, 0); |
1539 | 592 | break; |
1540 | | |
1541 | | /* SHORT, 1 component, default 1 */ |
1542 | 0 | case EXIF_TAG_ORIENTATION: |
1543 | 0 | case EXIF_TAG_PLANAR_CONFIGURATION: |
1544 | 0 | case EXIF_TAG_YCBCR_POSITIONING: |
1545 | 0 | e->components = 1; |
1546 | 0 | e->format = EXIF_FORMAT_SHORT; |
1547 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1548 | 0 | e->data = exif_entry_alloc (e, e->size); |
1549 | 0 | if (!e->data) { clear_entry(e); break; } |
1550 | 0 | exif_set_short (e->data, o, 1); |
1551 | 0 | break; |
1552 | | |
1553 | | /* SHORT, 1 component, default 2 */ |
1554 | 20.3k | case EXIF_TAG_RESOLUTION_UNIT: |
1555 | 20.3k | case EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT: |
1556 | 20.3k | e->components = 1; |
1557 | 20.3k | e->format = EXIF_FORMAT_SHORT; |
1558 | 20.3k | e->size = exif_format_get_size (e->format) * e->components; |
1559 | 20.3k | e->data = exif_entry_alloc (e, e->size); |
1560 | 20.3k | if (!e->data) { clear_entry(e); break; } |
1561 | 20.3k | exif_set_short (e->data, o, 2); |
1562 | 20.3k | break; |
1563 | | |
1564 | | /* SHORT, 1 component, default 3 */ |
1565 | 0 | case EXIF_TAG_SAMPLES_PER_PIXEL: |
1566 | 0 | e->components = 1; |
1567 | 0 | e->format = EXIF_FORMAT_SHORT; |
1568 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1569 | 0 | e->data = exif_entry_alloc (e, e->size); |
1570 | 0 | if (!e->data) { clear_entry(e); break; } |
1571 | 0 | exif_set_short (e->data, o, 3); |
1572 | 0 | break; |
1573 | | |
1574 | | /* SHORT, 1 component, default 0xffff */ |
1575 | 19.7k | case EXIF_TAG_COLOR_SPACE: |
1576 | 19.7k | e->components = 1; |
1577 | 19.7k | e->format = EXIF_FORMAT_SHORT; |
1578 | 19.7k | e->size = exif_format_get_size (e->format) * e->components; |
1579 | 19.7k | e->data = exif_entry_alloc (e, e->size); |
1580 | 19.7k | if (!e->data) { clear_entry(e); break; } |
1581 | 19.7k | exif_set_short (e->data, o, 0xffff); |
1582 | 19.7k | break; |
1583 | | |
1584 | | /* SHORT, 3 components, default 8 8 8 */ |
1585 | 0 | case EXIF_TAG_BITS_PER_SAMPLE: |
1586 | 0 | e->components = 3; |
1587 | 0 | e->format = EXIF_FORMAT_SHORT; |
1588 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1589 | 0 | e->data = exif_entry_alloc (e, e->size); |
1590 | 0 | if (!e->data) { clear_entry(e); break; } |
1591 | 0 | exif_set_short (e->data, o, 8); |
1592 | 0 | exif_set_short ( |
1593 | 0 | e->data + exif_format_get_size (e->format), |
1594 | 0 | o, 8); |
1595 | 0 | exif_set_short ( |
1596 | 0 | e->data + 2 * exif_format_get_size (e->format), |
1597 | 0 | o, 8); |
1598 | 0 | break; |
1599 | | |
1600 | | /* SHORT, 2 components, default 0 0 */ |
1601 | 0 | case EXIF_TAG_SOURCE_IMAGE_NUMBER_OF_COMPOSITE_IMAGE: |
1602 | 0 | e->components = 2; |
1603 | 0 | e->format = EXIF_FORMAT_SHORT; |
1604 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1605 | 0 | e->data = exif_entry_alloc (e, e->size); |
1606 | 0 | if (!e->data) { clear_entry(e); break; } |
1607 | 0 | exif_set_short (e->data, o, 0); |
1608 | 0 | exif_set_short ( |
1609 | 0 | e->data + exif_format_get_size (e->format), |
1610 | 0 | o, 0); |
1611 | 0 | break; |
1612 | | |
1613 | | /* SHORT, 2 components, default 2 1 */ |
1614 | 0 | case EXIF_TAG_YCBCR_SUB_SAMPLING: |
1615 | 0 | e->components = 2; |
1616 | 0 | e->format = EXIF_FORMAT_SHORT; |
1617 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1618 | 0 | e->data = exif_entry_alloc (e, e->size); |
1619 | 0 | if (!e->data) { clear_entry(e); break; } |
1620 | 0 | exif_set_short (e->data, o, 2); |
1621 | 0 | exif_set_short ( |
1622 | 0 | e->data + exif_format_get_size (e->format), |
1623 | 0 | o, 1); |
1624 | 0 | break; |
1625 | | |
1626 | | /* SRATIONAL, 1 component, no default */ |
1627 | 0 | case EXIF_TAG_EXPOSURE_BIAS_VALUE: |
1628 | 0 | case EXIF_TAG_BRIGHTNESS_VALUE: |
1629 | 0 | case EXIF_TAG_SHUTTER_SPEED_VALUE: |
1630 | 0 | e->components = 1; |
1631 | 0 | e->format = EXIF_FORMAT_SRATIONAL; |
1632 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1633 | 0 | e->data = exif_entry_alloc (e, e->size); |
1634 | 0 | if (!e->data) { clear_entry(e); break; } |
1635 | 0 | break; |
1636 | | |
1637 | | /* RATIONAL, 1 component, no default */ |
1638 | 0 | case EXIF_TAG_EXPOSURE_TIME: |
1639 | 0 | case EXIF_TAG_FOCAL_PLANE_X_RESOLUTION: |
1640 | 0 | case EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION: |
1641 | 0 | case EXIF_TAG_EXPOSURE_INDEX: |
1642 | 0 | case EXIF_TAG_FLASH_ENERGY: |
1643 | 0 | case EXIF_TAG_FNUMBER: |
1644 | 0 | case EXIF_TAG_FOCAL_LENGTH: |
1645 | 0 | case EXIF_TAG_SUBJECT_DISTANCE: |
1646 | 0 | case EXIF_TAG_MAX_APERTURE_VALUE: |
1647 | 0 | case EXIF_TAG_APERTURE_VALUE: |
1648 | 0 | case EXIF_TAG_COMPRESSED_BITS_PER_PIXEL: |
1649 | 0 | case EXIF_TAG_PRIMARY_CHROMATICITIES: |
1650 | 0 | case EXIF_TAG_DIGITAL_ZOOM_RATIO: |
1651 | 0 | case EXIF_TAG_GAMMA: |
1652 | 0 | e->components = 1; |
1653 | 0 | e->format = EXIF_FORMAT_RATIONAL; |
1654 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1655 | 0 | e->data = exif_entry_alloc (e, e->size); |
1656 | 0 | if (!e->data) { clear_entry(e); break; } |
1657 | 0 | break; |
1658 | | |
1659 | | /* RATIONAL, 1 component, default 72/1 */ |
1660 | 20.3k | case EXIF_TAG_X_RESOLUTION: |
1661 | 40.7k | case EXIF_TAG_Y_RESOLUTION: |
1662 | 40.7k | e->components = 1; |
1663 | 40.7k | e->format = EXIF_FORMAT_RATIONAL; |
1664 | 40.7k | e->size = exif_format_get_size (e->format) * e->components; |
1665 | 40.7k | e->data = exif_entry_alloc (e, e->size); |
1666 | 40.7k | if (!e->data) { clear_entry(e); break; } |
1667 | 40.7k | r.numerator = 72; |
1668 | 40.7k | r.denominator = 1; |
1669 | 40.7k | exif_set_rational (e->data, o, r); |
1670 | 40.7k | break; |
1671 | | |
1672 | | /* RATIONAL, 2 components, no default */ |
1673 | 0 | case EXIF_TAG_WHITE_POINT: |
1674 | 0 | e->components = 2; |
1675 | 0 | e->format = EXIF_FORMAT_RATIONAL; |
1676 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1677 | 0 | e->data = exif_entry_alloc (e, e->size); |
1678 | 0 | if (!e->data) { clear_entry(e); break; } |
1679 | 0 | break; |
1680 | | |
1681 | | /* RATIONAL, 4 components, no default */ |
1682 | 0 | case EXIF_TAG_LENS_SPECIFICATION: |
1683 | 0 | e->components = 4; |
1684 | 0 | e->format = EXIF_FORMAT_RATIONAL; |
1685 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1686 | 0 | e->data = exif_entry_alloc (e, e->size); |
1687 | 0 | if (!e->data) { clear_entry(e); break; } |
1688 | 0 | break; |
1689 | | |
1690 | | /* RATIONAL, 6 components */ |
1691 | 0 | case EXIF_TAG_REFERENCE_BLACK_WHITE: |
1692 | 0 | e->components = 6; |
1693 | 0 | e->format = EXIF_FORMAT_RATIONAL; |
1694 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1695 | 0 | e->data = exif_entry_alloc (e, e->size); |
1696 | 0 | if (!e->data) { clear_entry(e); break; } |
1697 | 0 | r.denominator = 1; |
1698 | 0 | r.numerator = 0; |
1699 | 0 | exif_set_rational (e->data, o, r); |
1700 | 0 | r.numerator = 255; |
1701 | 0 | exif_set_rational ( |
1702 | 0 | e->data + exif_format_get_size (e->format), o, r); |
1703 | 0 | r.numerator = 0; |
1704 | 0 | exif_set_rational ( |
1705 | 0 | e->data + 2 * exif_format_get_size (e->format), o, r); |
1706 | 0 | r.numerator = 255; |
1707 | 0 | exif_set_rational ( |
1708 | 0 | e->data + 3 * exif_format_get_size (e->format), o, r); |
1709 | 0 | r.numerator = 0; |
1710 | 0 | exif_set_rational ( |
1711 | 0 | e->data + 4 * exif_format_get_size (e->format), o, r); |
1712 | 0 | r.numerator = 255; |
1713 | 0 | exif_set_rational ( |
1714 | 0 | e->data + 5 * exif_format_get_size (e->format), o, r); |
1715 | 0 | break; |
1716 | | |
1717 | | /* ASCII, 20 components */ |
1718 | 0 | case EXIF_TAG_DATE_TIME: |
1719 | 0 | case EXIF_TAG_DATE_TIME_ORIGINAL: |
1720 | 0 | case EXIF_TAG_DATE_TIME_DIGITIZED: |
1721 | 0 | { |
1722 | 0 | time_t t; |
1723 | 0 | #if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) |
1724 | 0 | struct tm tms; |
1725 | 0 | #endif |
1726 | 0 | struct tm *tm; |
1727 | |
|
1728 | 0 | t = time (NULL); |
1729 | | #if defined(HAVE_LOCALTIME_S) |
1730 | | localtime_s (&tms, &t); |
1731 | | tm = &tms; |
1732 | | #elif defined(HAVE_LOCALTIME_R) |
1733 | | tm = localtime_r (&t, &tms); |
1734 | | #else |
1735 | | tm = localtime (&t); |
1736 | | #endif |
1737 | 0 | e->components = 20; |
1738 | 0 | e->format = EXIF_FORMAT_ASCII; |
1739 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1740 | 0 | e->data = exif_entry_alloc (e, e->size); |
1741 | 0 | if (!e->data) { clear_entry(e); break; } |
1742 | 0 | snprintf ((char *) e->data, e->size, |
1743 | 0 | "%04i:%02i:%02i %02i:%02i:%02i", |
1744 | 0 | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, |
1745 | 0 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
1746 | 0 | break; |
1747 | 0 | } |
1748 | | |
1749 | | /* ASCII, no default */ |
1750 | 0 | case EXIF_TAG_SUB_SEC_TIME: |
1751 | 0 | case EXIF_TAG_SUB_SEC_TIME_ORIGINAL: |
1752 | 0 | case EXIF_TAG_SUB_SEC_TIME_DIGITIZED: |
1753 | 0 | case EXIF_TAG_OFFSET_TIME: |
1754 | 0 | case EXIF_TAG_OFFSET_TIME_ORIGINAL: |
1755 | 0 | case EXIF_TAG_OFFSET_TIME_DIGITIZED: |
1756 | 0 | e->components = 0; |
1757 | 0 | e->format = EXIF_FORMAT_ASCII; |
1758 | 0 | e->size = 0; |
1759 | 0 | e->data = NULL; |
1760 | 0 | break; |
1761 | | |
1762 | | /* ASCII, default "[None]" */ |
1763 | 0 | case EXIF_TAG_IMAGE_DESCRIPTION: |
1764 | 0 | case EXIF_TAG_MAKE: |
1765 | 0 | case EXIF_TAG_MODEL: |
1766 | 0 | case EXIF_TAG_SOFTWARE: |
1767 | 0 | case EXIF_TAG_ARTIST: |
1768 | 0 | case EXIF_TAG_CAMERA_OWNER_NAME: |
1769 | 0 | case EXIF_TAG_BODY_SERIAL_NUMBER: |
1770 | 0 | case EXIF_TAG_LENS_MAKE: |
1771 | 0 | case EXIF_TAG_LENS_MODEL: |
1772 | 0 | case EXIF_TAG_LENS_SERIAL_NUMBER: |
1773 | 0 | e->components = strlen (_("[None]")) + 1; |
1774 | 0 | e->format = EXIF_FORMAT_ASCII; |
1775 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1776 | 0 | e->data = exif_entry_alloc (e, e->size); |
1777 | 0 | if (!e->data) { clear_entry(e); break; } |
1778 | 0 | strncpy ((char *)e->data, _("[None]"), e->size); |
1779 | 0 | break; |
1780 | | /* ASCII, default "[None]\0[None]\0" */ |
1781 | 0 | case EXIF_TAG_COPYRIGHT: |
1782 | 0 | e->components = (strlen (_("[None]")) + 1) * 2; |
1783 | 0 | e->format = EXIF_FORMAT_ASCII; |
1784 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1785 | 0 | e->data = exif_entry_alloc (e, e->size); |
1786 | 0 | if (!e->data) { clear_entry(e); break; } |
1787 | 0 | strcpy (((char *)e->data) + 0, _("[None]")); |
1788 | 0 | strcpy (((char *)e->data) + strlen (_("[None]")) + 1, _("[None]")); |
1789 | 0 | break; |
1790 | | |
1791 | | /* UNDEFINED, 1 component, default 1 */ |
1792 | 0 | case EXIF_TAG_SCENE_TYPE: |
1793 | 0 | e->components = 1; |
1794 | 0 | e->format = EXIF_FORMAT_UNDEFINED; |
1795 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1796 | 0 | e->data = exif_entry_alloc (e, e->size); |
1797 | 0 | if (!e->data) { clear_entry(e); break; } |
1798 | 0 | e->data[0] = 0x01; |
1799 | 0 | break; |
1800 | | |
1801 | | /* UNDEFINED, 1 component, default 3 */ |
1802 | 0 | case EXIF_TAG_FILE_SOURCE: |
1803 | 0 | e->components = 1; |
1804 | 0 | e->format = EXIF_FORMAT_UNDEFINED; |
1805 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1806 | 0 | e->data = exif_entry_alloc (e, e->size); |
1807 | 0 | if (!e->data) { clear_entry(e); break; } |
1808 | 0 | e->data[0] = 0x03; |
1809 | 0 | break; |
1810 | | |
1811 | | /* UNDEFINED, 4 components, default 48 49 48 48 */ |
1812 | 19.7k | case EXIF_TAG_FLASH_PIX_VERSION: |
1813 | 19.7k | e->components = 4; |
1814 | 19.7k | e->format = EXIF_FORMAT_UNDEFINED; |
1815 | 19.7k | e->size = exif_format_get_size (e->format) * e->components; |
1816 | 19.7k | e->data = exif_entry_alloc (e, e->size); |
1817 | 19.7k | if (!e->data) { clear_entry(e); break; } |
1818 | 19.7k | memcpy (e->data, "0100", 4); |
1819 | 19.7k | break; |
1820 | | |
1821 | | /* UNDEFINED, 4 components, default 48 50 49 48 */ |
1822 | 19.7k | case EXIF_TAG_EXIF_VERSION: |
1823 | 19.7k | e->components = 4; |
1824 | 19.7k | e->format = EXIF_FORMAT_UNDEFINED; |
1825 | 19.7k | e->size = exif_format_get_size (e->format) * e->components; |
1826 | 19.7k | e->data = exif_entry_alloc (e, e->size); |
1827 | 19.7k | if (!e->data) { clear_entry(e); break; } |
1828 | 19.7k | memcpy (e->data, "0210", 4); |
1829 | 19.7k | break; |
1830 | | |
1831 | | /* UNDEFINED, 4 components, default 1 2 3 0 */ |
1832 | 0 | case EXIF_TAG_COMPONENTS_CONFIGURATION: |
1833 | 0 | e->components = 4; |
1834 | 0 | e->format = EXIF_FORMAT_UNDEFINED; |
1835 | 0 | e->size = exif_format_get_size (e->format) * e->components; |
1836 | 0 | e->data = exif_entry_alloc (e, e->size); |
1837 | 0 | if (!e->data) { clear_entry(e); break; } |
1838 | 0 | e->data[0] = 1; |
1839 | 0 | e->data[1] = 2; |
1840 | 0 | e->data[2] = 3; |
1841 | 0 | e->data[3] = 0; |
1842 | 0 | break; |
1843 | | |
1844 | | /* UNDEFINED, no components, no default */ |
1845 | | /* Use this if the tag is otherwise unsupported */ |
1846 | 0 | case EXIF_TAG_MAKER_NOTE: |
1847 | 0 | case EXIF_TAG_USER_COMMENT: |
1848 | 0 | default: |
1849 | 0 | e->components = 0; |
1850 | 0 | e->format = EXIF_FORMAT_UNDEFINED; |
1851 | 0 | e->size = 0; |
1852 | | e->data = NULL; |
1853 | 0 | break; |
1854 | 120k | } |
1855 | 120k | } |