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-mnote-data.h>
00024 #include <libexif/exif-data.h>
00025 #include <libexif/exif-ifd.h>
00026 #include <libexif/exif-mnote-data-priv.h>
00027 #include <libexif/exif-utils.h>
00028 #include <libexif/exif-loader.h>
00029 #include <libexif/exif-log.h>
00030 #include <libexif/i18n.h>
00031
00032 #include <libexif/olympus/exif-mnote-data-olympus.h>
00033 #include <libexif/canon/exif-mnote-data-canon.h>
00034 #include <libexif/pentax/exif-mnote-data-pentax.h>
00035
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 #include <string.h>
00039
00040 #undef MAX
00041 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
00042
00043 #if defined(__WATCOMC__) || defined(_MSC_VER)
00044 # define strncasecmp strnicmp
00045 #endif
00046
00047 #undef JPEG_MARKER_SOI
00048 #define JPEG_MARKER_SOI 0xd8
00049 #undef JPEG_MARKER_APP0
00050 #define JPEG_MARKER_APP0 0xe0
00051 #undef JPEG_MARKER_APP1
00052 #define JPEG_MARKER_APP1 0xe1
00053
00054 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
00055
00056 struct _ExifDataPrivate
00057 {
00058 ExifByteOrder order;
00059
00060 ExifMnoteData *md;
00061
00062 ExifLog *log;
00063 ExifMem *mem;
00064
00065 unsigned int ref_count;
00066
00067
00068 unsigned int offset_mnote;
00069
00070 ExifDataOption options;
00071 ExifDataType data_type;
00072 };
00073
00074 static void *
00075 exif_data_alloc (ExifData *data, unsigned int i)
00076 {
00077 void *d;
00078
00079 if (!data || !i)
00080 return NULL;
00081
00082 d = exif_mem_alloc (data->priv->mem, i);
00083 if (d)
00084 return d;
00085
00086 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", i);
00087 return NULL;
00088 }
00089
00090 ExifMnoteData *
00091 exif_data_get_mnote_data (ExifData *d)
00092 {
00093 return (d && d->priv) ? d->priv->md : NULL;
00094 }
00095
00096 ExifData *
00097 exif_data_new (void)
00098 {
00099 ExifMem *mem = exif_mem_new_default ();
00100 ExifData *d = exif_data_new_mem (mem);
00101
00102 exif_mem_unref (mem);
00103
00104 return d;
00105 }
00106
00107 ExifData *
00108 exif_data_new_mem (ExifMem *mem)
00109 {
00110 ExifData *data;
00111 unsigned int i;
00112
00113 if (!mem)
00114 return NULL;
00115
00116 data = exif_mem_alloc (mem, sizeof (ExifData));
00117 if (!data)
00118 return (NULL);
00119 data->priv = exif_mem_alloc (mem, sizeof (ExifDataPrivate));
00120 if (!data->priv) {
00121 exif_mem_free (mem, data);
00122 return (NULL);
00123 }
00124 data->priv->ref_count = 1;
00125
00126 data->priv->mem = mem;
00127 exif_mem_ref (mem);
00128
00129 for (i = 0; i < EXIF_IFD_COUNT; i++) {
00130 data->ifd[i] = exif_content_new_mem (data->priv->mem);
00131 if (!data->ifd[i]) {
00132 exif_data_free (data);
00133 return (NULL);
00134 }
00135 data->ifd[i]->parent = data;
00136 }
00137
00138
00139 exif_data_set_option (data, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
00140 exif_data_set_option (data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
00141
00142
00143 exif_data_set_data_type (data, EXIF_DATA_TYPE_COUNT);
00144
00145 return (data);
00146 }
00147
00148 ExifData *
00149 exif_data_new_from_data (const unsigned char *data, unsigned int size)
00150 {
00151 ExifData *edata;
00152
00153 edata = exif_data_new ();
00154 exif_data_load_data (edata, data, size);
00155 return (edata);
00156 }
00157
00158 static void
00159 exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
00160 const unsigned char *d,
00161 unsigned int size, unsigned int offset)
00162 {
00163 unsigned int s, doff;
00164
00165 entry->tag = exif_get_short (d + offset + 0, data->priv->order);
00166 entry->format = exif_get_short (d + offset + 2, data->priv->order);
00167 entry->components = exif_get_long (d + offset + 4, data->priv->order);
00168
00169 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00170 "Loading entry 0x%x ('%s')...", entry->tag,
00171 exif_tag_get_name (entry->tag));
00172
00173
00174
00175 s = exif_format_get_size(entry->format) * entry->components;
00176 if (s < entry->components) {
00177 return 0;
00178 }
00179 if (0 == s)
00180 return 0;
00181
00182
00183
00184
00185
00186 if (s > 4)
00187 doff = exif_get_long (d + offset + 8, data->priv->order);
00188 else
00189 doff = offset + 8;
00190
00191
00192 if ((doff + s < doff) || (doff + s < s))
00193 return;
00194 if (size < doff + s)
00195 return;
00196
00197 entry->data = exif_data_alloc (data, s);
00198 if (entry->data) {
00199 entry->size = s;
00200 memcpy (entry->data, d + doff, s);
00201 }
00202
00203
00204 if (entry->tag == EXIF_TAG_MAKER_NOTE) {
00205 if (entry->size > 6) exif_log (data->priv->log,
00206 EXIF_LOG_CODE_DEBUG, "ExifData",
00207 "MakerNote found (%02x %02x %02x %02x "
00208 "%02x %02x %02x...).",
00209 entry->data[0], entry->data[1], entry->data[2],
00210 entry->data[3], entry->data[4], entry->data[5],
00211 entry->data[6]);
00212 data->priv->offset_mnote = doff;
00213 }
00214 }
00215
00216 static void
00217 exif_data_save_data_entry (ExifData *data, ExifEntry *e,
00218 unsigned char **d, unsigned int *ds,
00219 unsigned int offset)
00220 {
00221 unsigned int doff, s;
00222
00223 if (!data || !data->priv)
00224 return;
00225
00226
00227
00228
00229
00230 exif_set_short (*d + 6 + offset + 0,
00231 data->priv->order, (ExifShort) e->tag);
00232 exif_set_short (*d + 6 + offset + 2,
00233 data->priv->order, (ExifShort) e->format);
00234
00235 #ifndef EXIF_DONT_CHANGE_MAKER_NOTE
00236
00237 if ((e->tag == EXIF_TAG_MAKER_NOTE) && data->priv->md) {
00238 exif_mem_free (data->priv->mem, e->data);
00239 e->data = NULL;
00240 e->size = 0;
00241 exif_mnote_data_set_offset (data->priv->md, *ds - 6);
00242 exif_mnote_data_save (data->priv->md, &e->data, &e->size);
00243 e->components = e->size;
00244 }
00245 #endif
00246
00247 exif_set_long (*d + 6 + offset + 4,
00248 data->priv->order, e->components);
00249
00250
00251
00252
00253
00254 s = exif_format_get_size (e->format) * e->components;
00255 if (s > 4) {
00256 doff = *ds - 6;
00257 *ds += s;
00258
00259
00260
00261
00262
00263
00264 if (s & 1)
00265 (*ds)++;
00266 *d = exif_mem_realloc (data->priv->mem, *d, *ds);
00267 if (!*d) {
00268 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", *ds);
00269 return;
00270 }
00271 exif_set_long (*d + 6 + offset + 8, data->priv->order, doff);
00272 if (s & 1)
00273 *(*d + *ds - 1) = '\0';
00274
00275 } else
00276 doff = offset + 8;
00277
00278
00279 memcpy (*d + 6 + doff, e->data, s);
00280 if (s < 4)
00281 memset (*d + 6 + doff + s, 0, (4 - s));
00282 }
00283
00284 static void
00285 exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d,
00286 unsigned int ds, ExifLong offset, ExifLong size)
00287 {
00288 if ((ds < offset + size) || (offset < 0) || (size < 0) || (offset + size < offset)) {
00289 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00290 "Bogus thumbnail offset and size");
00291 return;
00292 }
00293 if (data->data)
00294 exif_mem_free (data->priv->mem, data->data);
00295 data->size = size;
00296 data->data = exif_data_alloc (data, data->size);
00297 if (!data->data)
00298 return;
00299 memcpy (data->data, d + offset, data->size);
00300 }
00301
00302 #undef CHECK_REC
00303 #define CHECK_REC(i) \
00304 if ((i) == ifd) { \
00305 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \
00306 "ExifData", "Recursive entry in IFD " \
00307 "'%s' detected. Skipping...", \
00308 exif_ifd_get_name (i)); \
00309 break; \
00310 } \
00311 if (data->ifd[(i)]->count) { \
00312 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \
00313 "ExifData", "Attemt to load IFD " \
00314 "'%s' multiple times detected. " \
00315 "Skipping...", \
00316 exif_ifd_get_name (i)); \
00317 break; \
00318 }
00319
00320 static void
00321 exif_data_load_data_content (ExifData *data, ExifIfd ifd,
00322 const unsigned char *d,
00323 unsigned int ds, unsigned int offset, unsigned int recursion_depth)
00324 {
00325 ExifLong o, thumbnail_offset = 0, thumbnail_length = 0;
00326 ExifShort n;
00327 ExifEntry *entry;
00328 unsigned int i;
00329 ExifTag tag;
00330
00331 if (!data || !data->priv)
00332 return;
00333 if ((ifd < 0) || (ifd >= EXIF_IFD_COUNT))
00334 return;
00335
00336 if (recursion_depth > 150) {
00337 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData",
00338 "Deep recursion detected!");
00339 return;
00340 }
00341
00342
00343 if (offset >= ds - 1)
00344 return;
00345 n = exif_get_short (d + offset, data->priv->order);
00346 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00347 "Loading %i entries...", n);
00348 offset += 2;
00349
00350
00351 if (offset + 12 * n > ds)
00352 n = (ds - offset) / 12;
00353
00354 for (i = 0; i < n; i++) {
00355
00356 tag = exif_get_short (d + offset + 12 * i, data->priv->order);
00357 switch (tag) {
00358 case EXIF_TAG_EXIF_IFD_POINTER:
00359 case EXIF_TAG_GPS_INFO_IFD_POINTER:
00360 case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
00361 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
00362 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT:
00363 o = exif_get_long (d + offset + 12 * i + 8,
00364 data->priv->order);
00365 switch (tag) {
00366 case EXIF_TAG_EXIF_IFD_POINTER:
00367 CHECK_REC (EXIF_IFD_EXIF);
00368 exif_data_load_data_content (data, EXIF_IFD_EXIF, d, ds, o, recursion_depth + 1);
00369 break;
00370 case EXIF_TAG_GPS_INFO_IFD_POINTER:
00371 CHECK_REC (EXIF_IFD_GPS);
00372 exif_data_load_data_content (data, EXIF_IFD_GPS, d, ds, o, recursion_depth + 1);
00373 break;
00374 case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
00375 CHECK_REC (EXIF_IFD_INTEROPERABILITY);
00376 exif_data_load_data_content (data, EXIF_IFD_INTEROPERABILITY, d, ds, o, recursion_depth + 1);
00377 break;
00378 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT:
00379 thumbnail_offset = o;
00380 if (thumbnail_offset && thumbnail_length)
00381 exif_data_load_data_thumbnail (data, d,
00382 ds, thumbnail_offset,
00383 thumbnail_length);
00384 break;
00385 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
00386 thumbnail_length = o;
00387 if (thumbnail_offset && thumbnail_length)
00388 exif_data_load_data_thumbnail (data, d,
00389 ds, thumbnail_offset,
00390 thumbnail_length);
00391 break;
00392 default:
00393 return;
00394 }
00395 break;
00396 default:
00397
00398
00399
00400
00401
00402
00403 if (!exif_tag_get_name_in_ifd (tag, ifd)) {
00404
00405
00406
00407
00408
00409 if (!memcmp (d + offset + 12 * i, "\0\0\0\0", 4)) {
00410 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00411 "Skipping empty entry at position %i in '%s'.", i,
00412 exif_ifd_get_name (ifd));
00413 break;
00414 }
00415 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00416 "Unknown tag 0x%04x (entry %i in '%s'). Please report this tag "
00417 "to <libexif-devel@lists.sourceforge.net>.", tag, i,
00418 exif_ifd_get_name (ifd));
00419 if (data->priv->options & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS)
00420 break;
00421 }
00422 entry = exif_entry_new_mem (data->priv->mem);
00423 exif_data_load_data_entry (data, entry, d, ds,
00424 offset + 12 * i);
00425 exif_content_add_entry (data->ifd[ifd], entry);
00426 exif_entry_unref (entry);
00427 break;
00428 }
00429 }
00430 }
00431
00432 static int
00433 cmp_func (const unsigned char *p1, const unsigned char *p2, ExifByteOrder o)
00434 {
00435 ExifShort tag1 = exif_get_short (p1, o);
00436 ExifShort tag2 = exif_get_short (p2, o);
00437
00438 return (tag1 < tag2) ? -1 : (tag1 > tag2) ? 1 : 0;
00439 }
00440
00441 static int
00442 cmp_func_intel (const void *elem1, const void *elem2)
00443 {
00444 return cmp_func ((const unsigned char *) elem1,
00445 (const unsigned char *) elem2, EXIF_BYTE_ORDER_INTEL);
00446 }
00447
00448 static int
00449 cmp_func_motorola (const void *elem1, const void *elem2)
00450 {
00451 return cmp_func ((const unsigned char *) elem1,
00452 (const unsigned char *) elem2, EXIF_BYTE_ORDER_MOTOROLA);
00453 }
00454
00455 static void
00456 exif_data_save_data_content (ExifData *data, ExifContent *ifd,
00457 unsigned char **d, unsigned int *ds,
00458 unsigned int offset)
00459 {
00460 unsigned int j, n_ptr = 0, n_thumb = 0;
00461 ExifIfd i;
00462
00463 if (!data || !data->priv || !ifd || !d || !ds)
00464 return;
00465
00466 for (i = 0; i < EXIF_IFD_COUNT; i++)
00467 if (ifd == data->ifd[i])
00468 break;
00469 if (i == EXIF_IFD_COUNT)
00470 return;
00471
00472
00473
00474
00475 switch (i) {
00476 case EXIF_IFD_0:
00477
00478
00479
00480
00481
00482 if (data->ifd[EXIF_IFD_EXIF]->count ||
00483 data->ifd[EXIF_IFD_INTEROPERABILITY]->count)
00484 n_ptr++;
00485
00486
00487 if (data->ifd[EXIF_IFD_GPS]->count)
00488 n_ptr++;
00489
00490 break;
00491 case EXIF_IFD_1:
00492 if (data->size)
00493 n_thumb = 2;
00494 break;
00495 case EXIF_IFD_EXIF:
00496 if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count)
00497 n_ptr++;
00498 default:
00499 break;
00500 }
00501
00502
00503
00504
00505
00506 *ds += (2 + (ifd->count + n_ptr + n_thumb) * 12 + 4);
00507 *d = exif_mem_realloc (data->priv->mem, *d, *ds);
00508 if (!*d) {
00509 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", *ds);
00510 return;
00511 }
00512
00513
00514 exif_set_short (*d + 6 + offset, data->priv->order,
00515 (ExifShort) (ifd->count + n_ptr + n_thumb));
00516 offset += 2;
00517
00518
00519 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00520 "Saving %i entries (IFD '%s', offset: %i)...",
00521 ifd->count, exif_ifd_get_name (i), offset);
00522 for (j = 0; j < ifd->count; j++)
00523 exif_data_save_data_entry (data, ifd->entries[j], d, ds, offset + 12 * j);
00524
00525 offset += 12 * ifd->count;
00526
00527
00528 switch (i) {
00529 case EXIF_IFD_0:
00530
00531
00532
00533
00534
00535
00536
00537 if (data->ifd[EXIF_IFD_EXIF]->count ||
00538 data->ifd[EXIF_IFD_INTEROPERABILITY]->count) {
00539 exif_set_short (*d + 6 + offset + 0, data->priv->order,
00540 EXIF_TAG_EXIF_IFD_POINTER);
00541 exif_set_short (*d + 6 + offset + 2, data->priv->order,
00542 EXIF_FORMAT_LONG);
00543 exif_set_long (*d + 6 + offset + 4, data->priv->order,
00544 1);
00545 exif_set_long (*d + 6 + offset + 8, data->priv->order,
00546 *ds - 6);
00547 exif_data_save_data_content (data,
00548 data->ifd[EXIF_IFD_EXIF], d, ds, *ds - 6);
00549 offset += 12;
00550 }
00551
00552
00553 if (data->ifd[EXIF_IFD_GPS]->count) {
00554 exif_set_short (*d + 6 + offset + 0, data->priv->order,
00555 EXIF_TAG_GPS_INFO_IFD_POINTER);
00556 exif_set_short (*d + 6 + offset + 2, data->priv->order,
00557 EXIF_FORMAT_LONG);
00558 exif_set_long (*d + 6 + offset + 4, data->priv->order,
00559 1);
00560 exif_set_long (*d + 6 + offset + 8, data->priv->order,
00561 *ds - 6);
00562 exif_data_save_data_content (data,
00563 data->ifd[EXIF_IFD_GPS], d, ds, *ds - 6);
00564 offset += 12;
00565 }
00566
00567 break;
00568 case EXIF_IFD_EXIF:
00569
00570
00571
00572
00573
00574 if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) {
00575 exif_set_short (*d + 6 + offset + 0, data->priv->order,
00576 EXIF_TAG_INTEROPERABILITY_IFD_POINTER);
00577 exif_set_short (*d + 6 + offset + 2, data->priv->order,
00578 EXIF_FORMAT_LONG);
00579 exif_set_long (*d + 6 + offset + 4, data->priv->order,
00580 1);
00581 exif_set_long (*d + 6 + offset + 8, data->priv->order,
00582 *ds - 6);
00583 exif_data_save_data_content (data,
00584 data->ifd[EXIF_IFD_INTEROPERABILITY], d, ds,
00585 *ds - 6);
00586 offset += 12;
00587 }
00588
00589 break;
00590 case EXIF_IFD_1:
00591
00592
00593
00594
00595
00596 if (data->size) {
00597
00598
00599 exif_set_short (*d + 6 + offset + 0, data->priv->order,
00600 EXIF_TAG_JPEG_INTERCHANGE_FORMAT);
00601 exif_set_short (*d + 6 + offset + 2, data->priv->order,
00602 EXIF_FORMAT_LONG);
00603 exif_set_long (*d + 6 + offset + 4, data->priv->order,
00604 1);
00605 exif_set_long (*d + 6 + offset + 8, data->priv->order,
00606 *ds - 6);
00607 *ds += data->size;
00608 *d = exif_mem_realloc (data->priv->mem, *d, *ds);
00609 if (!*d) {
00610 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData",
00611 *ds);
00612 return;
00613 }
00614 memcpy (*d + *ds - data->size, data->data, data->size);
00615 offset += 12;
00616
00617
00618 exif_set_short (*d + 6 + offset + 0, data->priv->order,
00619 EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
00620 exif_set_short (*d + 6 + offset + 2, data->priv->order,
00621 EXIF_FORMAT_LONG);
00622 exif_set_long (*d + 6 + offset + 4, data->priv->order,
00623 1);
00624 exif_set_long (*d + 6 + offset + 8, data->priv->order,
00625 data->size);
00626 offset += 12;
00627 }
00628
00629 break;
00630 default:
00631 break;
00632 }
00633
00634
00635 qsort (*d + 6 + offset - (ifd->count + n_ptr + n_thumb) * 12,
00636 (ifd->count + n_ptr + n_thumb), 12,
00637 (data->priv->order == EXIF_BYTE_ORDER_INTEL) ? cmp_func_intel : cmp_func_motorola);
00638
00639
00640 if (i == EXIF_IFD_0 && (data->ifd[EXIF_IFD_1]->count ||
00641 data->size)) {
00642
00643
00644
00645
00646
00647 exif_set_long (*d + 6 + offset, data->priv->order, *ds - 6);
00648 exif_data_save_data_content (data, data->ifd[EXIF_IFD_1], d, ds,
00649 *ds - 6);
00650 } else
00651 exif_set_long (*d + 6 + offset, data->priv->order, 0);
00652 }
00653
00654 typedef enum {
00655 EXIF_DATA_TYPE_MAKER_NOTE_NONE = 0,
00656 EXIF_DATA_TYPE_MAKER_NOTE_CANON = 1,
00657 EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS = 2,
00658 EXIF_DATA_TYPE_MAKER_NOTE_PENTAX = 3
00659 } ExifDataTypeMakerNote;
00660
00661 static ExifDataTypeMakerNote
00662 exif_data_get_type_maker_note (ExifData *d)
00663 {
00664 ExifEntry *e, *em;
00665 char value[1024];
00666
00667 if (!d)
00668 return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
00669
00670 e = exif_data_get_entry (d, EXIF_TAG_MAKER_NOTE);
00671 if (!e)
00672 return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
00673
00674
00675 if ((e->size >= 5) && (!memcmp (e->data, "OLYMP", 5) ||
00676 !memcmp (e->data, "Nikon", 5)))
00677 return EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS;
00678
00679 em = exif_data_get_entry (d, EXIF_TAG_MAKE);
00680 if (!em)
00681 return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
00682
00683
00684 if (!strcmp (exif_entry_get_value (em, value, sizeof (value)), "Canon"))
00685 return EXIF_DATA_TYPE_MAKER_NOTE_CANON;
00686
00687
00688 if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b)) {
00689 if (!strncasecmp (
00690 exif_entry_get_value (em, value, sizeof(value)),
00691 "Nikon", 5))
00692 return EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS;
00693 else
00694 return EXIF_DATA_TYPE_MAKER_NOTE_PENTAX;
00695 }
00696
00697 return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
00698 }
00699
00700 #define LOG_TOO_SMALL \
00701 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", \
00702 _("Size of data too small to allow for EXIF data."));
00703
00704 void
00705 exif_data_load_data (ExifData *data, const unsigned char *d_orig,
00706 unsigned int ds_orig)
00707 {
00708 unsigned int l;
00709 ExifLong offset;
00710 ExifShort n;
00711 const unsigned char *d = d_orig;
00712 unsigned int ds = ds_orig, len;
00713
00714 if (!data || !data->priv || !d || !ds)
00715 return;
00716
00717 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00718 "Parsing %i byte(s) EXIF data...\n", ds);
00719
00720
00721
00722
00723
00724 if (ds < 6) {
00725 LOG_TOO_SMALL;
00726 return;
00727 }
00728 if (!memcmp (d, ExifHeader, 6)) {
00729 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00730 "Found EXIF header.");
00731 } else {
00732 while (1) {
00733 while ((d[0] == 0xff) && ds) {
00734 d++;
00735 ds--;
00736 }
00737
00738
00739 if (d[0] == JPEG_MARKER_SOI) {
00740 d++;
00741 ds--;
00742 continue;
00743 }
00744
00745
00746 if (d[0] == JPEG_MARKER_APP0) {
00747 d++;
00748 ds--;
00749 l = (d[0] << 8) | d[1];
00750 if (l > ds)
00751 return;
00752 d += l;
00753 ds -= l;
00754 continue;
00755 }
00756
00757
00758 if (d[0] == JPEG_MARKER_APP1)
00759 break;
00760
00761
00762 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
00763 "ExifData", _("EXIF marker not found."));
00764 return;
00765 }
00766 d++;
00767 ds--;
00768 if (ds < 2) {
00769 LOG_TOO_SMALL;
00770 return;
00771 }
00772 len = (d[0] << 8) | d[1];
00773 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00774 "We have to deal with %i byte(s) of EXIF data.",
00775 len);
00776 d += 2;
00777 ds -= 2;
00778 }
00779
00780
00781
00782
00783
00784 if (ds < 6) {
00785 LOG_TOO_SMALL;
00786 return;
00787 }
00788 if (memcmp (d, ExifHeader, 6)) {
00789 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
00790 "ExifData", _("EXIF header not found."));
00791 return;
00792 }
00793
00794 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00795 "Found EXIF header.");
00796
00797
00798 if (ds < 14)
00799 return;
00800 if (!memcmp (d + 6, "II", 2))
00801 data->priv->order = EXIF_BYTE_ORDER_INTEL;
00802 else if (!memcmp (d + 6, "MM", 2))
00803 data->priv->order = EXIF_BYTE_ORDER_MOTOROLA;
00804 else {
00805 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
00806 "ExifData", _("Unknown encoding."));
00807 return;
00808 }
00809
00810
00811 if (exif_get_short (d + 8, data->priv->order) != 0x002a)
00812 return;
00813
00814
00815 offset = exif_get_long (d + 10, data->priv->order);
00816 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00817 "IFD 0 at %i.", (int) offset);
00818
00819
00820 exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0);
00821
00822
00823 if (offset + 6 + 2 > ds) {
00824 return;
00825 }
00826 n = exif_get_short (d + 6 + offset, data->priv->order);
00827 if (offset + 6 + 2 + 12 * n + 4 > ds) {
00828 return;
00829 }
00830 offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order);
00831 if (offset) {
00832 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00833 "IFD 1 at %i.", (int) offset);
00834
00835
00836 if (offset > ds - 6) {
00837 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
00838 "ExifData", "Bogus offset.");
00839 return;
00840 }
00841
00842 exif_data_load_data_content (data, EXIF_IFD_1, d + 6, ds - 6, offset, 0);
00843 }
00844
00845
00846
00847
00848
00849
00850
00851 switch (exif_data_get_type_maker_note (data)) {
00852 case EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS:
00853 data->priv->md = exif_mnote_data_olympus_new (data->priv->mem);
00854 break;
00855 case EXIF_DATA_TYPE_MAKER_NOTE_PENTAX:
00856 data->priv->md = exif_mnote_data_pentax_new (data->priv->mem);
00857 break;
00858 case EXIF_DATA_TYPE_MAKER_NOTE_CANON:
00859 data->priv->md = exif_mnote_data_canon_new (data->priv->mem);
00860 break;
00861 default:
00862 break;
00863 }
00864
00865
00866
00867
00868 if (data->priv->md) {
00869 exif_mnote_data_log (data->priv->md, data->priv->log);
00870 exif_mnote_data_set_byte_order (data->priv->md,
00871 data->priv->order);
00872 exif_mnote_data_set_offset (data->priv->md,
00873 data->priv->offset_mnote);
00874 exif_mnote_data_load (data->priv->md, d, ds);
00875 }
00876
00877 if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION)
00878 exif_data_fix (data);
00879 }
00880
00881 void
00882 exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds)
00883 {
00884 if (!data || !d || !ds)
00885 return;
00886
00887
00888 *ds = 14;
00889 *d = exif_data_alloc (data, *ds);
00890 if (!*d)
00891 return;
00892 memcpy (*d, ExifHeader, 6);
00893
00894
00895 if (data->priv->order == EXIF_BYTE_ORDER_INTEL) {
00896 memcpy (*d + 6, "II", 2);
00897 } else {
00898 memcpy (*d + 6, "MM", 2);
00899 }
00900
00901
00902 exif_set_short (*d + 8, data->priv->order, 0x002a);
00903
00904
00905
00906
00907
00908
00909
00910 exif_set_long (*d + 10, data->priv->order, 8);
00911
00912
00913 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00914 "Saving IFDs...");
00915 exif_data_save_data_content (data, data->ifd[EXIF_IFD_0], d, ds,
00916 *ds - 6);
00917 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
00918 "Saved %i byte(s) EXIF data.", *ds);
00919 }
00920
00921 ExifData *
00922 exif_data_new_from_file (const char *path)
00923 {
00924 ExifData *edata;
00925 ExifLoader *loader;
00926
00927 loader = exif_loader_new ();
00928 exif_loader_write_file (loader, path);
00929 edata = exif_loader_get_data (loader);
00930 exif_loader_unref (loader);
00931
00932 return (edata);
00933 }
00934
00935 void
00936 exif_data_ref (ExifData *data)
00937 {
00938 if (!data)
00939 return;
00940
00941 data->priv->ref_count++;
00942 }
00943
00944 void
00945 exif_data_unref (ExifData *data)
00946 {
00947 if (!data)
00948 return;
00949
00950 data->priv->ref_count--;
00951 if (!data->priv->ref_count)
00952 exif_data_free (data);
00953 }
00954
00955 void
00956 exif_data_free (ExifData *data)
00957 {
00958 unsigned int i;
00959 ExifMem *mem = (data && data->priv) ? data->priv->mem : NULL;
00960
00961 if (!data)
00962 return;
00963
00964 for (i = 0; i < EXIF_IFD_COUNT; i++) {
00965 if (data->ifd[i]) {
00966 exif_content_unref (data->ifd[i]);
00967 data->ifd[i] = NULL;
00968 }
00969 }
00970
00971 if (data->data) {
00972 exif_mem_free (mem, data->data);
00973 data->data = NULL;
00974 }
00975
00976 if (data->priv) {
00977 if (data->priv->log) {
00978 exif_log_unref (data->priv->log);
00979 data->priv->log = NULL;
00980 }
00981 if (data->priv->md) {
00982 exif_mnote_data_unref (data->priv->md);
00983 data->priv->md = NULL;
00984 }
00985 exif_mem_free (mem, data->priv);
00986 exif_mem_free (mem, data);
00987 }
00988
00989 exif_mem_unref (mem);
00990 }
00991
00992 void
00993 exif_data_dump (ExifData *data)
00994 {
00995 unsigned int i;
00996
00997 if (!data)
00998 return;
00999
01000 for (i = 0; i < EXIF_IFD_COUNT; i++) {
01001 if (data->ifd[i] && data->ifd[i]->count) {
01002 printf ("Dumping IFD '%s'...\n",
01003 exif_ifd_get_name (i));
01004 exif_content_dump (data->ifd[i], 0);
01005 }
01006 }
01007
01008 if (data->data) {
01009 printf ("%i byte(s) thumbnail data available.", data->size);
01010 if (data->size >= 4) {
01011 printf ("0x%02x 0x%02x ... 0x%02x 0x%02x\n",
01012 data->data[0], data->data[1],
01013 data->data[data->size - 2],
01014 data->data[data->size - 1]);
01015 }
01016 }
01017 }
01018
01019 ExifByteOrder
01020 exif_data_get_byte_order (ExifData *data)
01021 {
01022 if (!data)
01023 return (0);
01024
01025 return (data->priv->order);
01026 }
01027
01028 void
01029 exif_data_foreach_content (ExifData *data, ExifDataForeachContentFunc func,
01030 void *user_data)
01031 {
01032 unsigned int i;
01033
01034 if (!data || !func)
01035 return;
01036
01037 for (i = 0; i < EXIF_IFD_COUNT; i++)
01038 func (data->ifd[i], user_data);
01039 }
01040
01041 typedef struct _ByteOrderChangeData ByteOrderChangeData;
01042 struct _ByteOrderChangeData {
01043 ExifByteOrder old, new;
01044 };
01045
01046 static void
01047 entry_set_byte_order (ExifEntry *e, void *data)
01048 {
01049 ByteOrderChangeData *d = data;
01050
01051 if (!e)
01052 return;
01053
01054 exif_array_set_byte_order (e->format, e->data, e->components, d->old, d->new);
01055 }
01056
01057 static void
01058 content_set_byte_order (ExifContent *content, void *data)
01059 {
01060 exif_content_foreach_entry (content, entry_set_byte_order, data);
01061 }
01062
01063 void
01064 exif_data_set_byte_order (ExifData *data, ExifByteOrder order)
01065 {
01066 ByteOrderChangeData d;
01067
01068 if (!data || (order == data->priv->order))
01069 return;
01070
01071 d.old = data->priv->order;
01072 d.new = order;
01073 exif_data_foreach_content (data, content_set_byte_order, &d);
01074 data->priv->order = order;
01075 if (data->priv->md)
01076 exif_mnote_data_set_byte_order (data->priv->md, order);
01077 }
01078
01079 void
01080 exif_data_log (ExifData *data, ExifLog *log)
01081 {
01082 unsigned int i;
01083
01084 if (!data || !data->priv)
01085 return;
01086 exif_log_unref (data->priv->log);
01087 data->priv->log = log;
01088 exif_log_ref (log);
01089
01090 for (i = 0; i < EXIF_IFD_COUNT; i++)
01091 exif_content_log (data->ifd[i], log);
01092 }
01093
01094
01095 ExifLog *exif_data_get_log (ExifData *);
01096 ExifLog *
01097 exif_data_get_log (ExifData *data)
01098 {
01099 if (!data || !data->priv)
01100 return NULL;
01101 return data->priv->log;
01102 }
01103
01104 static struct {
01105 ExifDataOption option;
01106 const char *name;
01107 const char *description;
01108 } exif_data_option[] = {
01109 {EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS, N_("Ignore unknown tags"),
01110 N_("Ignore unknown tags when loading EXIF data.")},
01111 {EXIF_DATA_OPTION_FOLLOW_SPECIFICATION, N_("Follow specification"),
01112 N_("Add, correct and remove entries to get EXIF data that follows "
01113 "the specification.")},
01114 {0, NULL, NULL}
01115 };
01116
01117 const char *
01118 exif_data_option_get_name (ExifDataOption o)
01119 {
01120 unsigned int i;
01121
01122 for (i = 0; exif_data_option[i].name; i++)
01123 if (exif_data_option[i].option == o)
01124 break;
01125 return _(exif_data_option[i].name);
01126 }
01127
01128 const char *
01129 exif_data_option_get_description (ExifDataOption o)
01130 {
01131 unsigned int i;
01132
01133 for (i = 0; exif_data_option[i].description; i++)
01134 if (exif_data_option[i].option == o)
01135 break;
01136 return _(exif_data_option[i].description);
01137 }
01138
01139 void
01140 exif_data_set_option (ExifData *d, ExifDataOption o)
01141 {
01142 if (!d)
01143 return;
01144
01145 d->priv->options |= o;
01146 }
01147
01148 void
01149 exif_data_unset_option (ExifData *d, ExifDataOption o)
01150 {
01151 if (!d)
01152 return;
01153
01154 d->priv->options &= ~o;
01155 }
01156
01157 static void
01158 fix_func (ExifContent *c, void *data)
01159 {
01160 switch (exif_content_get_ifd (c)) {
01161 case EXIF_IFD_1:
01162 if (c->parent->data)
01163 exif_content_fix (c);
01164 else {
01165 exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data",
01166 "No thumbnail but entries on thumbnail. These entries have been "
01167 "removed.");
01168 while (c->count)
01169 exif_content_remove_entry (c, c->entries[c->count - 1]);
01170 }
01171 break;
01172 default:
01173 exif_content_fix (c);
01174 }
01175 }
01176
01177 void
01178 exif_data_fix (ExifData *d)
01179 {
01180 exif_data_foreach_content (d, fix_func, NULL);
01181 }
01182
01183 void
01184 exif_data_set_data_type (ExifData *d, ExifDataType dt)
01185 {
01186 if (!d || !d->priv)
01187 return;
01188
01189 d->priv->data_type = dt;
01190 }
01191
01192 ExifDataType
01193 exif_data_get_data_type (ExifData *d)
01194 {
01195 return (d && d->priv) ? d->priv->data_type : EXIF_DATA_TYPE_COUNT;
01196 }