00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <libexif/exif-entry.h>
00024 #include <libexif/exif-ifd.h>
00025 #include <libexif/exif-utils.h>
00026 #include <libexif/i18n.h>
00027
00028 #include <ctype.h>
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <time.h>
00033 #include <math.h>
00034
00035 #ifndef M_PI
00036 #define M_PI 3.14159265358979323846
00037 #endif
00038
00039 struct _ExifEntryPrivate
00040 {
00041 unsigned int ref_count;
00042
00043 ExifMem *mem;
00044 };
00045
00046
00047 ExifLog *exif_data_get_log (ExifData *);
00048
00049 #ifndef NO_VERBOSE_TAG_STRINGS
00050 static void
00051 exif_entry_log (ExifEntry *e, ExifLogCode code, const char *format, ...)
00052 {
00053 va_list args;
00054 ExifLog *l = NULL;
00055
00056 if (e && e->parent && e->parent->parent)
00057 l = exif_data_get_log (e->parent->parent);
00058 va_start (args, format);
00059 exif_logv (l, code, "ExifEntry", format, args);
00060 va_end (args);
00061 }
00062 #else
00063 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
00064 #define exif_entry_log(...) do { } while (0)
00065 #elif defined(__GNUC__)
00066 #define exif_entry_log(x...) do { } while (0)
00067 #else
00068 #define exif_entry_log (void)
00069 #endif
00070 #endif
00071
00072 static void *
00073 exif_entry_alloc (ExifEntry *e, unsigned int i)
00074 {
00075 void *d;
00076 ExifLog *l = NULL;
00077
00078 if (!e || !e->priv || !i) return NULL;
00079
00080 d = exif_mem_alloc (e->priv->mem, i);
00081 if (d) return d;
00082
00083 if (e->parent && e->parent->parent)
00084 l = exif_data_get_log (e->parent->parent);
00085 EXIF_LOG_NO_MEMORY (l, "ExifEntry", i);
00086 return NULL;
00087 }
00088
00089 static void *
00090 exif_entry_realloc (ExifEntry *e, void *d_orig, unsigned int i)
00091 {
00092 void *d;
00093 ExifLog *l = NULL;
00094
00095 if (!e || !e->priv) return NULL;
00096
00097 if (!i) { exif_mem_free (e->priv->mem, d_orig); return NULL; }
00098
00099 d = exif_mem_realloc (e->priv->mem, d_orig, i);
00100 if (d) return d;
00101
00102 if (e->parent && e->parent->parent)
00103 l = exif_data_get_log (e->parent->parent);
00104 EXIF_LOG_NO_MEMORY (l, "ExifEntry", i);
00105 return NULL;
00106 }
00107
00108 ExifEntry *
00109 exif_entry_new (void)
00110 {
00111 ExifMem *mem = exif_mem_new_default ();
00112 ExifEntry *e = exif_entry_new_mem (mem);
00113
00114 exif_mem_unref (mem);
00115
00116 return e;
00117 }
00118
00119 ExifEntry *
00120 exif_entry_new_mem (ExifMem *mem)
00121 {
00122 ExifEntry *e = NULL;
00123
00124 e = exif_mem_alloc (mem, sizeof (ExifEntry));
00125 if (!e) return NULL;
00126 e->priv = exif_mem_alloc (mem, sizeof (ExifEntryPrivate));
00127 if (!e->priv) { exif_mem_free (mem, e); return NULL; }
00128 e->priv->ref_count = 1;
00129
00130 e->priv->mem = mem;
00131 exif_mem_ref (mem);
00132
00133 return e;
00134 }
00135
00136 void
00137 exif_entry_ref (ExifEntry *e)
00138 {
00139 if (!e) return;
00140
00141 e->priv->ref_count++;
00142 }
00143
00144 void
00145 exif_entry_unref (ExifEntry *e)
00146 {
00147 if (!e) return;
00148
00149 e->priv->ref_count--;
00150 if (!e->priv->ref_count)
00151 exif_entry_free (e);
00152 }
00153
00154 void
00155 exif_entry_free (ExifEntry *e)
00156 {
00157 if (!e) return;
00158
00159 if (e->priv) {
00160 ExifMem *mem = e->priv->mem;
00161 if (e->data)
00162 exif_mem_free (mem, e->data);
00163 exif_mem_free (mem, e->priv);
00164 exif_mem_free (mem, e);
00165 exif_mem_unref (mem);
00166 }
00167 }
00168
00173 static inline ExifShort
00174 exif_get_short_convert (const unsigned char *buf, ExifFormat format,
00175 ExifByteOrder order)
00176 {
00177 switch (format) {
00178 case EXIF_FORMAT_LONG:
00179 return (ExifShort) exif_get_long (buf, order);
00180 case EXIF_FORMAT_SLONG:
00181 return (ExifShort) exif_get_slong (buf, order);
00182 case EXIF_FORMAT_SHORT:
00183 return (ExifShort) exif_get_short (buf, order);
00184 case EXIF_FORMAT_SSHORT:
00185 return (ExifShort) exif_get_sshort (buf, order);
00186 case EXIF_FORMAT_BYTE:
00187 case EXIF_FORMAT_SBYTE:
00188 return (ExifShort) buf[0];
00189 default:
00190
00191 return (ExifShort) 0;
00192 }
00193 }
00194
00195 void
00196 exif_entry_fix (ExifEntry *e)
00197 {
00198 unsigned int i, newsize;
00199 unsigned char *newdata;
00200 ExifByteOrder o;
00201 ExifRational r;
00202 ExifSRational sr;
00203
00204 if (!e || !e->priv) return;
00205
00206 switch (e->tag) {
00207
00208
00209 case EXIF_TAG_YCBCR_SUB_SAMPLING:
00210 case EXIF_TAG_SUBJECT_AREA:
00211 case EXIF_TAG_COLOR_SPACE:
00212 case EXIF_TAG_PLANAR_CONFIGURATION:
00213 case EXIF_TAG_SENSING_METHOD:
00214 case EXIF_TAG_ORIENTATION:
00215 case EXIF_TAG_YCBCR_POSITIONING:
00216 case EXIF_TAG_PHOTOMETRIC_INTERPRETATION:
00217 case EXIF_TAG_CUSTOM_RENDERED:
00218 case EXIF_TAG_EXPOSURE_MODE:
00219 case EXIF_TAG_WHITE_BALANCE:
00220 case EXIF_TAG_SCENE_CAPTURE_TYPE:
00221 case EXIF_TAG_GAIN_CONTROL:
00222 case EXIF_TAG_SATURATION:
00223 case EXIF_TAG_CONTRAST:
00224 case EXIF_TAG_SHARPNESS:
00225 case EXIF_TAG_ISO_SPEED_RATINGS:
00226 switch (e->format) {
00227 case EXIF_FORMAT_LONG:
00228 case EXIF_FORMAT_SLONG:
00229 case EXIF_FORMAT_BYTE:
00230 case EXIF_FORMAT_SBYTE:
00231 case EXIF_FORMAT_SSHORT:
00232 if (!e->parent || !e->parent->parent) break;
00233 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00234 _("Tag '%s' was of format '%s' (which is "
00235 "against specification) and has been "
00236 "changed to format '%s'."),
00237 exif_tag_get_name_in_ifd(e->tag,
00238 exif_entry_get_ifd(e)),
00239 exif_format_get_name (e->format),
00240 exif_format_get_name (EXIF_FORMAT_SHORT));
00241
00242 o = exif_data_get_byte_order (e->parent->parent);
00243 newsize = e->components * exif_format_get_size (EXIF_FORMAT_SHORT);
00244 newdata = exif_entry_alloc (e, newsize);
00245 if (!newdata) {
00246 exif_entry_log (e, EXIF_LOG_CODE_NO_MEMORY,
00247 "Could not allocate %lu byte(s).", (unsigned long)newsize);
00248 break;
00249 }
00250
00251 for (i = 0; i < e->components; i++)
00252 exif_set_short (
00253 newdata + i *
00254 exif_format_get_size (
00255 EXIF_FORMAT_SHORT), o,
00256 exif_get_short_convert (
00257 e->data + i *
00258 exif_format_get_size (e->format),
00259 e->format, o));
00260
00261 exif_mem_free (e->priv->mem, e->data);
00262 e->data = newdata;
00263 e->size = newsize;
00264 e->format = EXIF_FORMAT_SHORT;
00265 break;
00266 case EXIF_FORMAT_SHORT:
00267
00268 break;
00269 default:
00270 exif_entry_log (e, EXIF_LOG_CODE_CORRUPT_DATA,
00271 _("Tag '%s' is of format '%s' (which is "
00272 "against specification) but cannot be changed "
00273 "to format '%s'."),
00274 exif_tag_get_name_in_ifd(e->tag,
00275 exif_entry_get_ifd(e)),
00276 exif_format_get_name (e->format),
00277 exif_format_get_name (EXIF_FORMAT_SHORT));
00278 break;
00279 }
00280 break;
00281
00282
00283 case EXIF_TAG_FNUMBER:
00284 case EXIF_TAG_APERTURE_VALUE:
00285 case EXIF_TAG_EXPOSURE_TIME:
00286 case EXIF_TAG_FOCAL_LENGTH:
00287 switch (e->format) {
00288 case EXIF_FORMAT_SRATIONAL:
00289 if (!e->parent || !e->parent->parent) break;
00290 o = exif_data_get_byte_order (e->parent->parent);
00291 for (i = 0; i < e->components; i++) {
00292 sr = exif_get_srational (e->data + i *
00293 exif_format_get_size (
00294 EXIF_FORMAT_SRATIONAL), o);
00295 r.numerator = (ExifLong) sr.numerator;
00296 r.denominator = (ExifLong) sr.denominator;
00297 exif_set_rational (e->data + i *
00298 exif_format_get_size (
00299 EXIF_FORMAT_RATIONAL), o, r);
00300 }
00301 e->format = EXIF_FORMAT_RATIONAL;
00302 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00303 _("Tag '%s' was of format '%s' (which is "
00304 "against specification) and has been "
00305 "changed to format '%s'."),
00306 exif_tag_get_name_in_ifd(e->tag,
00307 exif_entry_get_ifd(e)),
00308 exif_format_get_name (EXIF_FORMAT_SRATIONAL),
00309 exif_format_get_name (EXIF_FORMAT_RATIONAL));
00310 break;
00311 default:
00312 break;
00313 }
00314 break;
00315
00316
00317 case EXIF_TAG_EXPOSURE_BIAS_VALUE:
00318 case EXIF_TAG_BRIGHTNESS_VALUE:
00319 case EXIF_TAG_SHUTTER_SPEED_VALUE:
00320 switch (e->format) {
00321 case EXIF_FORMAT_RATIONAL:
00322 if (!e->parent || !e->parent->parent) break;
00323 o = exif_data_get_byte_order (e->parent->parent);
00324 for (i = 0; i < e->components; i++) {
00325 r = exif_get_rational (e->data + i *
00326 exif_format_get_size (
00327 EXIF_FORMAT_RATIONAL), o);
00328 sr.numerator = (ExifLong) r.numerator;
00329 sr.denominator = (ExifLong) r.denominator;
00330 exif_set_srational (e->data + i *
00331 exif_format_get_size (
00332 EXIF_FORMAT_SRATIONAL), o, sr);
00333 }
00334 e->format = EXIF_FORMAT_SRATIONAL;
00335 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00336 _("Tag '%s' was of format '%s' (which is "
00337 "against specification) and has been "
00338 "changed to format '%s'."),
00339 exif_tag_get_name_in_ifd(e->tag,
00340 exif_entry_get_ifd(e)),
00341 exif_format_get_name (EXIF_FORMAT_RATIONAL),
00342 exif_format_get_name (EXIF_FORMAT_SRATIONAL));
00343 break;
00344 default:
00345 break;
00346 }
00347 break;
00348
00349 case EXIF_TAG_USER_COMMENT:
00350
00351
00352 if (e->format != EXIF_FORMAT_UNDEFINED) {
00353 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00354 _("Tag 'UserComment' had invalid format '%s'. "
00355 "Format has been set to 'undefined'."),
00356 exif_format_get_name (e->format));
00357 e->format = EXIF_FORMAT_UNDEFINED;
00358 }
00359
00360
00361
00362 if ((e->size >= 8) && (e->data[0] == 0)) {
00363 memcpy(e->data, "\0\0\0\0\0\0\0\0", 8);
00364 }
00365
00366
00367 if (e->size < 8) {
00368 e->data = exif_entry_realloc (e, e->data, 8 + e->size);
00369 if (!e->data) {
00370 e->size = 0;
00371 e->components = 0;
00372 return;
00373 }
00374
00375
00376 memmove (e->data + 8, e->data, e->size);
00377 memcpy (e->data, "ASCII\0\0\0", 8);
00378 e->size += 8;
00379 e->components += 8;
00380 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00381 _("Tag 'UserComment' has been expanded to at "
00382 "least 8 bytes in order to follow the "
00383 "specification."));
00384 break;
00385 }
00386
00387
00388
00389
00390
00391
00392 for (i = 0; (i < e->size) && !e->data[i]; i++);
00393 if (!i) for ( ; (i < e->size) && (e->data[i] == ' '); i++);
00394 if ((i >= 8) && (i < e->size)) {
00395 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00396 _("Tag 'UserComment' is not empty but does not "
00397 "start with a format identifier. "
00398 "This has been fixed."));
00399 memcpy (e->data, "ASCII\0\0\0", 8);
00400 break;
00401 }
00402
00403
00404
00405
00406
00407 if (memcmp (e->data, "ASCII\0\0\0" , 8) &&
00408 memcmp (e->data, "UNICODE\0" , 8) &&
00409 memcmp (e->data, "JIS\0\0\0\0\0" , 8) &&
00410 memcmp (e->data, "\0\0\0\0\0\0\0\0", 8)) {
00411 e->data = exif_entry_realloc (e, e->data, 8 + e->size);
00412 if (!e->data) {
00413 e->size = 0;
00414 e->components = 0;
00415 break;
00416 }
00417
00418
00419 memmove (e->data + 8, e->data, e->size);
00420 memcpy (e->data, "ASCII\0\0\0", 8);
00421 e->size += 8;
00422 e->components += 8;
00423 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00424 _("Tag 'UserComment' did not start with a "
00425 "format identifier. This has been fixed."));
00426 break;
00427 }
00428
00429 break;
00430 default:
00431 break;
00432 }
00433 }
00434
00443 static void
00444 exif_entry_format_value(ExifEntry *e, char *val, size_t maxlen)
00445 {
00446 ExifByte v_byte;
00447 ExifShort v_short;
00448 ExifSShort v_sshort;
00449 ExifLong v_long;
00450 ExifRational v_rat;
00451 ExifSRational v_srat;
00452 ExifSLong v_slong;
00453 unsigned int i;
00454 size_t len;
00455 const ExifByteOrder o = exif_data_get_byte_order (e->parent->parent);
00456
00457 if (!e->size || !maxlen)
00458 return;
00459 ++maxlen;
00460 switch (e->format) {
00461 case EXIF_FORMAT_UNDEFINED:
00462 snprintf (val, maxlen, _("%i bytes undefined data"), e->size);
00463 break;
00464 case EXIF_FORMAT_BYTE:
00465 case EXIF_FORMAT_SBYTE:
00466 v_byte = e->data[0];
00467 snprintf (val, maxlen, "0x%02x", v_byte);
00468 len = strlen (val);
00469 for (i = 1; i < e->components; i++) {
00470 v_byte = e->data[i];
00471 snprintf (val+len, maxlen-len, ", 0x%02x", v_byte);
00472 len += strlen (val+len);
00473 if (len >= maxlen-1) break;
00474 }
00475 break;
00476 case EXIF_FORMAT_SHORT:
00477 v_short = exif_get_short (e->data, o);
00478 snprintf (val, maxlen, "%u", v_short);
00479 len = strlen (val);
00480 for (i = 1; i < e->components; i++) {
00481 v_short = exif_get_short (e->data +
00482 exif_format_get_size (e->format) * i, o);
00483 snprintf (val+len, maxlen-len, ", %u", v_short);
00484 len += strlen (val+len);
00485 if (len >= maxlen-1) break;
00486 }
00487 break;
00488 case EXIF_FORMAT_SSHORT:
00489 v_sshort = exif_get_sshort (e->data, o);
00490 snprintf (val, maxlen, "%i", v_sshort);
00491 len = strlen (val);
00492 for (i = 1; i < e->components; i++) {
00493 v_sshort = exif_get_short (e->data +
00494 exif_format_get_size (e->format) *
00495 i, o);
00496 snprintf (val+len, maxlen-len, ", %i", v_sshort);
00497 len += strlen (val+len);
00498 if (len >= maxlen-1) break;
00499 }
00500 break;
00501 case EXIF_FORMAT_LONG:
00502 v_long = exif_get_long (e->data, o);
00503 snprintf (val, maxlen, "%lu", (unsigned long) v_long);
00504 len = strlen (val);
00505 for (i = 1; i < e->components; i++) {
00506 v_long = exif_get_long (e->data +
00507 exif_format_get_size (e->format) *
00508 i, o);
00509 snprintf (val+len, maxlen-len, ", %lu", (unsigned long) v_long);
00510 len += strlen (val+len);
00511 if (len >= maxlen-1) break;
00512 }
00513 break;
00514 case EXIF_FORMAT_SLONG:
00515 v_slong = exif_get_slong (e->data, o);
00516 snprintf (val, maxlen, "%li", (long) v_slong);
00517 len = strlen (val);
00518 for (i = 1; i < e->components; i++) {
00519 v_slong = exif_get_slong (e->data +
00520 exif_format_get_size (e->format) * i, o);
00521 snprintf (val+len, maxlen-len, ", %li", (long) v_slong);
00522 len += strlen (val+len);
00523 if (len >= maxlen-1) break;
00524 }
00525 break;
00526 case EXIF_FORMAT_ASCII:
00527 strncpy (val, (char *) e->data, MIN (maxlen-1, e->size));
00528 val[MIN (maxlen-1, e->size)] = 0;
00529 break;
00530 case EXIF_FORMAT_RATIONAL:
00531 len = 0;
00532 for (i = 0; i < e->components; i++) {
00533 if (i > 0) {
00534 snprintf (val+len, maxlen-len, ", ");
00535 len += strlen (val+len);
00536 }
00537 v_rat = exif_get_rational (
00538 e->data + 8 * i, o);
00539 if (v_rat.denominator) {
00540
00541
00542
00543
00544
00545
00546 int decimals = (int)(log10(v_rat.denominator)-0.08+1.0);
00547 snprintf (val+len, maxlen-len, "%2.*f",
00548 decimals,
00549 (double) v_rat.numerator /
00550 (double) v_rat.denominator);
00551 } else
00552 snprintf (val+len, maxlen-len, "%lu/%lu",
00553 (unsigned long) v_rat.numerator,
00554 (unsigned long) v_rat.denominator);
00555 len += strlen (val+len);
00556 if (len >= maxlen-1) break;
00557 }
00558 break;
00559 case EXIF_FORMAT_SRATIONAL:
00560 len = 0;
00561 for (i = 0; i < e->components; i++) {
00562 if (i > 0) {
00563 snprintf (val+len, maxlen-len, ", ");
00564 len += strlen (val+len);
00565 }
00566 v_srat = exif_get_srational (
00567 e->data + 8 * i, o);
00568 if (v_srat.denominator) {
00569 int decimals = (int)(log10(fabs(v_srat.denominator))-0.08+1.0);
00570 snprintf (val+len, maxlen-len, "%2.*f",
00571 decimals,
00572 (double) v_srat.numerator /
00573 (double) v_srat.denominator);
00574 } else
00575 snprintf (val+len, maxlen-len, "%li/%li",
00576 (long) v_srat.numerator,
00577 (long) v_srat.denominator);
00578 len += strlen (val+len);
00579 if (len >= maxlen-1) break;
00580 }
00581 break;
00582 case EXIF_FORMAT_DOUBLE:
00583 case EXIF_FORMAT_FLOAT:
00584 default:
00585 snprintf (val, maxlen, _("%i bytes unsupported data type"),
00586 e->size);
00587 break;
00588 }
00589 }
00590
00591 void
00592 exif_entry_dump (ExifEntry *e, unsigned int indent)
00593 {
00594 char buf[1024];
00595 char value[1024];
00596 unsigned int i;
00597
00598 for (i = 0; i < 2 * indent; i++)
00599 buf[i] = ' ';
00600 buf[i] = '\0';
00601
00602 if (!e)
00603 return;
00604
00605 printf ("%sTag: 0x%x ('%s')\n", buf, e->tag,
00606 exif_tag_get_name_in_ifd (e->tag, exif_entry_get_ifd(e)));
00607 printf ("%s Format: %i ('%s')\n", buf, e->format,
00608 exif_format_get_name (e->format));
00609 printf ("%s Components: %i\n", buf, (int) e->components);
00610 printf ("%s Size: %i\n", buf, e->size);
00611 printf ("%s Value: %s\n", buf, exif_entry_get_value (e, value, sizeof(value)));
00612 }
00613
00623 static int
00624 match_repeated_char(const unsigned char *data, unsigned char ch, size_t n)
00625 {
00626 int i;
00627 for (i=n; i; --i, ++data) {
00628 if (*data == 0) {
00629 i = 0;
00630 break;
00631 }
00632 if (*data != ch)
00633 break;
00634 }
00635 return i;
00636 }
00637
00638 #define CF(entry,target,v,maxlen) \
00639 { \
00640 if (entry->format != target) { \
00641 exif_entry_log (entry, EXIF_LOG_CODE_CORRUPT_DATA, \
00642 _("The tag '%s' contains data of an invalid " \
00643 "format ('%s', expected '%s')."), \
00644 exif_tag_get_name (entry->tag), \
00645 exif_format_get_name (entry->format), \
00646 exif_format_get_name (target)); \
00647 break; \
00648 } \
00649 }
00650
00651 #define CC(entry,target,v,maxlen) \
00652 { \
00653 if (entry->components != target) { \
00654 exif_entry_log (entry, EXIF_LOG_CODE_CORRUPT_DATA, \
00655 _("The tag '%s' contains an invalid number of " \
00656 "components (%i, expected %i)."), \
00657 exif_tag_get_name (entry->tag), \
00658 (int) entry->components, (int) target); \
00659 break; \
00660 } \
00661 }
00662
00663 static const struct {
00664 ExifTag tag;
00665 const char *strings[10];
00666 } list[] = {
00667 #ifndef NO_VERBOSE_TAG_DATA
00668 { EXIF_TAG_PLANAR_CONFIGURATION,
00669 { N_("Chunky format"), N_("Planar format"), NULL}},
00670 { EXIF_TAG_SENSING_METHOD,
00671 { "", N_("Not defined"), N_("One-chip color area sensor"),
00672 N_("Two-chip color area sensor"), N_("Three-chip color area sensor"),
00673 N_("Color sequential area sensor"), "", N_("Trilinear sensor"),
00674 N_("Color sequential linear sensor"), NULL}},
00675 { EXIF_TAG_ORIENTATION,
00676 { "", N_("Top-left"), N_("Top-right"), N_("Bottom-right"),
00677 N_("Bottom-left"), N_("Left-top"), N_("Right-top"),
00678 N_("Right-bottom"), N_("Left-bottom"), NULL}},
00679 { EXIF_TAG_YCBCR_POSITIONING,
00680 { "", N_("Centered"), N_("Co-sited"), NULL}},
00681 { EXIF_TAG_PHOTOMETRIC_INTERPRETATION,
00682 { N_("Reversed mono"), N_("Normal mono"), N_("RGB"), N_("Palette"), "",
00683 N_("CMYK"), N_("YCbCr"), "", N_("CieLAB"), NULL}},
00684 { EXIF_TAG_CUSTOM_RENDERED,
00685 { N_("Normal process"), N_("Custom process"), NULL}},
00686 { EXIF_TAG_EXPOSURE_MODE,
00687 { N_("Auto exposure"), N_("Manual exposure"), N_("Auto bracket"), NULL}},
00688 { EXIF_TAG_WHITE_BALANCE,
00689 { N_("Auto white balance"), N_("Manual white balance"), NULL}},
00690 { EXIF_TAG_SCENE_CAPTURE_TYPE,
00691 { N_("Standard"), N_("Landscape"), N_("Portrait"),
00692 N_("Night scene"), NULL}},
00693 { EXIF_TAG_GAIN_CONTROL,
00694 { N_("Normal"), N_("Low gain up"), N_("High gain up"),
00695 N_("Low gain down"), N_("High gain down"), NULL}},
00696 { EXIF_TAG_SATURATION,
00697 { N_("Normal"), N_("Low saturation"), N_("High saturation"), NULL}},
00698 { EXIF_TAG_CONTRAST , {N_("Normal"), N_("Soft"), N_("Hard"), NULL}},
00699 { EXIF_TAG_SHARPNESS, {N_("Normal"), N_("Soft"), N_("Hard"), NULL}},
00700 #endif
00701 { 0, {NULL}}
00702 };
00703
00704 static const struct {
00705 ExifTag tag;
00706 struct {
00707 int index;
00708 const char *values[4];
00711 } elem[25];
00712 } list2[] = {
00713 #ifndef NO_VERBOSE_TAG_DATA
00714 { EXIF_TAG_METERING_MODE,
00715 { { 0, {N_("Unknown"), NULL}},
00716 { 1, {N_("Average"), N_("Avg"), NULL}},
00717 { 2, {N_("Center-weighted average"), N_("Center-weight"), NULL}},
00718 { 3, {N_("Spot"), NULL}},
00719 { 4, {N_("Multi spot"), NULL}},
00720 { 5, {N_("Pattern"), NULL}},
00721 { 6, {N_("Partial"), NULL}},
00722 {255, {N_("Other"), NULL}},
00723 { 0, {NULL}}}},
00724 { EXIF_TAG_COMPRESSION,
00725 { {1, {N_("Uncompressed"), NULL}},
00726 {5, {N_("LZW compression"), NULL}},
00727 {6, {N_("JPEG compression"), NULL}},
00728 {7, {N_("JPEG compression"), NULL}},
00729 {8, {N_("Deflate/ZIP compression"), NULL}},
00730 {32773, {N_("PackBits compression"), NULL}},
00731 {0, {NULL}}}},
00732 { EXIF_TAG_LIGHT_SOURCE,
00733 { { 0, {N_("Unknown"), NULL}},
00734 { 1, {N_("Daylight"), NULL}},
00735 { 2, {N_("Fluorescent"), NULL}},
00736 { 3, {N_("Tungsten incandescent light"), N_("Tungsten"), NULL}},
00737 { 4, {N_("Flash"), NULL}},
00738 { 9, {N_("Fine weather"), NULL}},
00739 { 10, {N_("Cloudy weather"), N_("Cloudy"), NULL}},
00740 { 11, {N_("Shade"), NULL}},
00741 { 12, {N_("Daylight fluorescent"), NULL}},
00742 { 13, {N_("Day white fluorescent"), NULL}},
00743 { 14, {N_("Cool white fluorescent"), NULL}},
00744 { 15, {N_("White fluorescent"), NULL}},
00745 { 17, {N_("Standard light A"), NULL}},
00746 { 18, {N_("Standard light B"), NULL}},
00747 { 19, {N_("Standard light C"), NULL}},
00748 { 20, {N_("D55"), NULL}},
00749 { 21, {N_("D65"), NULL}},
00750 { 22, {N_("D75"), NULL}},
00751 { 24, {N_("ISO studio tungsten"),NULL}},
00752 {255, {N_("Other"), NULL}},
00753 { 0, {NULL}}}},
00754 { EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT,
00755 { {2, {N_("Inch"), N_("in"), NULL}},
00756 {3, {N_("Centimeter"), N_("cm"), NULL}},
00757 {0, {NULL}}}},
00758 { EXIF_TAG_RESOLUTION_UNIT,
00759 { {2, {N_("Inch"), N_("in"), NULL}},
00760 {3, {N_("Centimeter"), N_("cm"), NULL}},
00761 {0, {NULL}}}},
00762 { EXIF_TAG_EXPOSURE_PROGRAM,
00763 { {0, {N_("Not defined"), NULL}},
00764 {1, {N_("Manual"), NULL}},
00765 {2, {N_("Normal program"), N_("Normal"), NULL}},
00766 {3, {N_("Aperture priority"), N_("Aperture"), NULL}},
00767 {4, {N_("Shutter priority"),N_("Shutter"), NULL}},
00768 {5, {N_("Creative program (biased toward depth of field)"),
00769 N_("Creative"), NULL}},
00770 {6, {N_("Creative program (biased toward fast shutter speed)"),
00771 N_("Action"), NULL}},
00772 {7, {N_("Portrait mode (for closeup photos with the background out "
00773 "of focus)"), N_("Portrait"), NULL}},
00774 {8, {N_("Landscape mode (for landscape photos with the background "
00775 "in focus)"), N_("Landscape"), NULL}},
00776 {0, {NULL}}}},
00777 { EXIF_TAG_FLASH,
00778 { {0x0000, {N_("Flash did not fire"), N_("No flash"), NULL}},
00779 {0x0001, {N_("Flash fired"), N_("Flash"), N_("Yes"), NULL}},
00780 {0x0005, {N_("Strobe return light not detected"), N_("Without strobe"),
00781 NULL}},
00782 {0x0007, {N_("Strobe return light detected"), N_("With strobe"), NULL}},
00783 {0x0008, {N_("Flash did not fire"), NULL}},
00784 {0x0009, {N_("Flash fired, compulsory flash mode"), NULL}},
00785 {0x000d, {N_("Flash fired, compulsory flash mode, return light "
00786 "not detected"), NULL}},
00787 {0x000f, {N_("Flash fired, compulsory flash mode, return light "
00788 "detected"), NULL}},
00789 {0x0010, {N_("Flash did not fire, compulsory flash mode"), NULL}},
00790 {0x0018, {N_("Flash did not fire, auto mode"), NULL}},
00791 {0x0019, {N_("Flash fired, auto mode"), NULL}},
00792 {0x001d, {N_("Flash fired, auto mode, return light not detected"),
00793 NULL}},
00794 {0x001f, {N_("Flash fired, auto mode, return light detected"), NULL}},
00795 {0x0020, {N_("No flash function"),NULL}},
00796 {0x0041, {N_("Flash fired, red-eye reduction mode"), NULL}},
00797 {0x0045, {N_("Flash fired, red-eye reduction mode, return light "
00798 "not detected"), NULL}},
00799 {0x0047, {N_("Flash fired, red-eye reduction mode, return light "
00800 "detected"), NULL}},
00801 {0x0049, {N_("Flash fired, compulsory flash mode, red-eye reduction "
00802 "mode"), NULL}},
00803 {0x004d, {N_("Flash fired, compulsory flash mode, red-eye reduction "
00804 "mode, return light not detected"), NULL}},
00805 {0x004f, {N_("Flash fired, compulsory flash mode, red-eye reduction mode, "
00806 "return light detected"), NULL}},
00807 {0x0058, {N_("Flash did not fire, auto mode, red-eye reduction mode"), NULL}},
00808 {0x0059, {N_("Flash fired, auto mode, red-eye reduction mode"), NULL}},
00809 {0x005d, {N_("Flash fired, auto mode, return light not detected, "
00810 "red-eye reduction mode"), NULL}},
00811 {0x005f, {N_("Flash fired, auto mode, return light detected, "
00812 "red-eye reduction mode"), NULL}},
00813 {0x0000, {NULL}}}},
00814 { EXIF_TAG_SUBJECT_DISTANCE_RANGE,
00815 { {0, {N_("Unknown"), N_("?"), NULL}},
00816 {1, {N_("Macro"), NULL}},
00817 {2, {N_("Close view"), N_("Close"), NULL}},
00818 {3, {N_("Distant view"), N_("Distant"), NULL}},
00819 {0, {NULL}}}},
00820 { EXIF_TAG_COLOR_SPACE,
00821 { {1, {N_("sRGB"), NULL}},
00822 {2, {N_("Adobe RGB"), NULL}},
00823 {0xffff, {N_("Uncalibrated"), NULL}},
00824 {0x0000, {NULL}}}},
00825 #endif
00826 {0, { { 0, {NULL}}} }
00827 };
00828
00829 const char *
00830 exif_entry_get_value (ExifEntry *e, char *val, unsigned int maxlen)
00831 {
00832 unsigned int i, j, k;
00833 ExifShort v_short, v_short2, v_short3, v_short4;
00834 ExifByte v_byte;
00835 ExifRational v_rat;
00836 ExifSRational v_srat;
00837 char b[64];
00838 const char *c;
00839 ExifByteOrder o;
00840 double d;
00841 ExifEntry *entry;
00842 static const struct {
00843 char label[5];
00844 char major, minor;
00845 } versions[] = {
00846 {"0110", 1, 1},
00847 {"0120", 1, 2},
00848 {"0200", 2, 0},
00849 {"0210", 2, 1},
00850 {"0220", 2, 2},
00851 {"0221", 2, 21},
00852 {"0230", 2, 3},
00853 {"" , 0, 0}
00854 };
00855
00856
00857
00858
00859
00860
00861
00862
00863 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
00864
00865 if (!e || !e->parent || !e->parent->parent || !maxlen)
00866 return val;
00867
00868
00869 memset (val, 0, maxlen);
00870 maxlen--;
00871 memset (b, 0, sizeof (b));
00872
00873
00874 o = exif_data_get_byte_order (e->parent->parent);
00875
00876
00877 if (e->size != e->components * exif_format_get_size (e->format)) {
00878 snprintf (val, maxlen, _("Invalid size of entry (%i, "
00879 "expected %li x %i)."), e->size, e->components,
00880 exif_format_get_size (e->format));
00881 return val;
00882 }
00883
00884 switch (e->tag) {
00885 case EXIF_TAG_USER_COMMENT:
00886
00887
00888
00889
00890
00891
00892
00893 if ((e->format != EXIF_FORMAT_ASCII) ||
00894 (e->size <= 8) ||
00895 ( memcmp (e->data, "ASCII\0\0\0" , 8) &&
00896 memcmp (e->data, "UNICODE\0" , 8) &&
00897 memcmp (e->data, "JIS\0\0\0\0\0", 8) &&
00898 memcmp (e->data, "\0\0\0\0\0\0\0\0", 8)))
00899 CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen);
00900
00901
00902
00903
00904
00905
00906 if ((e->size >= 8) && !memcmp (e->data, "ASCII\0\0\0", 8)) {
00907 strncpy (val, (char *) e->data + 8, MIN (e->size - 8, maxlen));
00908 break;
00909 }
00910 if ((e->size >= 8) && !memcmp (e->data, "UNICODE\0", 8)) {
00911 strncpy (val, _("Unsupported UNICODE string"), maxlen);
00912
00913
00914
00915
00916 break;
00917 }
00918 if ((e->size >= 8) && !memcmp (e->data, "JIS\0\0\0\0\0", 8)) {
00919 strncpy (val, _("Unsupported JIS string"), maxlen);
00920
00921 break;
00922 }
00923
00924
00925 for (i = 0; (i < e->size) &&
00926 (!e->data[i] || (e->data[i] == ' ')); i++);
00927 if (i == e->size) break;
00928
00929
00930
00931
00932
00933
00934 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00935 _("Tag UserComment contains data but is "
00936 "against specification."));
00937 for (j = 0; (i < e->size) && (j < maxlen); i++, j++) {
00938 exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
00939 _("Byte at position %i: 0x%02x"), i, e->data[i]);
00940 val[j] = isprint (e->data[i]) ? e->data[i] : '.';
00941 }
00942 break;
00943
00944 case EXIF_TAG_EXIF_VERSION:
00945 CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen);
00946 CC (e, 4, val, maxlen);
00947 strncpy (val, _("Unknown Exif Version"), maxlen);
00948 for (i = 0; *versions[i].label; i++) {
00949 if (!memcmp (e->data, versions[i].label, 4)) {
00950 snprintf (val, maxlen,
00951 _("Exif Version %d.%d"),
00952 versions[i].major,
00953 versions[i].minor);
00954 break;
00955 }
00956 }
00957 break;
00958 case EXIF_TAG_FLASH_PIX_VERSION:
00959 CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen);
00960 CC (e, 4, val, maxlen);
00961 if (!memcmp (e->data, "0100", 4))
00962 strncpy (val, _("FlashPix Version 1.0"), maxlen);
00963 else if (!memcmp (e->data, "0101", 4))
00964 strncpy (val, _("FlashPix Version 1.01"), maxlen);
00965 else
00966 strncpy (val, _("Unknown FlashPix Version"), maxlen);
00967 break;
00968 case EXIF_TAG_COPYRIGHT:
00969 CF (e, EXIF_FORMAT_ASCII, val, maxlen);
00970
00971
00972
00973
00974
00975
00976 if (e->size && e->data && match_repeated_char(e->data, ' ', e->size))
00977 strncpy (val, (char *) e->data, MIN (maxlen, e->size));
00978 else
00979 strncpy (val, _("[None]"), maxlen);
00980 strncat (val, " ", maxlen - strlen (val));
00981 strncat (val, _("(Photographer)"), maxlen - strlen (val));
00982
00983
00984 strncat (val, " - ", maxlen - strlen (val));
00985 k = 0;
00986 if (e->size && e->data) {
00987 const unsigned char *tagdata = memchr(e->data, 0, e->size);
00988 if (tagdata++) {
00989 int editor_ofs = tagdata - e->data;
00990 int remaining = e->size - editor_ofs;
00991 if (match_repeated_char(tagdata, ' ', remaining)) {
00992 strncat (val, (const char*)tagdata, MIN (maxlen - strlen (val), remaining));
00993 ++k;
00994 }
00995 }
00996 }
00997 if (!k)
00998 strncat (val, _("[None]"), maxlen - strlen (val));
00999 strncat (val, " ", maxlen - strlen (val));
01000 strncat (val, _("(Editor)"), maxlen - strlen (val));
01001
01002 break;
01003 case EXIF_TAG_FNUMBER:
01004 CF (e, EXIF_FORMAT_RATIONAL, val, maxlen);
01005 CC (e, 1, val, maxlen);
01006 v_rat = exif_get_rational (e->data, o);
01007 if (!v_rat.denominator) {
01008 exif_entry_format_value(e, val, maxlen);
01009 break;
01010 }
01011 d = (double) v_rat.numerator / (double) v_rat.denominator;
01012 snprintf (val, maxlen, "f/%.01f", d);
01013 break;
01014 case EXIF_TAG_APERTURE_VALUE:
01015 case EXIF_TAG_MAX_APERTURE_VALUE:
01016 CF (e, EXIF_FORMAT_RATIONAL, val, maxlen);
01017 CC (e, 1, val, maxlen);
01018 v_rat = exif_get_rational (e->data, o);
01019 if (!v_rat.denominator || (0x80000000 == v_rat.numerator)) {
01020 exif_entry_format_value(e, val, maxlen);
01021 break;
01022 }
01023 d = (double) v_rat.numerator / (double) v_rat.denominator;
01024 snprintf (val, maxlen, _("%.02f EV"), d);
01025 snprintf (b, sizeof (b), _(" (f/%.01f)"), pow (2, d / 2.));
01026 if (maxlen > strlen (val) + strlen (b))
01027 strncat (val, b, maxlen - strlen (val));
01028 break;
01029 case EXIF_TAG_FOCAL_LENGTH:
01030 CF (e, EXIF_FORMAT_RATIONAL, val, maxlen);
01031 CC (e, 1, val, maxlen);
01032 v_rat = exif_get_rational (e->data, o);
01033 if (!v_rat.denominator) {
01034 exif_entry_format_value(e, val, maxlen);
01035 break;
01036 }
01037
01038
01039
01040
01041
01042
01043 d = 0.;
01044 entry = exif_content_get_entry (
01045 e->parent->parent->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
01046 if (entry && entry->data &&
01047 !strncmp ((char *)entry->data, "Minolta", 7)) {
01048 entry = exif_content_get_entry (
01049 e->parent->parent->ifd[EXIF_IFD_0],
01050 EXIF_TAG_MODEL);
01051 if (entry && entry->data) {
01052 if (!strncmp ((char *)entry->data, "DiMAGE 7", 8))
01053 d = 3.9;
01054 else if (!strncmp ((char *)entry->data, "DiMAGE 5", 8))
01055 d = 4.9;
01056 }
01057 }
01058 if (d)
01059 snprintf (b, sizeof (b), _(" (35 equivalent: %d mm)"),
01060 (int) (d * (double) v_rat.numerator /
01061 (double) v_rat.denominator));
01062
01063 d = (double) v_rat.numerator / (double) v_rat.denominator;
01064 snprintf (val, maxlen, "%.1f mm", d);
01065 if (maxlen > strlen (val) + strlen (b))
01066 strncat (val, b, maxlen - strlen (val));
01067 break;
01068 case EXIF_TAG_SUBJECT_DISTANCE:
01069 CF (e, EXIF_FORMAT_RATIONAL, val, maxlen);
01070 CC (e, 1, val, maxlen);
01071 v_rat = exif_get_rational (e->data, o);
01072 if (!v_rat.denominator) {
01073 exif_entry_format_value(e, val, maxlen);
01074 break;
01075 }
01076 d = (double) v_rat.numerator / (double) v_rat.denominator;
01077 snprintf (val, maxlen, "%.1f m", d);
01078 break;
01079 case EXIF_TAG_EXPOSURE_TIME:
01080 CF (e, EXIF_FORMAT_RATIONAL, val, maxlen);
01081 CC (e, 1, val, maxlen);
01082 v_rat = exif_get_rational (e->data, o);
01083 if (!v_rat.denominator) {
01084 exif_entry_format_value(e, val, maxlen);
01085 break;
01086 }
01087 d = (double) v_rat.numerator / (double) v_rat.denominator;
01088 if (d < 1)
01089 snprintf (val, maxlen, _("1/%i"), (int) (0.5 + 1. / d));
01090 else
01091 snprintf (val, maxlen, "%i", (int) d);
01092 if (maxlen > strlen (val) + strlen (_(" sec.")))
01093 strncat (val, _(" sec."), maxlen - strlen (val));
01094 break;
01095 case EXIF_TAG_SHUTTER_SPEED_VALUE:
01096 CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen);
01097 CC (e, 1, val, maxlen);
01098 v_srat = exif_get_srational (e->data, o);
01099 if (!v_srat.denominator) {
01100 exif_entry_format_value(e, val, maxlen);
01101 break;
01102 }
01103 d = (double) v_srat.numerator / (double) v_srat.denominator;
01104 snprintf (val, maxlen, _("%.02f EV"), d);
01105 d = 1. / pow (2, d);
01106 if (d < 1)
01107 snprintf (b, sizeof (b), _(" (1/%d sec.)"), (int) (1. / d));
01108 else
01109 snprintf (b, sizeof (b), _(" (%d sec.)"), (int) d);
01110 strncat (val, b, maxlen - strlen (val));
01111 break;
01112 case EXIF_TAG_BRIGHTNESS_VALUE:
01113 CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen);
01114 CC (e, 1, val, maxlen);
01115 v_srat = exif_get_srational (e->data, o);
01116 if (!v_srat.denominator) {
01117 exif_entry_format_value(e, val, maxlen);
01118 break;
01119 }
01120 d = (double) v_srat.numerator / (double) v_srat.denominator;
01121 snprintf (val, maxlen, _("%.02f EV"), d);
01122 snprintf (b, sizeof (b), _(" (%.02f cd/m^2)"),
01123 1. / (M_PI * 0.3048 * 0.3048) * pow (2, d));
01124 if (maxlen > strlen (val) + strlen (b))
01125 strncat (val, b, maxlen - strlen (val));
01126 break;
01127 case EXIF_TAG_FILE_SOURCE:
01128 CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen);
01129 CC (e, 1, val, maxlen);
01130 v_byte = e->data[0];
01131 if (v_byte == 3)
01132 strncpy (val, _("DSC"), maxlen);
01133 else
01134 snprintf (val, maxlen, _("Internal error (unknown "
01135 "value %i)"), v_byte);
01136 break;
01137 case EXIF_TAG_COMPONENTS_CONFIGURATION:
01138 CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen);
01139 CC (e, 4, val, maxlen);
01140 for (i = 0; i < 4; i++) {
01141 switch (e->data[i]) {
01142 case 0: c = _("-"); break;
01143 case 1: c = _("Y"); break;
01144 case 2: c = _("Cb"); break;
01145 case 3: c = _("Cr"); break;
01146 case 4: c = _("R"); break;
01147 case 5: c = _("G"); break;
01148 case 6: c = _("B"); break;
01149 default: c = _("Reserved"); break;
01150 }
01151 strncat (val, c, maxlen - strlen (val));
01152 if (i < 3)
01153 strncat (val, " ", maxlen - strlen (val));
01154 }
01155 break;
01156 case EXIF_TAG_EXPOSURE_BIAS_VALUE:
01157 CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen);
01158 CC (e, 1, val, maxlen);
01159 v_srat = exif_get_srational (e->data, o);
01160 if (!v_srat.denominator) {
01161 exif_entry_format_value(e, val, maxlen);
01162 break;
01163 }
01164 d = (double) v_srat.numerator / (double) v_srat.denominator;
01165 snprintf (val, maxlen, _("%.02f EV"), d);
01166 break;
01167 case EXIF_TAG_SCENE_TYPE:
01168 CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen);
01169 CC (e, 1, val, maxlen);
01170 v_byte = e->data[0];
01171 if (v_byte == 1)
01172 strncpy (val, _("Directly photographed"), maxlen);
01173 else
01174 snprintf (val, maxlen, _("Internal error (unknown "
01175 "value %i)"), v_byte);
01176 break;
01177 case EXIF_TAG_YCBCR_SUB_SAMPLING:
01178 CF (e, EXIF_FORMAT_SHORT, val, maxlen);
01179 CC (e, 2, val, maxlen);
01180 v_short = exif_get_short (e->data, o);
01181 v_short2 = exif_get_short (
01182 e->data + exif_format_get_size (e->format),
01183 o);
01184 if ((v_short == 2) && (v_short2 == 1))
01185 strncpy (val, _("YCbCr4:2:2"), maxlen);
01186 else if ((v_short == 2) && (v_short2 == 2))
01187 strncpy (val, _("YCbCr4:2:0"), maxlen);
01188 else
01189 snprintf (val, maxlen, "%u, %u", v_short, v_short2);
01190 break;
01191 case EXIF_TAG_SUBJECT_AREA:
01192 CF (e, EXIF_FORMAT_SHORT, val, maxlen);
01193 switch (e->components) {
01194 case 2:
01195 v_short = exif_get_short (e->data, o);
01196 v_short2 = exif_get_short (e->data + 2, o);
01197 snprintf (val, maxlen, "(x,y) = (%i,%i)",
01198 v_short, v_short2);
01199 break;
01200 case 3:
01201 v_short = exif_get_short (e->data, o);
01202 v_short2 = exif_get_short (e->data + 2, o);
01203 v_short3 = exif_get_short (e->data + 4, o);
01204 snprintf (val, maxlen, _("Within distance %i of "
01205 "(x,y) = (%i,%i)"), v_short3, v_short,
01206 v_short2);
01207 break;
01208 case 4:
01209 v_short = exif_get_short (e->data, o);
01210 v_short2 = exif_get_short (e->data + 2, o);
01211 v_short3 = exif_get_short (e->data + 4, o);
01212 v_short4 = exif_get_short (e->data + 6, o);
01213 snprintf (val, maxlen, _("Within rectangle "
01214 "(width %i, height %i) around "
01215 "(x,y) = (%i,%i)"), v_short3, v_short4,
01216 v_short, v_short2);
01217 break;
01218 default:
01219 snprintf (val, maxlen, _("Unexpected number "
01220 "of components (%li, expected 2, 3, or 4)."),
01221 e->components);
01222 }
01223 break;
01224 case EXIF_TAG_GPS_VERSION_ID:
01225
01226 CF (e, EXIF_FORMAT_BYTE, val, maxlen);
01227 CC (e, 4, val, maxlen);
01228 v_byte = e->data[0];
01229 snprintf (val, maxlen, "%u", v_byte);
01230 maxlen -= strlen (val);
01231 for (i = 1; i < e->components; i++) {
01232 v_byte = e->data[i];
01233 snprintf (b, sizeof (b), ".%u", v_byte);
01234 strncat (val, b, maxlen);
01235 maxlen -= strlen (b);
01236 if ((signed)maxlen <= 0) break;
01237 }
01238 break;
01239 case EXIF_TAG_INTEROPERABILITY_VERSION:
01240
01241
01242 if (e->format == EXIF_FORMAT_UNDEFINED) {
01243 strncpy (val, (char *) e->data, MIN (maxlen, e->size));
01244 break;
01245 }
01246
01247
01248
01249 exif_entry_format_value(e, val, maxlen);
01250 break;
01251 case EXIF_TAG_GPS_ALTITUDE_REF:
01252
01253 CF (e, EXIF_FORMAT_BYTE, val, maxlen);
01254 CC (e, 1, val, maxlen);
01255 v_byte = e->data[0];
01256 if (v_byte == 0)
01257 strncpy (val, _("Sea level"), maxlen);
01258 else if (v_byte == 1)
01259 strncpy (val, _("Sea level reference"), maxlen);
01260 else
01261 snprintf (val, maxlen, _("Internal error (unknown "
01262 "value %i)"), v_byte);
01263 break;
01264 case EXIF_TAG_GPS_TIME_STAMP:
01265
01266 CF (e, EXIF_FORMAT_RATIONAL, val, maxlen);
01267 CC (e, 3, val, maxlen);
01268
01269 v_rat = exif_get_rational (e->data, o);
01270 if (!v_rat.denominator) {
01271 exif_entry_format_value(e, val, maxlen);
01272 break;
01273 }
01274 i = v_rat.numerator / v_rat.denominator;
01275
01276 v_rat = exif_get_rational (e->data +
01277 exif_format_get_size (e->format),
01278 o);
01279 if (!v_rat.denominator) {
01280 exif_entry_format_value(e, val, maxlen);
01281 break;
01282 }
01283 j = v_rat.numerator / v_rat.denominator;
01284
01285 v_rat = exif_get_rational (e->data +
01286 2*exif_format_get_size (e->format),
01287 o);
01288 if (!v_rat.denominator) {
01289 exif_entry_format_value(e, val, maxlen);
01290 break;
01291 }
01292 d = (double) v_rat.numerator / (double) v_rat.denominator;
01293 snprintf (val, maxlen, "%02u:%02u:%05.2f", i, j, d);
01294 break;
01295
01296 case EXIF_TAG_METERING_MODE:
01297 case EXIF_TAG_COMPRESSION:
01298 case EXIF_TAG_LIGHT_SOURCE:
01299 case EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT:
01300 case EXIF_TAG_RESOLUTION_UNIT:
01301 case EXIF_TAG_EXPOSURE_PROGRAM:
01302 case EXIF_TAG_FLASH:
01303 case EXIF_TAG_SUBJECT_DISTANCE_RANGE:
01304 case EXIF_TAG_COLOR_SPACE:
01305 CF (e,EXIF_FORMAT_SHORT, val, maxlen);
01306 CC (e, 1, val, maxlen);
01307 v_short = exif_get_short (e->data, o);
01308
01309
01310 for (i = 0; list2[i].tag && (list2[i].tag != e->tag); i++);
01311 if (!list2[i].tag) {
01312 snprintf (val, maxlen, _("Internal error (unknown "
01313 "value %i)"), v_short);
01314 break;
01315 }
01316
01317
01318 for (j = 0; list2[i].elem[j].values[0] &&
01319 (list2[i].elem[j].index < v_short); j++);
01320 if (list2[i].elem[j].index != v_short) {
01321 snprintf (val, maxlen, _("Internal error (unknown "
01322 "value %i)"), v_short);
01323 break;
01324 }
01325
01326
01327 memset (val, 0, maxlen);
01328 for (k = 0; list2[i].elem[j].values[k]; k++) {
01329 size_t l = strlen (_(list2[i].elem[j].values[k]));
01330 if ((maxlen > l) && (strlen (val) < l))
01331 strncpy (val, _(list2[i].elem[j].values[k]), maxlen);
01332 }
01333 if (!val[0]) snprintf (val, maxlen, "%i", v_short);
01334
01335 break;
01336
01337 case EXIF_TAG_PLANAR_CONFIGURATION:
01338 case EXIF_TAG_SENSING_METHOD:
01339 case EXIF_TAG_ORIENTATION:
01340 case EXIF_TAG_YCBCR_POSITIONING:
01341 case EXIF_TAG_PHOTOMETRIC_INTERPRETATION:
01342 case EXIF_TAG_CUSTOM_RENDERED:
01343 case EXIF_TAG_EXPOSURE_MODE:
01344 case EXIF_TAG_WHITE_BALANCE:
01345 case EXIF_TAG_SCENE_CAPTURE_TYPE:
01346 case EXIF_TAG_GAIN_CONTROL:
01347 case EXIF_TAG_SATURATION:
01348 case EXIF_TAG_CONTRAST:
01349 case EXIF_TAG_SHARPNESS:
01350 CF (e, EXIF_FORMAT_SHORT, val, maxlen);
01351 CC (e, 1, val, maxlen);
01352 v_short = exif_get_short (e->data, o);
01353
01354
01355 for (i = 0; list[i].tag && (list[i].tag != e->tag); i++);
01356 if (!list[i].tag) {
01357 snprintf (val, maxlen, _("Internal error (unknown "
01358 "value %i)"), v_short);
01359 break;
01360 }
01361
01362
01363 for (j = 0; list[i].strings[j] && (j < v_short); j++);
01364 if (!list[i].strings[j])
01365 snprintf (val, maxlen, "%i", v_short);
01366 else if (!*list[i].strings[j])
01367 snprintf (val, maxlen, _("Unknown value %i"), v_short);
01368 else
01369 strncpy (val, _(list[i].strings[j]), maxlen);
01370 break;
01371
01372 case EXIF_TAG_XP_TITLE:
01373 case EXIF_TAG_XP_COMMENT:
01374 case EXIF_TAG_XP_AUTHOR:
01375 case EXIF_TAG_XP_KEYWORDS:
01376 case EXIF_TAG_XP_SUBJECT:
01377 {
01378
01379 if (e->size+sizeof(unsigned short) < e->size) break;
01380
01381
01382
01383 unsigned short *utf16 = exif_mem_alloc (e->priv->mem, e->size+sizeof(unsigned short));
01384 if (!utf16) break;
01385 memcpy(utf16, e->data, e->size);
01386 utf16[e->size/sizeof(unsigned short)] = 0;
01387
01388
01389
01390 exif_convert_utf16_to_utf8(val, utf16, maxlen);
01391 exif_mem_free(e->priv->mem, utf16);
01392 break;
01393 }
01394
01395 default:
01396
01397 exif_entry_format_value(e, val, maxlen);
01398 }
01399
01400 return val;
01401 }
01402
01403
01407 void
01408 exif_entry_initialize (ExifEntry *e, ExifTag tag)
01409 {
01410 ExifRational r;
01411 ExifByteOrder o;
01412
01413
01414 if (!e || !e->parent || e->data || !e->parent->parent)
01415 return;
01416 o = exif_data_get_byte_order (e->parent->parent);
01417
01418 e->tag = tag;
01419 switch (tag) {
01420
01421
01422 case EXIF_TAG_PIXEL_X_DIMENSION:
01423 case EXIF_TAG_PIXEL_Y_DIMENSION:
01424 case EXIF_TAG_EXIF_IFD_POINTER:
01425 case EXIF_TAG_GPS_INFO_IFD_POINTER:
01426 case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
01427 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
01428 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT:
01429 e->components = 1;
01430 e->format = EXIF_FORMAT_LONG;
01431 e->size = exif_format_get_size (e->format) * e->components;
01432 e->data = exif_entry_alloc (e, e->size);
01433 if (!e->data) break;
01434 break;
01435
01436
01437 case EXIF_TAG_SUBJECT_LOCATION:
01438 case EXIF_TAG_SENSING_METHOD:
01439 case EXIF_TAG_PHOTOMETRIC_INTERPRETATION:
01440 case EXIF_TAG_COMPRESSION:
01441 case EXIF_TAG_EXPOSURE_MODE:
01442 case EXIF_TAG_WHITE_BALANCE:
01443 case EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM:
01444 case EXIF_TAG_GAIN_CONTROL:
01445 case EXIF_TAG_SUBJECT_DISTANCE_RANGE:
01446 case EXIF_TAG_FLASH:
01447 case EXIF_TAG_ISO_SPEED_RATINGS:
01448
01449
01450 case EXIF_TAG_IMAGE_WIDTH:
01451 case EXIF_TAG_IMAGE_LENGTH:
01452 case EXIF_TAG_EXPOSURE_PROGRAM:
01453 case EXIF_TAG_LIGHT_SOURCE:
01454 case EXIF_TAG_METERING_MODE:
01455 case EXIF_TAG_CUSTOM_RENDERED:
01456 case EXIF_TAG_SCENE_CAPTURE_TYPE:
01457 case EXIF_TAG_CONTRAST:
01458 case EXIF_TAG_SATURATION:
01459 case EXIF_TAG_SHARPNESS:
01460 e->components = 1;
01461 e->format = EXIF_FORMAT_SHORT;
01462 e->size = exif_format_get_size (e->format) * e->components;
01463 e->data = exif_entry_alloc (e, e->size);
01464 if (!e->data) break;
01465 exif_set_short (e->data, o, 0);
01466 break;
01467
01468
01469 case EXIF_TAG_ORIENTATION:
01470 case EXIF_TAG_PLANAR_CONFIGURATION:
01471 case EXIF_TAG_YCBCR_POSITIONING:
01472 e->components = 1;
01473 e->format = EXIF_FORMAT_SHORT;
01474 e->size = exif_format_get_size (e->format) * e->components;
01475 e->data = exif_entry_alloc (e, e->size);
01476 if (!e->data) break;
01477 exif_set_short (e->data, o, 1);
01478 break;
01479
01480
01481 case EXIF_TAG_RESOLUTION_UNIT:
01482 case EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT:
01483 e->components = 1;
01484 e->format = EXIF_FORMAT_SHORT;
01485 e->size = exif_format_get_size (e->format) * e->components;
01486 e->data = exif_entry_alloc (e, e->size);
01487 if (!e->data) break;
01488 exif_set_short (e->data, o, 2);
01489 break;
01490
01491
01492 case EXIF_TAG_SAMPLES_PER_PIXEL:
01493 e->components = 1;
01494 e->format = EXIF_FORMAT_SHORT;
01495 e->size = exif_format_get_size (e->format) * e->components;
01496 e->data = exif_entry_alloc (e, e->size);
01497 if (!e->data) break;
01498 exif_set_short (e->data, o, 3);
01499 break;
01500
01501
01502 case EXIF_TAG_COLOR_SPACE:
01503 e->components = 1;
01504 e->format = EXIF_FORMAT_SHORT;
01505 e->size = exif_format_get_size (e->format) * e->components;
01506 e->data = exif_entry_alloc (e, e->size);
01507 if (!e->data) break;
01508 exif_set_short (e->data, o, 0xffff);
01509 break;
01510
01511
01512 case EXIF_TAG_BITS_PER_SAMPLE:
01513 e->components = 3;
01514 e->format = EXIF_FORMAT_SHORT;
01515 e->size = exif_format_get_size (e->format) * e->components;
01516 e->data = exif_entry_alloc (e, e->size);
01517 if (!e->data) break;
01518 exif_set_short (e->data, o, 8);
01519 exif_set_short (
01520 e->data + exif_format_get_size (e->format),
01521 o, 8);
01522 exif_set_short (
01523 e->data + 2 * exif_format_get_size (e->format),
01524 o, 8);
01525 break;
01526
01527
01528 case EXIF_TAG_YCBCR_SUB_SAMPLING:
01529 e->components = 2;
01530 e->format = EXIF_FORMAT_SHORT;
01531 e->size = exif_format_get_size (e->format) * e->components;
01532 e->data = exif_entry_alloc (e, e->size);
01533 if (!e->data) break;
01534 exif_set_short (e->data, o, 2);
01535 exif_set_short (
01536 e->data + exif_format_get_size (e->format),
01537 o, 1);
01538 break;
01539
01540
01541 case EXIF_TAG_EXPOSURE_BIAS_VALUE:
01542 case EXIF_TAG_BRIGHTNESS_VALUE:
01543 case EXIF_TAG_SHUTTER_SPEED_VALUE:
01544 e->components = 1;
01545 e->format = EXIF_FORMAT_SRATIONAL;
01546 e->size = exif_format_get_size (e->format) * e->components;
01547 e->data = exif_entry_alloc (e, e->size);
01548 if (!e->data) break;
01549 break;
01550
01551
01552 case EXIF_TAG_EXPOSURE_TIME:
01553 case EXIF_TAG_FOCAL_PLANE_X_RESOLUTION:
01554 case EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION:
01555 case EXIF_TAG_EXPOSURE_INDEX:
01556 case EXIF_TAG_FLASH_ENERGY:
01557 case EXIF_TAG_FNUMBER:
01558 case EXIF_TAG_FOCAL_LENGTH:
01559 case EXIF_TAG_SUBJECT_DISTANCE:
01560 case EXIF_TAG_MAX_APERTURE_VALUE:
01561 case EXIF_TAG_APERTURE_VALUE:
01562 case EXIF_TAG_COMPRESSED_BITS_PER_PIXEL:
01563 case EXIF_TAG_PRIMARY_CHROMATICITIES:
01564 case EXIF_TAG_DIGITAL_ZOOM_RATIO:
01565 e->components = 1;
01566 e->format = EXIF_FORMAT_RATIONAL;
01567 e->size = exif_format_get_size (e->format) * e->components;
01568 e->data = exif_entry_alloc (e, e->size);
01569 if (!e->data) break;
01570 break;
01571
01572
01573 case EXIF_TAG_X_RESOLUTION:
01574 case EXIF_TAG_Y_RESOLUTION:
01575 e->components = 1;
01576 e->format = EXIF_FORMAT_RATIONAL;
01577 e->size = exif_format_get_size (e->format) * e->components;
01578 e->data = exif_entry_alloc (e, e->size);
01579 if (!e->data) break;
01580 r.numerator = 72;
01581 r.denominator = 1;
01582 exif_set_rational (e->data, o, r);
01583 break;
01584
01585
01586 case EXIF_TAG_WHITE_POINT:
01587 e->components = 2;
01588 e->format = EXIF_FORMAT_RATIONAL;
01589 e->size = exif_format_get_size (e->format) * e->components;
01590 e->data = exif_entry_alloc (e, e->size);
01591 if (!e->data) break;
01592 break;
01593
01594
01595 case EXIF_TAG_REFERENCE_BLACK_WHITE:
01596 e->components = 6;
01597 e->format = EXIF_FORMAT_RATIONAL;
01598 e->size = exif_format_get_size (e->format) * e->components;
01599 e->data = exif_entry_alloc (e, e->size);
01600 if (!e->data) break;
01601 r.denominator = 1;
01602 r.numerator = 0;
01603 exif_set_rational (e->data, o, r);
01604 r.numerator = 255;
01605 exif_set_rational (
01606 e->data + exif_format_get_size (e->format), o, r);
01607 r.numerator = 0;
01608 exif_set_rational (
01609 e->data + 2 * exif_format_get_size (e->format), o, r);
01610 r.numerator = 255;
01611 exif_set_rational (
01612 e->data + 3 * exif_format_get_size (e->format), o, r);
01613 r.numerator = 0;
01614 exif_set_rational (
01615 e->data + 4 * exif_format_get_size (e->format), o, r);
01616 r.numerator = 255;
01617 exif_set_rational (
01618 e->data + 5 * exif_format_get_size (e->format), o, r);
01619 break;
01620
01621
01622 case EXIF_TAG_DATE_TIME:
01623 case EXIF_TAG_DATE_TIME_ORIGINAL:
01624 case EXIF_TAG_DATE_TIME_DIGITIZED:
01625 {
01626 time_t t;
01627 #ifdef HAVE_LOCALTIME_R
01628 struct tm tms;
01629 #endif
01630 struct tm *tm;
01631
01632 t = time (NULL);
01633 #ifdef HAVE_LOCALTIME_R
01634 tm = localtime_r (&t, &tms);
01635 #else
01636 tm = localtime (&t);
01637 #endif
01638 e->components = 20;
01639 e->format = EXIF_FORMAT_ASCII;
01640 e->size = exif_format_get_size (e->format) * e->components;
01641 e->data = exif_entry_alloc (e, e->size);
01642 if (!e->data) break;
01643 snprintf ((char *) e->data, e->size,
01644 "%04i:%02i:%02i %02i:%02i:%02i",
01645 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
01646 tm->tm_hour, tm->tm_min, tm->tm_sec);
01647 break;
01648 }
01649
01650
01651 case EXIF_TAG_SUB_SEC_TIME:
01652 case EXIF_TAG_SUB_SEC_TIME_ORIGINAL:
01653 case EXIF_TAG_SUB_SEC_TIME_DIGITIZED:
01654 e->components = 0;
01655 e->format = EXIF_FORMAT_ASCII;
01656 e->size = 0;
01657 e->data = NULL;
01658 break;
01659
01660
01661 case EXIF_TAG_IMAGE_DESCRIPTION:
01662 case EXIF_TAG_MAKE:
01663 case EXIF_TAG_MODEL:
01664 case EXIF_TAG_SOFTWARE:
01665 case EXIF_TAG_ARTIST:
01666 e->components = strlen (_("[None]")) + 1;
01667 e->format = EXIF_FORMAT_ASCII;
01668 e->size = exif_format_get_size (e->format) * e->components;
01669 e->data = exif_entry_alloc (e, e->size);
01670 if (!e->data) break;
01671 strncpy ((char *)e->data, _("[None]"), e->size);
01672 break;
01673
01674 case EXIF_TAG_COPYRIGHT:
01675 e->components = (strlen (_("[None]")) + 1) * 2;
01676 e->format = EXIF_FORMAT_ASCII;
01677 e->size = exif_format_get_size (e->format) * e->components;
01678 e->data = exif_entry_alloc (e, e->size);
01679 if (!e->data) break;
01680 strcpy (((char *)e->data) + 0, _("[None]"));
01681 strcpy (((char *)e->data) + strlen (_("[None]")) + 1, _("[None]"));
01682 break;
01683
01684
01685 case EXIF_TAG_SCENE_TYPE:
01686 e->components = 1;
01687 e->format = EXIF_FORMAT_UNDEFINED;
01688 e->size = exif_format_get_size (e->format) * e->components;
01689 e->data = exif_entry_alloc (e, e->size);
01690 if (!e->data) break;
01691 e->data[0] = 0x01;
01692 break;
01693
01694
01695 case EXIF_TAG_FILE_SOURCE:
01696 e->components = 1;
01697 e->format = EXIF_FORMAT_UNDEFINED;
01698 e->size = exif_format_get_size (e->format) * e->components;
01699 e->data = exif_entry_alloc (e, e->size);
01700 if (!e->data) break;
01701 e->data[0] = 0x03;
01702 break;
01703
01704
01705 case EXIF_TAG_FLASH_PIX_VERSION:
01706 e->components = 4;
01707 e->format = EXIF_FORMAT_UNDEFINED;
01708 e->size = exif_format_get_size (e->format) * e->components;
01709 e->data = exif_entry_alloc (e, e->size);
01710 if (!e->data) break;
01711 memcpy (e->data, "0100", 4);
01712 break;
01713
01714
01715 case EXIF_TAG_EXIF_VERSION:
01716 e->components = 4;
01717 e->format = EXIF_FORMAT_UNDEFINED;
01718 e->size = exif_format_get_size (e->format) * e->components;
01719 e->data = exif_entry_alloc (e, e->size);
01720 if (!e->data) break;
01721 memcpy (e->data, "0210", 4);
01722 break;
01723
01724
01725 case EXIF_TAG_COMPONENTS_CONFIGURATION:
01726 e->components = 4;
01727 e->format = EXIF_FORMAT_UNDEFINED;
01728 e->size = exif_format_get_size (e->format) * e->components;
01729 e->data = exif_entry_alloc (e, e->size);
01730 if (!e->data) break;
01731 e->data[0] = 1;
01732 e->data[1] = 2;
01733 e->data[2] = 3;
01734 e->data[3] = 0;
01735 break;
01736
01737
01738
01739 case EXIF_TAG_MAKER_NOTE:
01740 case EXIF_TAG_USER_COMMENT:
01741 default:
01742 e->components = 0;
01743 e->format = EXIF_FORMAT_UNDEFINED;
01744 e->size = 0;
01745 e->data = NULL;
01746 break;
01747 }
01748 }