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