Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: libexif/sources/libexif/exif-entry.c

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

Powered by Google App Engine
This is Rietveld 408576698