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