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