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