EXIF library (libexif) Internals 0.6.26
exif-data.c
Go to the documentation of this file.
1/* exif-data.c
2 *
3 * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA.
19 *
20 * SPDX-License-Identifier: LGPL-2.0-or-later
21 */
22
23#include <config.h>
24
26#include <libexif/exif-data.h>
27#include <libexif/exif-ifd.h>
29#include <libexif/exif-utils.h>
30#include <libexif/exif-loader.h>
31#include <libexif/exif-log.h>
32#include <libexif/i18n.h>
33#include <libexif/exif-system.h>
34
35/*#include <libexif/apple/exif-mnote-data-apple.h>*/
40
41#include <math.h>
42#include <stdlib.h>
43#include <stdio.h>
44#include <string.h>
45
46#undef JPEG_MARKER_SOI
47#define JPEG_MARKER_SOI 0xd8
48#undef JPEG_MARKER_APP0
49#define JPEG_MARKER_APP0 0xe0
50#undef JPEG_MARKER_APP1
51#define JPEG_MARKER_APP1 0xe1
52
53#define CHECKOVERFLOW(offset,datasize,structsize) (( (offset) >= (datasize)) || ((structsize) > (datasize)) || ((offset) > (datasize) - (structsize) ))
54
55static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
56
58{
60
62
65
66 unsigned int ref_count;
67
68 /* Temporarily used while loading data */
69 unsigned int offset_mnote;
70
73};
74
75static void *
76exif_data_alloc (ExifData *data, unsigned int i)
77{
78 void *d;
79
80 if (!data || !i)
81 return NULL;
82
83 d = exif_mem_alloc (data->priv->mem, i);
84 if (d)
85 return d;
86
87 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", i);
88 return NULL;
89}
90
93{
94 return (d && d->priv) ? d->priv->md : NULL;
95}
96
99{
101 ExifData *d = exif_data_new_mem (mem);
102
103 exif_mem_unref (mem);
104
105 return d;
106}
107
108ExifData *
110{
111 ExifData *data;
112 unsigned int i;
113
114 if (!mem)
115 return NULL;
116
117 data = exif_mem_alloc (mem, sizeof (ExifData));
118 if (!data)
119 return (NULL);
120 data->priv = exif_mem_alloc (mem, sizeof (ExifDataPrivate));
121 if (!data->priv) {
122 exif_mem_free (mem, data);
123 return (NULL);
124 }
125 data->priv->ref_count = 1;
126
127 data->priv->mem = mem;
128 exif_mem_ref (mem);
129
130 for (i = 0; i < EXIF_IFD_COUNT; i++) {
131 data->ifd[i] = exif_content_new_mem (data->priv->mem);
132 if (!data->ifd[i]) {
133 exif_data_free (data);
134 return (NULL);
135 }
136 data->ifd[i]->parent = data;
137 }
138
139 /* Default options */
140#ifndef NO_VERBOSE_TAG_STRINGS
141 /*
142 * When the tag list is compiled away, setting this option prevents
143 * any tags from being loaded
144 */
146#endif
148
149 /* Default data type: none */
151
152 return (data);
153}
154
155ExifData *
156exif_data_new_from_data (const unsigned char *data, unsigned int size)
157{
158 ExifData *edata;
159
160 edata = exif_data_new ();
161 exif_data_load_data (edata, data, size);
162 return (edata);
163}
164
165static int
167 const unsigned char *d,
168 unsigned int size, unsigned int offset)
169{
170 unsigned int s, doff;
171
172 entry->tag = exif_get_short (d + offset + 0, data->priv->order);
173 entry->format = exif_get_short (d + offset + 2, data->priv->order);
174 entry->components = exif_get_long (d + offset + 4, data->priv->order);
175
176 /* FIXME: should use exif_tag_get_name_in_ifd here but entry->parent
177 * has not been set yet
178 */
179 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
180 "Loading entry 0x%x ('%s')...", entry->tag,
181 exif_tag_get_name (entry->tag));
182
183 /* {0,1,2,4,8} x { 0x00000000 .. 0xffffffff }
184 * -> { 0x000000000 .. 0x7fffffff8 } */
185 s = exif_format_get_size(entry->format) * entry->components;
186 if ((s < entry->components) || (s == 0)){
187 return 0;
188 }
189
190 /*
191 * Size? If bigger than 4 bytes, the actual data is not
192 * in the entry but somewhere else (offset).
193 */
194 if (s > 4)
195 doff = exif_get_long (d + offset + 8, data->priv->order);
196 else
197 doff = offset + 8;
198
199 /* Sanity checks */
200 if (doff >= size) {
201 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
202 "Tag starts past end of buffer (%u > %u)", doff, size);
203 return 0;
204 }
205
206 if (s > size - doff) {
207 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
208 "Tag data goes past end of buffer (%u > %u)", doff+s, size);
209 return 0;
210 }
211
212 entry->data = exif_data_alloc (data, s);
213 if (entry->data) {
214 entry->size = s;
215 memcpy (entry->data, d + doff, s);
216 } else {
217 EXIF_LOG_NO_MEMORY(data->priv->log, "ExifData", s);
218 return 0;
219 }
220
221 /* If this is the MakerNote, remember the offset */
222 if (entry->tag == EXIF_TAG_MAKER_NOTE) {
223 if (!entry->data) {
224 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
225 "MakerNote found with empty data");
226 } else if (entry->size > 6) {
227 exif_log (data->priv->log,
228 EXIF_LOG_CODE_DEBUG, "ExifData",
229 "MakerNote found (%02x %02x %02x %02x "
230 "%02x %02x %02x...).",
231 entry->data[0], entry->data[1], entry->data[2],
232 entry->data[3], entry->data[4], entry->data[5],
233 entry->data[6]);
234 }
235 data->priv->offset_mnote = doff;
236 }
237 return 1;
238}
239
240static void
242 unsigned char **d, unsigned int *ds,
243 unsigned int offset)
244{
245 unsigned int doff, s;
246 unsigned int ts;
247
248 if (!data || !data->priv)
249 return;
250
251 /*
252 * Each entry is 12 bytes long. The memory for the entry has
253 * already been allocated.
254 */
255 exif_set_short (*d + 6 + offset + 0,
256 data->priv->order, (ExifShort) e->tag);
257 exif_set_short (*d + 6 + offset + 2,
258 data->priv->order, (ExifShort) e->format);
259
261 /* If this is the maker note tag, update it. */
262 if ((e->tag == EXIF_TAG_MAKER_NOTE) && data->priv->md) {
263 /* TODO: this is using the wrong ExifMem to free e->data */
264 exif_mem_free (data->priv->mem, e->data);
265 e->data = NULL;
266 e->size = 0;
267 exif_mnote_data_set_offset (data->priv->md, *ds - 6);
268 exif_mnote_data_save (data->priv->md, &e->data, &e->size);
269 e->components = e->size;
270 if (exif_format_get_size (e->format) != 1) {
271 /* e->format is taken from input code,
272 * but we need to make sure it is a 1 byte
273 * entity due to the multiplication below. */
275 }
276 }
277 }
278
279 exif_set_long (*d + 6 + offset + 4,
280 data->priv->order, e->components);
281
282 /*
283 * Size? If bigger than 4 bytes, the actual data is not in
284 * the entry but somewhere else.
285 */
286 /* we usually have only 64kb datablock, so add a safety bound to avoid overflows */
287 if (e->components > 65536) {
288 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", _("Overflow in components detected."));
289 return;
290 }
292 if (s > 4) {
293 unsigned char *t;
294 doff = *ds - 6;
295 ts = *ds + s;
296
297 /*
298 * According to the TIFF specification,
299 * the offset must be an even number. If we need to introduce
300 * a padding byte, we set it to 0.
301 */
302 if (s & 1)
303 ts++;
304 t = exif_mem_realloc (data->priv->mem, *d, ts);
305 if (!t) {
306 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", ts);
307 return;
308 }
309 *d = t;
310 *ds = ts;
311 exif_set_long (*d + 6 + offset + 8, data->priv->order, doff);
312 if (s & 1)
313 *(*d + *ds - 1) = '\0';
314
315 } else
316 doff = offset + 8;
317
318 /* Write the data. Fill unneeded bytes with 0. Do not crash with
319 * e->data is NULL */
320 if (e->data) {
321 unsigned int len = s;
322 if (e->size < s) len = e->size;
323 memcpy (*d + 6 + doff, e->data, len);
324 } else {
325 memset (*d + 6 + doff, 0, s);
326 }
327 if (s < 4)
328 memset (*d + 6 + doff + s, 0, (4 - s));
329}
330
331static void
332exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d,
333 unsigned int ds, ExifLong o, ExifLong s)
334{
335 /* Sanity checks */
336 if (o >= ds) {
337 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail offset (%u).", o);
338 return;
339 }
340 if (CHECKOVERFLOW(o,ds,s)) {
341 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail size (%u), max would be %u.", s, ds-o);
342 return;
343 }
344 if (data->data)
345 exif_mem_free (data->priv->mem, data->data);
346 if (!(data->data = exif_data_alloc (data, s))) {
347 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", s);
348 data->size = 0;
349 return;
350 }
351 data->size = s;
352 memcpy (data->data, d + o, s);
353}
354
355#undef CHECK_REC
356#define CHECK_REC(i) \
357if ((i) == ifd) { \
358 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \
359 "ExifData", "Recursive entry in IFD " \
360 "'%s' detected. Skipping...", \
361 exif_ifd_get_name (i)); \
362 break; \
363} \
364if (data->ifd[(i)]->count) { \
365 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \
366 "ExifData", "Attempt to load IFD " \
367 "'%s' multiple times detected. " \
368 "Skipping...", \
369 exif_ifd_get_name (i)); \
370 break; \
371}
372
378static unsigned int
379level_cost(unsigned int n)
380{
381 static const double log_1_1 = 0.09531017980432493;
382
383 /* Adding 0.1 protects against the case where n==1 */
384 return ceil(log(n + 0.1)/log_1_1);
385}
386
397static void
399 const unsigned char *d,
400 unsigned int ds, unsigned int offset, unsigned int recursion_cost)
401{
402 ExifLong o, thumbnail_offset = 0, thumbnail_length = 0;
403 ExifShort n;
404 ExifEntry *entry;
405 unsigned int i;
406 ExifTag tag;
407
408 if (!data || !data->priv)
409 return;
410
411 /* check for valid ExifIfd enum range */
412 if ((((int)ifd) < 0) || ( ((int)ifd) >= EXIF_IFD_COUNT))
413 return;
414
415 if (recursion_cost > 170) {
416 /*
417 * recursion_cost is a logarithmic-scale indicator of how expensive this
418 * recursive call might end up being. It is an indicator of the depth of
419 * recursion as well as the potential for worst-case future recursive
420 * calls. Since it's difficult to tell ahead of time how often recursion
421 * will occur, this assumes the worst by assuming every tag could end up
422 * causing recursion.
423 * The value of 170 was chosen to limit typical EXIF structures to a
424 * recursive depth of about 6, but pathological ones (those with very
425 * many tags) to only 2.
426 */
427 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData",
428 "Deep/expensive recursion detected!");
429 return;
430 }
431
432 /* Read the number of entries */
433 if (CHECKOVERFLOW(offset, ds, 2)) {
434 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData",
435 "Tag data past end of buffer (%u+2 > %u)", offset, ds);
436 return;
437 }
438 n = exif_get_short (d + offset, data->priv->order);
439 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
440 "Loading %hu entries...", n);
441 offset += 2;
442
443 /* Check if we have enough data. */
444 if (CHECKOVERFLOW(offset, ds, 12*n)) {
445 n = (ds - offset) / 12;
446 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
447 "Short data; only loading %hu entries...", n);
448 }
449
450 for (i = 0; i < n; i++) {
451
452 tag = exif_get_short (d + offset + 12 * i, data->priv->order);
453 switch (tag) {
459 o = exif_get_long (d + offset + 12 * i + 8,
460 data->priv->order);
461 if (o >= ds) {
462 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData",
463 "Tag data past end of buffer (%u > %u)", offset+2, ds);
464 if (recursion_cost > 0)
465 return;
466 break;
467 }
468 /* FIXME: IFD_POINTER tags aren't marked as being in a
469 * specific IFD, so exif_tag_get_name_in_ifd won't work
470 */
471 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
472 "Sub-IFD entry 0x%x ('%s') at %u.", tag,
474 switch (tag) {
478 recursion_cost + level_cost(n));
479 break;
483 recursion_cost + level_cost(n));
484 break;
488 recursion_cost + level_cost(n));
489 break;
491 thumbnail_offset = o;
492 if (thumbnail_offset && thumbnail_length)
494 ds, thumbnail_offset,
495 thumbnail_length);
496 break;
498 thumbnail_length = o;
499 if (thumbnail_offset && thumbnail_length)
501 ds, thumbnail_offset,
502 thumbnail_length);
503 break;
504 default:
505 return;
506 }
507 break;
508 default:
509
510 /*
511 * If we don't know the tag, don't fail. It could be that new
512 * versions of the standard have defined additional tags. Note that
513 * 0 is a valid tag in the GPS IFD.
514 */
516
517 /*
518 * Special case: Tag and format 0. That's against specification
519 * (at least up to 2.2). But Photoshop writes it anyways.
520 */
521 if (!memcmp (d + offset + 12 * i, "\0\0\0\0", 4)) {
522 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
523 "Skipping empty entry at position %u in '%s'.", i,
525 break;
526 }
527 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
528 "Unknown tag 0x%04x (entry %u in '%s'). Please report this tag "
529 "to <libexif-devel@lists.sourceforge.net>.", tag, i,
532 break;
533 }
534 entry = exif_entry_new_mem (data->priv->mem);
535 if (!entry) {
536 exif_log (data->priv->log, EXIF_LOG_CODE_NO_MEMORY, "ExifData",
537 "Could not allocate memory");
538 return;
539 }
540 if (exif_data_load_data_entry (data, entry, d, ds,
541 offset + 12 * i))
542 exif_content_add_entry (data->ifd[ifd], entry);
543 exif_entry_unref (entry);
544 break;
545 }
546 }
547}
548
549static int
550cmp_func (const unsigned char *p1, const unsigned char *p2, ExifByteOrder o)
551{
552 ExifShort tag1 = exif_get_short (p1, o);
553 ExifShort tag2 = exif_get_short (p2, o);
554
555 return (tag1 < tag2) ? -1 : (tag1 > tag2) ? 1 : 0;
556}
557
558static int
559cmp_func_intel (const void *elem1, const void *elem2)
560{
561 return cmp_func ((const unsigned char *) elem1,
562 (const unsigned char *) elem2, EXIF_BYTE_ORDER_INTEL);
563}
564
565static int
566cmp_func_motorola (const void *elem1, const void *elem2)
567{
568 return cmp_func ((const unsigned char *) elem1,
569 (const unsigned char *) elem2, EXIF_BYTE_ORDER_MOTOROLA);
570}
571
572static void
574 unsigned char **d, unsigned int *ds,
575 unsigned int offset)
576{
577 unsigned int j, n_ptr = 0, n_thumb = 0;
578 ExifIfd i;
579 unsigned char *t;
580 unsigned int ts;
581
582 if (!data || !data->priv || !ifd || !d || !ds)
583 return;
584
585 for (i = 0; i < EXIF_IFD_COUNT; i++)
586 if (ifd == data->ifd[i])
587 break;
588 if (i == EXIF_IFD_COUNT)
589 return; /* error */
590
591 /*
592 * Check if we need some extra entries for pointers or the thumbnail.
593 */
594 switch (i) {
595 case EXIF_IFD_0:
596
597 /*
598 * The pointer to IFD_EXIF is in IFD_0. The pointer to
599 * IFD_INTEROPERABILITY is in IFD_EXIF.
600 */
601 if (data->ifd[EXIF_IFD_EXIF]->count ||
603 n_ptr++;
604
605 /* The pointer to IFD_GPS is in IFD_0. */
606 if (data->ifd[EXIF_IFD_GPS]->count)
607 n_ptr++;
608
609 break;
610 case EXIF_IFD_1:
611 if (data->size)
612 n_thumb = 2;
613 break;
614 case EXIF_IFD_EXIF:
616 n_ptr++;
617 default:
618 break;
619 }
620
621 /*
622 * Allocate enough memory for all entries
623 * and the number of entries.
624 */
625 ts = *ds + (2 + (ifd->count + n_ptr + n_thumb) * 12 + 4);
626 t = exif_mem_realloc (data->priv->mem, *d, ts);
627 if (!t) {
628 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", ts);
629 return;
630 }
631 *d = t;
632 *ds = ts;
633
634 /* Save the number of entries */
635 exif_set_short (*d + 6 + offset, data->priv->order,
636 (ExifShort) (ifd->count + n_ptr + n_thumb));
637 offset += 2;
638
639 /*
640 * Save each entry. Make sure that no memcpys from NULL pointers are
641 * performed
642 */
643 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
644 "Saving %i entries (IFD '%s', offset: %i)...",
645 ifd->count, exif_ifd_get_name (i), offset);
646 for (j = 0; j < ifd->count; j++) {
647 if (ifd->entries[j]) {
648 exif_data_save_data_entry (data, ifd->entries[j], d, ds,
649 offset + 12 * j);
650 }
651 }
652
653 offset += 12 * ifd->count;
654
655 /* Now save special entries. */
656 switch (i) {
657 case EXIF_IFD_0:
658
659 /*
660 * The pointer to IFD_EXIF is in IFD_0.
661 * However, the pointer to IFD_INTEROPERABILITY is in IFD_EXIF,
662 * therefore, if IFD_INTEROPERABILITY is not empty, we need
663 * IFD_EXIF even if latter is empty.
664 */
665 if (data->ifd[EXIF_IFD_EXIF]->count ||
667 exif_set_short (*d + 6 + offset + 0, data->priv->order,
669 exif_set_short (*d + 6 + offset + 2, data->priv->order,
671 exif_set_long (*d + 6 + offset + 4, data->priv->order,
672 1);
673 exif_set_long (*d + 6 + offset + 8, data->priv->order,
674 *ds - 6);
676 data->ifd[EXIF_IFD_EXIF], d, ds, *ds - 6);
677 offset += 12;
678 }
679
680 /* The pointer to IFD_GPS is in IFD_0, too. */
681 if (data->ifd[EXIF_IFD_GPS]->count) {
682 exif_set_short (*d + 6 + offset + 0, data->priv->order,
684 exif_set_short (*d + 6 + offset + 2, data->priv->order,
686 exif_set_long (*d + 6 + offset + 4, data->priv->order,
687 1);
688 exif_set_long (*d + 6 + offset + 8, data->priv->order,
689 *ds - 6);
691 data->ifd[EXIF_IFD_GPS], d, ds, *ds - 6);
692 offset += 12;
693 }
694
695 break;
696 case EXIF_IFD_EXIF:
697
698 /*
699 * The pointer to IFD_INTEROPERABILITY is in IFD_EXIF.
700 * See note above.
701 */
702 if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) {
703 exif_set_short (*d + 6 + offset + 0, data->priv->order,
705 exif_set_short (*d + 6 + offset + 2, data->priv->order,
707 exif_set_long (*d + 6 + offset + 4, data->priv->order,
708 1);
709 exif_set_long (*d + 6 + offset + 8, data->priv->order,
710 *ds - 6);
712 data->ifd[EXIF_IFD_INTEROPERABILITY], d, ds,
713 *ds - 6);
714 offset += 12;
715 }
716
717 break;
718 case EXIF_IFD_1:
719
720 /*
721 * Information about the thumbnail (if any) is saved in
722 * IFD_1.
723 */
724 if (data->size) {
725
726 /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT */
727 exif_set_short (*d + 6 + offset + 0, data->priv->order,
729 exif_set_short (*d + 6 + offset + 2, data->priv->order,
731 exif_set_long (*d + 6 + offset + 4, data->priv->order,
732 1);
733 exif_set_long (*d + 6 + offset + 8, data->priv->order,
734 *ds - 6);
735 ts = *ds + data->size;
736 t = exif_mem_realloc (data->priv->mem, *d, ts);
737 if (!t) {
738 EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData",
739 ts);
740 return;
741 }
742 *d = t;
743 *ds = ts;
744 memcpy (*d + *ds - data->size, data->data, data->size);
745 offset += 12;
746
747 /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH */
748 exif_set_short (*d + 6 + offset + 0, data->priv->order,
750 exif_set_short (*d + 6 + offset + 2, data->priv->order,
752 exif_set_long (*d + 6 + offset + 4, data->priv->order,
753 1);
754 exif_set_long (*d + 6 + offset + 8, data->priv->order,
755 data->size);
756 offset += 12;
757 }
758
759 break;
760 default:
761 break;
762 }
763
764 /* Sort the directory according to TIFF specification */
765 qsort (*d + 6 + offset - (ifd->count + n_ptr + n_thumb) * 12,
766 (ifd->count + n_ptr + n_thumb), 12,
768
769 /* Correctly terminate the directory */
770 if (i == EXIF_IFD_0 && (data->ifd[EXIF_IFD_1]->count ||
771 data->size)) {
772
773 /*
774 * We are saving IFD 0. Tell where IFD 1 starts and save
775 * IFD 1.
776 */
777 exif_set_long (*d + 6 + offset, data->priv->order, *ds - 6);
778 exif_data_save_data_content (data, data->ifd[EXIF_IFD_1], d, ds,
779 *ds - 6);
780 } else
781 exif_set_long (*d + 6 + offset, data->priv->order, 0);
782}
783
784typedef enum {
793
800static void
801interpret_maker_note(ExifData *data, const unsigned char *d, unsigned int ds)
802{
803 int mnoteid;
805 if (!e)
806 return;
807
808 if ((mnoteid = exif_mnote_data_olympus_identify (data, e)) != 0) {
810 "ExifData", "Olympus MakerNote variant type %d", mnoteid);
811 data->priv->md = exif_mnote_data_olympus_new (data->priv->mem);
812
813 } else if ((mnoteid = exif_mnote_data_canon_identify (data, e)) != 0) {
815 "ExifData", "Canon MakerNote variant type %d", mnoteid);
816 data->priv->md = exif_mnote_data_canon_new (data->priv->mem, data->priv->options);
817
818 } else if ((mnoteid = exif_mnote_data_fuji_identify (data, e)) != 0) {
820 "ExifData", "Fuji MakerNote variant type %d", mnoteid);
821 data->priv->md = exif_mnote_data_fuji_new (data->priv->mem);
822
823 /* NOTE: Must do Pentax detection last because some of the
824 * heuristics are pretty general. */
825 } else if ((mnoteid = exif_mnote_data_pentax_identify (data, e)) != 0) {
827 "ExifData", "Pentax MakerNote variant type %d", mnoteid);
828 data->priv->md = exif_mnote_data_pentax_new (data->priv->mem);
829 }
830/* Marcus: disabled until apple makernote can also be saved
831 else if ((mnoteid = exif_mnote_data_apple_identify (data, e)) != 0) {
832 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG,
833 "ExifData", "Apple MakerNote variant type %d", mnoteid);
834 data->priv->md = exif_mnote_data_apple_new (data->priv->mem);
835 }
836*/
837
838 /*
839 * If we are able to interpret the maker note, do so.
840 */
841 if (data->priv->md) {
842 exif_mnote_data_log (data->priv->md, data->priv->log);
844 data->priv->order);
846 data->priv->offset_mnote);
847 exif_mnote_data_load (data->priv->md, d, ds);
848 }
849}
850
851#define LOG_TOO_SMALL \
852exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", \
853 _("Size of data too small to allow for EXIF data."))
854
855void
856exif_data_load_data (ExifData *data, const unsigned char *d_orig,
857 unsigned int ds)
858{
859 unsigned int l;
860 ExifLong offset;
861 ExifShort n;
862 const unsigned char *d = d_orig;
863 unsigned int len, fullds;
864
865 if (!data || !data->priv || !d || !ds)
866 return;
867
868 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
869 "Parsing %i byte(s) EXIF data...\n", ds);
870
871 /*
872 * It can be that the data starts with the EXIF header. If it does
873 * not, search the EXIF marker.
874 */
875 if (ds < 6) {
877 return;
878 }
879 if (!memcmp (d, ExifHeader, 6)) {
880 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
881 "Found EXIF header at start.");
882 } else {
883 while (ds >= 3) {
884 while (ds && (d[0] == 0xff)) {
885 d++;
886 ds--;
887 }
888
889 /* JPEG_MARKER_SOI */
890 if (ds && d[0] == JPEG_MARKER_SOI) {
891 d++;
892 ds--;
893 continue;
894 }
895
896 /* JPEG_MARKER_APP1 */
897 if (ds && d[0] == JPEG_MARKER_APP1) {
898 /*
899 * Verify the exif header
900 * (offset 3, length 6).
901 * FF E1 NN NN EXIFHEADER
902 * ^^ d points here currently
903 */
904 if ((ds >= 9) && !memcmp (d+3, ExifHeader, 6))
905 break;
906 /* fallthrough */
907 }
908 /* Skip irrelevant APP markers. The branch for APP1 must come before this,
909 otherwise this code block will cause APP1 to be skipped. This code path
910 is only relevant for files that are nonconformant to the EXIF
911 specification. For conformant files, the APP1 code path above will be
912 taken. */
913 if (ds >= 3 && d[0] >= 0xe0 && d[0] <= 0xef) { /* JPEG_MARKER_APPn */
914 d++;
915 ds--;
916 l = (((unsigned int)d[0]) << 8) | d[1];
917 if (l > ds)
918 return;
919 d += l;
920 ds -= l;
921 continue;
922 }
923
924 /* Unknown marker or data. Give up. */
926 "ExifData", _("EXIF marker not found."));
927 return;
928 }
929 if (ds < 3) {
931 return;
932 }
933 d++;
934 ds--;
935 len = (((unsigned int)d[0]) << 8) | d[1];
936 if (len > ds) {
938 "ExifData", _("Read length %d is longer than data length %d."), len, ds);
939 return;
940 }
941 if (len < 2) {
943 "ExifData", _("APP Tag too short."));
944 return;
945 }
946 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
947 "We have to deal with %i byte(s) of EXIF data.",
948 len);
949 d += 2;
950 ds = len - 2; /* we do not want the full rest size, but only the size of the tag */
951 }
952
953 /*
954 * Verify the exif header
955 * (offset 2, length 6).
956 */
957 if (ds < 6) {
959 return;
960 }
961 if (memcmp (d, ExifHeader, 6)) {
963 "ExifData", _("EXIF header not found."));
964 return;
965 }
966
967 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
968 "Found EXIF header.");
969
970 /* Sanity check the data length */
971 if (ds < 14)
972 return;
973
974 /* The JPEG APP1 section can be no longer than 64 KiB (including a
975 16-bit length), so cap the data length to protect against overflow
976 in future offset calculations */
977 fullds = ds;
978 if (ds > 0xfffe)
979 ds = 0xfffe;
980
981 /* Byte order (offset 6, length 2) */
982 if (!memcmp (d + 6, "II", 2))
984 else if (!memcmp (d + 6, "MM", 2))
986 else {
988 "ExifData", _("Unknown encoding."));
989 return;
990 }
991
992 /* Fixed value */
993 if (exif_get_short (d + 8, data->priv->order) != 0x002a)
994 return;
995
996 /* IFD 0 offset */
997 offset = exif_get_long (d + 10, data->priv->order);
998 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
999 "IFD 0 at %i.", (int) offset);
1000
1001 /* ds is restricted to 16 bit above, so offset is restricted too, and offset+8 should not overflow. */
1002 if (offset > ds || offset + 6 + 2 > ds)
1003 return;
1004
1005 /* Parse the actual exif data (usually offset 14 from start) */
1006 exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0);
1007
1008 /* IFD 1 offset */
1009 n = exif_get_short (d + 6 + offset, data->priv->order);
1010 /* offset < 2<<16, n is 16 bit at most, so this op will not overflow */
1011 if (offset + 6 + 2 + 12 * n + 4 > ds)
1012 return;
1013
1014 offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order);
1015 if (offset) {
1016 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
1017 "IFD 1 at %i.", (int) offset);
1018
1019 /* Sanity check. ds is ensured to be above 6 above, offset is 16bit */
1020 if (offset > ds - 6) {
1022 "ExifData", "Bogus offset of IFD1.");
1023 } else {
1024 exif_data_load_data_content (data, EXIF_IFD_1, d + 6, ds - 6, offset, 0);
1025 }
1026 }
1027
1028 /*
1029 * If we got an EXIF_TAG_MAKER_NOTE, try to interpret it. Some
1030 * cameras use pointers in the maker note tag that point to the
1031 * space between IFDs. Here is the only place where we have access
1032 * to that data.
1033 */
1034 interpret_maker_note(data, d, fullds);
1035
1036 /* Fixup tags if requested */
1038 exif_data_fix (data);
1039}
1040
1041void
1042exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds)
1043{
1044 if (ds)
1045 *ds = 0; /* This means something went wrong */
1046
1047 if (!data || !d || !ds)
1048 return;
1049
1050 /* Header */
1051 *ds = 14;
1052 *d = exif_data_alloc (data, *ds);
1053 if (!*d) {
1054 *ds = 0;
1055 return;
1056 }
1057 memcpy (*d, ExifHeader, 6);
1058
1059 /* Order (offset 6) */
1060 if (data->priv->order == EXIF_BYTE_ORDER_INTEL) {
1061 memcpy (*d + 6, "II", 2);
1062 } else {
1063 memcpy (*d + 6, "MM", 2);
1064 }
1065
1066 /* Fixed value (2 bytes, offset 8) */
1067 exif_set_short (*d + 8, data->priv->order, 0x002a);
1068
1069 /*
1070 * IFD 0 offset (4 bytes, offset 10).
1071 * We will start 8 bytes after the
1072 * EXIF header (2 bytes for order, another 2 for the test, and
1073 * 4 bytes for the IFD 0 offset make 8 bytes together).
1074 */
1075 exif_set_long (*d + 10, data->priv->order, 8);
1076
1077 /* Now save IFD 0. IFD 1 will be saved automatically. */
1078 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
1079 "Saving IFDs...");
1080 exif_data_save_data_content (data, data->ifd[EXIF_IFD_0], d, ds,
1081 *ds - 6);
1082 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
1083 "Saved %i byte(s) EXIF data.", *ds);
1084}
1085
1086ExifData *
1087exif_data_new_from_file (const char *path)
1088{
1089 ExifData *edata;
1090 ExifLoader *loader;
1091
1092 loader = exif_loader_new ();
1093 exif_loader_write_file (loader, path);
1094 edata = exif_loader_get_data (loader);
1095 exif_loader_unref (loader);
1096
1097 return (edata);
1098}
1099
1100void
1102{
1103 if (!data)
1104 return;
1105
1106 data->priv->ref_count++;
1107}
1108
1109void
1111{
1112 if (!data)
1113 return;
1114
1115 data->priv->ref_count--;
1116 if (!data->priv->ref_count)
1117 exif_data_free (data);
1118}
1119
1120void
1122{
1123 unsigned int i;
1124 ExifMem *mem = (data && data->priv) ? data->priv->mem : NULL;
1125
1126 if (!data)
1127 return;
1128
1129 for (i = 0; i < EXIF_IFD_COUNT; i++) {
1130 if (data->ifd[i]) {
1131 exif_content_unref (data->ifd[i]);
1132 data->ifd[i] = NULL;
1133 }
1134 }
1135
1136 if (data->data) {
1137 exif_mem_free (mem, data->data);
1138 data->data = NULL;
1139 }
1140
1141 if (data->priv) {
1142 if (data->priv->log) {
1143 exif_log_unref (data->priv->log);
1144 data->priv->log = NULL;
1145 }
1146 if (data->priv->md) {
1147 exif_mnote_data_unref (data->priv->md);
1148 data->priv->md = NULL;
1149 }
1150 exif_mem_free (mem, data->priv);
1151 exif_mem_free (mem, data);
1152 }
1153
1154 exif_mem_unref (mem);
1155}
1156
1157void
1159{
1160 unsigned int i;
1161
1162 if (!data)
1163 return;
1164
1165 for (i = 0; i < EXIF_IFD_COUNT; i++) {
1166 if (data->ifd[i] && data->ifd[i]->count) {
1167 printf ("Dumping IFD '%s'...\n",
1168 exif_ifd_get_name (i));
1169 exif_content_dump (data->ifd[i], 0);
1170 }
1171 }
1172
1173 if (data->data) {
1174 printf ("%i byte(s) thumbnail data available: ", data->size);
1175 if (data->size >= 4) {
1176 printf ("0x%02x 0x%02x ... 0x%02x 0x%02x\n",
1177 data->data[0], data->data[1],
1178 data->data[data->size - 2],
1179 data->data[data->size - 1]);
1180 }
1181 }
1182}
1183
1186{
1187 if (!data)
1188 return (0);
1189
1190 return (data->priv->order);
1191}
1192
1193void
1195 void *user_data)
1196{
1197 unsigned int i;
1198
1199 if (!data || !func)
1200 return;
1201
1202 for (i = 0; i < EXIF_IFD_COUNT; i++)
1203 func (data->ifd[i], user_data);
1204}
1205
1209};
1210
1211static void
1213{
1214 ByteOrderChangeData *d = data;
1215
1216 if (!e)
1217 return;
1218
1220}
1221
1222static void
1224{
1226}
1227
1228void
1230{
1232
1233 if (!data || (order == data->priv->order))
1234 return;
1235
1236 d.old = data->priv->order;
1237 d.new = order;
1239 data->priv->order = order;
1240 if (data->priv->md)
1241 exif_mnote_data_set_byte_order (data->priv->md, order);
1242}
1243
1244void
1246{
1247 unsigned int i;
1248
1249 if (!data || !data->priv)
1250 return;
1251 exif_log_unref (data->priv->log);
1252 data->priv->log = log;
1253 exif_log_ref (log);
1254
1255 for (i = 0; i < EXIF_IFD_COUNT; i++)
1256 exif_content_log (data->ifd[i], log);
1257}
1258
1259/* Used internally within libexif */
1261ExifLog *
1263{
1264 if (!data || !data->priv)
1265 return NULL;
1266 return data->priv->log;
1267}
1268
1269static const struct {
1271 const char *name;
1272 const char *description;
1273} exif_data_option[] = {
1274 {EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS, N_("Ignore unknown tags"),
1275 N_("Ignore unknown tags when loading EXIF data.")},
1276 {EXIF_DATA_OPTION_FOLLOW_SPECIFICATION, N_("Follow specification"),
1277 N_("Add, correct and remove entries to get EXIF data that follows "
1278 "the specification.")},
1279 {EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE, N_("Do not change maker note"),
1280 N_("When loading and resaving Exif data, save the maker note unmodified."
1281 " Be aware that the maker note can get corrupted.")},
1282 {0, NULL, NULL}
1284
1285const char *
1287{
1288 unsigned int i;
1289
1290 for (i = 0; exif_data_option[i].name; i++)
1291 if (exif_data_option[i].option == o)
1292 break;
1293 return _(exif_data_option[i].name);
1294}
1295
1296const char *
1298{
1299 unsigned int i;
1300
1301 for (i = 0; exif_data_option[i].description; i++)
1302 if (exif_data_option[i].option == o)
1303 break;
1304 return _(exif_data_option[i].description);
1305}
1306
1307void
1309{
1310 if (!d)
1311 return;
1312
1313 d->priv->options |= o;
1314}
1315
1316void
1318{
1319 if (!d)
1320 return;
1321
1322 d->priv->options &= ~o;
1323}
1324
1325static void
1326fix_func (ExifContent *c, void *UNUSED(data))
1327{
1328 switch (exif_content_get_ifd (c)) {
1329 case EXIF_IFD_1:
1330 if (c->parent->data)
1331 exif_content_fix (c);
1332 else if (c->count) {
1333 exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data",
1334 "No thumbnail but entries on thumbnail. These entries have been "
1335 "removed.");
1336 while (c->count) {
1337 unsigned int cnt = c->count;
1338 exif_content_remove_entry (c, c->entries[c->count - 1]);
1339 if (cnt == c->count) {
1340 /* safety net */
1341 exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data",
1342 "failed to remove last entry from entries.");
1343 c->count--;
1344 }
1345 }
1346 }
1347 break;
1348 default:
1349 exif_content_fix (c);
1350 }
1351}
1352
1353void
1355{
1357}
1358
1359void
1361{
1362 if (!d || !d->priv)
1363 return;
1364
1365 d->priv->data_type = dt;
1366}
1367
1370{
1371 return (d && d->priv) ? d->priv->data_type : EXIF_DATA_TYPE_UNKNOWN;
1372}
ExifByteOrder
Which byte order to use.
@ EXIF_BYTE_ORDER_INTEL
Little-endian byte order.
@ EXIF_BYTE_ORDER_MOTOROLA
Big-endian byte order.
void exif_content_remove_entry(ExifContent *c, ExifEntry *e)
Remove an EXIF tag from an IFD.
ExifIfd exif_content_get_ifd(ExifContent *c)
Return the IFD number in which the given ExifContent is found.
void exif_content_fix(ExifContent *c)
Fix the IFD to bring it into specification.
ExifContent * exif_content_new_mem(ExifMem *mem)
Reserve memory for and initialize new ExifContent using the specified memory allocator.
void exif_content_unref(ExifContent *content)
Decrease reference counter for ExifContent.
void exif_content_add_entry(ExifContent *c, ExifEntry *entry)
Add an EXIF tag to an IFD.
void exif_content_dump(ExifContent *content, unsigned int indent)
Dump contents of the IFD to stdout.
void exif_content_log(ExifContent *content, ExifLog *log)
Set the log message object for this IFD.
void exif_content_foreach_entry(ExifContent *content, ExifContentForeachEntryFunc func, void *data)
Executes function on each EXIF tag in this IFD in turn.
ExifDataType
Represents the type of image data to which the EXIF data applies.
@ EXIF_DATA_TYPE_UNKNOWN
@ EXIF_DATA_TYPE_COUNT
#define JPEG_MARKER_APP1
Definition exif-data.c:51
static void exif_data_load_data_thumbnail(ExifData *data, const unsigned char *d, unsigned int ds, ExifLong o, ExifLong s)
Definition exif-data.c:332
static unsigned int level_cost(unsigned int n)
Calculate the recursion cost added by one level of IFD loading.
Definition exif-data.c:379
static int cmp_func(const unsigned char *p1, const unsigned char *p2, ExifByteOrder o)
Definition exif-data.c:550
void exif_data_set_byte_order(ExifData *data, ExifByteOrder order)
Set the byte order to use for this EXIF data.
Definition exif-data.c:1229
ExifData * exif_data_new_mem(ExifMem *mem)
Allocate a new ExifData using the given memory allocator.
Definition exif-data.c:109
#define LOG_TOO_SMALL
Definition exif-data.c:851
static void fix_func(ExifContent *c, void *UNUSED(data))
Definition exif-data.c:1326
void exif_data_unref(ExifData *data)
Definition exif-data.c:1110
void exif_data_free(ExifData *data)
Definition exif-data.c:1121
ExifByteOrder exif_data_get_byte_order(ExifData *data)
Return the byte order in use by this EXIF structure.
Definition exif-data.c:1185
#define CHECK_REC(i)
Definition exif-data.c:356
ExifMnoteData * exif_data_get_mnote_data(ExifData *d)
Return the MakerNote data out of the EXIF data.
Definition exif-data.c:92
ExifDataTypeMakerNote
Definition exif-data.c:784
@ EXIF_DATA_TYPE_MAKER_NOTE_CANON
Definition exif-data.c:786
@ EXIF_DATA_TYPE_MAKER_NOTE_CASIO
Definition exif-data.c:790
@ EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS
Definition exif-data.c:787
@ EXIF_DATA_TYPE_MAKER_NOTE_NONE
Definition exif-data.c:785
@ EXIF_DATA_TYPE_MAKER_NOTE_FUJI
Definition exif-data.c:791
@ EXIF_DATA_TYPE_MAKER_NOTE_NIKON
Definition exif-data.c:789
@ EXIF_DATA_TYPE_MAKER_NOTE_PENTAX
Definition exif-data.c:788
void exif_data_ref(ExifData *data)
Definition exif-data.c:1101
static void * exif_data_alloc(ExifData *data, unsigned int i)
Definition exif-data.c:76
void exif_data_load_data(ExifData *data, const unsigned char *d_orig, unsigned int ds)
Load the ExifData structure from the raw JPEG or EXIF data in the given memory buffer.
Definition exif-data.c:856
ExifDataType exif_data_get_data_type(ExifData *d)
Return the data type for the given ExifData.
Definition exif-data.c:1369
const char * exif_data_option_get_description(ExifDataOption o)
Return a verbose textual description of the given ExifDataOption.
Definition exif-data.c:1297
static void content_set_byte_order(ExifContent *content, void *data)
Definition exif-data.c:1223
const char * description
Definition exif-data.c:1272
#define JPEG_MARKER_SOI
Definition exif-data.c:47
static const unsigned char ExifHeader[]
Definition exif-data.c:55
const char * exif_data_option_get_name(ExifDataOption o)
Return a short textual description of the given ExifDataOption.
Definition exif-data.c:1286
ExifData * exif_data_new(void)
Allocate a new ExifData.
Definition exif-data.c:98
ExifData * exif_data_new_from_data(const unsigned char *data, unsigned int size)
Allocate a new ExifData and load EXIF data from a memory buffer.
Definition exif-data.c:156
static void exif_data_save_data_entry(ExifData *data, ExifEntry *e, unsigned char **d, unsigned int *ds, unsigned int offset)
Definition exif-data.c:241
const char * name
Definition exif-data.c:1271
void exif_data_fix(ExifData *d)
Fix the EXIF data to bring it into specification.
Definition exif-data.c:1354
ExifLog * exif_data_get_log(ExifData *)
Definition exif-data.c:1262
static void entry_set_byte_order(ExifEntry *e, void *data)
Definition exif-data.c:1212
static void interpret_maker_note(ExifData *data, const unsigned char *d, unsigned int ds)
If MakerNote is recognized, load it.
Definition exif-data.c:801
static const struct @3 exif_data_option[]
void exif_data_dump(ExifData *data)
Dump all EXIF data to stdout.
Definition exif-data.c:1158
void exif_data_unset_option(ExifData *d, ExifDataOption o)
Clear the given option on the given ExifData.
Definition exif-data.c:1317
void exif_data_set_data_type(ExifData *d, ExifDataType dt)
Set the data type for the given ExifData.
Definition exif-data.c:1360
ExifData * exif_data_new_from_file(const char *path)
Allocate a new ExifData and load EXIF data from a JPEG file.
Definition exif-data.c:1087
static int cmp_func_intel(const void *elem1, const void *elem2)
Definition exif-data.c:559
static int exif_data_load_data_entry(ExifData *data, ExifEntry *entry, const unsigned char *d, unsigned int size, unsigned int offset)
Definition exif-data.c:166
void exif_data_save_data(ExifData *data, unsigned char **d, unsigned int *ds)
Store raw EXIF data representing the ExifData structure into a memory buffer.
Definition exif-data.c:1042
static void exif_data_save_data_content(ExifData *data, ExifContent *ifd, unsigned char **d, unsigned int *ds, unsigned int offset)
Definition exif-data.c:573
void exif_data_foreach_content(ExifData *data, ExifDataForeachContentFunc func, void *user_data)
Execute a function on each IFD in turn.
Definition exif-data.c:1194
#define CHECKOVERFLOW(offset, datasize, structsize)
Definition exif-data.c:53
ExifDataOption option
Definition exif-data.c:1270
static int cmp_func_motorola(const void *elem1, const void *elem2)
Definition exif-data.c:566
static void exif_data_load_data_content(ExifData *data, ExifIfd ifd, const unsigned char *d, unsigned int ds, unsigned int offset, unsigned int recursion_cost)
Load data for an IFD.
Definition exif-data.c:398
void exif_data_log(ExifData *data, ExifLog *log)
Set the log message object for all IFDs.
Definition exif-data.c:1245
void exif_data_set_option(ExifData *d, ExifDataOption o)
Set the given option on the given ExifData.
Definition exif-data.c:1308
Defines the ExifData type and the associated functions.
ExifDataOption
Options to configure the behaviour of ExifData.
Definition exif-data.h:175
@ EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE
Leave the MakerNote alone, which could cause it to be corrupted.
Definition exif-data.h:183
@ EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS
Act as though unknown tags are not present.
Definition exif-data.h:177
@ EXIF_DATA_OPTION_FOLLOW_SPECIFICATION
Fix the EXIF tags to follow the spec.
Definition exif-data.h:180
#define exif_data_get_entry(d, t)
Return an ExifEntry for the given tag if found in any IFD.
Definition exif-data.h:252
void(* ExifDataForeachContentFunc)(ExifContent *, void *user_data)
Definition exif-data.h:162
ExifEntry * exif_entry_new_mem(ExifMem *mem)
Reserve memory for and initialize new ExifEntry using the specified memory allocator.
Definition exif-entry.c:124
void exif_entry_unref(ExifEntry *e)
Decrease reference counter for ExifEntry.
Definition exif-entry.c:149
unsigned char exif_format_get_size(ExifFormat format)
Return the raw size of the given EXIF data type.
Definition exif-format.c:68
unsigned char size
Definition exif-format.c:37
@ EXIF_FORMAT_LONG
Definition exif-format.h:38
@ EXIF_FORMAT_UNDEFINED
Definition exif-format.h:41
ExifIfd ifd
Definition exif-ifd.c:30
const char * exif_ifd_get_name(ExifIfd ifd)
Return a textual name of the given IFD.
Definition exif-ifd.c:42
ExifIfd
Possible EXIF Image File Directories.
Definition exif-ifd.h:31
@ EXIF_IFD_GPS
Definition exif-ifd.h:35
@ EXIF_IFD_INTEROPERABILITY
Definition exif-ifd.h:36
@ EXIF_IFD_EXIF
Definition exif-ifd.h:34
@ EXIF_IFD_1
Definition exif-ifd.h:33
@ EXIF_IFD_COUNT
Not a real value, just (max_value + 1).
Definition exif-ifd.h:37
@ EXIF_IFD_0
Definition exif-ifd.h:32
ExifLoader * exif_loader_new(void)
Allocate a new ExifLoader.
ExifData * exif_loader_get_data(ExifLoader *loader)
Create an ExifData from the data in the loader.
void exif_loader_unref(ExifLoader *loader)
Decrease the refcount of the ExifLoader.
void exif_loader_write_file(ExifLoader *l, const char *path)
Load a file into the given ExifLoader from the filesystem.
Defines the ExifLoader type.
void exif_log(ExifLog *log, ExifLogCode code, const char *domain, const char *format,...)
Definition exif-log.c:137
void exif_log_unref(ExifLog *log)
Definition exif-log.c:106
void exif_log_ref(ExifLog *log)
Definition exif-log.c:99
Log message infrastructure.
@ EXIF_LOG_CODE_NO_MEMORY
Definition exif-log.h:59
@ EXIF_LOG_CODE_CORRUPT_DATA
Definition exif-log.h:60
@ EXIF_LOG_CODE_DEBUG
Definition exif-log.h:58
#define EXIF_LOG_NO_MEMORY(l, d, s)
Definition exif-log.h:112
void exif_mem_free(ExifMem *mem, void *d)
Definition exif-mem.c:91
void exif_mem_unref(ExifMem *mem)
Unrefcount an ExifMem.
Definition exif-mem.c:83
void * exif_mem_alloc(ExifMem *mem, ExifLong ds)
Definition exif-mem.c:101
void * exif_mem_realloc(ExifMem *mem, void *d, ExifLong ds)
Definition exif-mem.c:111
ExifMem * exif_mem_new_default(void)
Create a new ExifMem with default values for your convenience.
Definition exif-mem.c:117
void exif_mem_ref(ExifMem *mem)
Refcount an ExifMem.
Definition exif-mem.c:76
ExifMnoteData * exif_mnote_data_canon_new(ExifMem *mem, ExifDataOption o)
int exif_mnote_data_canon_identify(const ExifData *ed, const ExifEntry *e)
Detect if MakerNote is recognized as one handled by the Canon module.
ExifMnoteData * exif_mnote_data_fuji_new(ExifMem *mem)
int exif_mnote_data_fuji_identify(const ExifData *ed, const ExifEntry *e)
Detect if MakerNote is recognized as one handled by the Fuji module.
int exif_mnote_data_olympus_identify(const ExifData *ed, const ExifEntry *e)
Detect if MakerNote is recognized as one handled by the Olympus module.
ExifMnoteData * exif_mnote_data_olympus_new(ExifMem *mem)
int exif_mnote_data_pentax_identify(const ExifData *ed, const ExifEntry *e)
Detect if MakerNote is recognized as one handled by the Pentax module.
ExifMnoteData * exif_mnote_data_pentax_new(ExifMem *mem)
void exif_mnote_data_set_offset(ExifMnoteData *, unsigned int)
void exif_mnote_data_set_byte_order(ExifMnoteData *, ExifByteOrder)
void exif_mnote_data_load(ExifMnoteData *d, const unsigned char *buf, unsigned int buf_size)
Load the MakerNote data from a memory buffer.
void exif_mnote_data_save(ExifMnoteData *d, unsigned char **buf, unsigned int *buf_size)
Save the raw MakerNote data into a memory buffer.
void exif_mnote_data_log(ExifMnoteData *d, ExifLog *log)
void exif_mnote_data_unref(ExifMnoteData *d)
Handling EXIF MakerNote tags.
System specific definitions, not for installation!
#define UNUSED(param)
Definition exif-system.h:31
const char * exif_tag_get_name_in_ifd(ExifTag tag, ExifIfd ifd)
Return a textual name of the given tag when found in the given IFD.
Definition exif-tag.c:1042
const char * exif_tag_get_name(ExifTag tag)
Definition exif-tag.c:1151
ExifTag
EXIF tags.
Definition exif-tag.h:36
@ EXIF_TAG_EXIF_IFD_POINTER
Definition exif-tag.h:87
@ EXIF_TAG_GPS_INFO_IFD_POINTER
Definition exif-tag.h:91
@ EXIF_TAG_INTEROPERABILITY_IFD_POINTER
Definition exif-tag.h:136
@ EXIF_TAG_JPEG_INTERCHANGE_FORMAT
Definition exif-tag.h:68
@ EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH
Definition exif-tag.h:69
@ EXIF_TAG_MAKER_NOTE
Definition exif-tag.h:121
ExifLong exif_get_long(const unsigned char *buf, ExifByteOrder order)
Retrieve an ExifLong value from memory.
Definition exif-utils.c:167
ExifShort exif_get_short(const unsigned char *buf, ExifByteOrder order)
Retrieve an ExifShort value from memory.
Definition exif-utils.c:104
void exif_array_set_byte_order(ExifFormat f, unsigned char *b, unsigned int n, ExifByteOrder o_orig, ExifByteOrder o_new)
Definition exif-utils.c:28
void exif_set_long(unsigned char *b, ExifByteOrder order, ExifLong value)
Store an ExifLong value into memory in EXIF format.
Definition exif-utils.c:173
void exif_set_short(unsigned char *b, ExifByteOrder order, ExifShort value)
Store an ExifShort value into memory in EXIF format.
Definition exif-utils.c:126
EXIF data manipulation functions and types.
uint32_t ExifLong
EXIF Unsigned Long data type.
Definition exif-utils.h:56
uint16_t ExifShort
EXIF Unsigned Short data type.
Definition exif-utils.h:50
#define _(String)
Definition i18n.h:50
#define N_(String)
Definition i18n.h:51
MnoteAppleTag tag
ExifByteOrder old
Definition exif-data.c:1208
ExifByteOrder new
Definition exif-data.c:1208
unsigned int count
ExifData * parent
Data containing this content.
ExifEntry ** entries
ExifDataType data_type
Definition exif-data.c:72
ExifDataOption options
Definition exif-data.c:71
unsigned int offset_mnote
Definition exif-data.c:69
ExifMem * mem
Definition exif-data.c:64
ExifLog * log
Definition exif-data.c:63
ExifMnoteData * md
Definition exif-data.c:61
ExifByteOrder order
Definition exif-data.c:59
unsigned int ref_count
Definition exif-data.c:66
Represents the entire EXIF data found in an image.
Definition exif-data.h:48
unsigned char * data
Pointer to thumbnail image, or NULL if not available.
Definition exif-data.h:53
unsigned int size
Number of bytes in thumbnail image at data.
Definition exif-data.h:56
ExifContent * ifd[EXIF_IFD_COUNT]
Data for each IFD.
Definition exif-data.h:50
ExifDataPrivate * priv
Definition exif-data.h:58
Data found in one EXIF tag.
Definition exif-entry.h:45
unsigned long components
Number of elements in the array, if this is an array entry.
Definition exif-entry.h:54
ExifFormat format
Type of data in this entry.
Definition exif-entry.h:50
unsigned char * data
Pointer to the raw EXIF data for this entry.
Definition exif-entry.h:59
ExifTag tag
EXIF tag for this entry.
Definition exif-entry.h:47
unsigned int size
Number of bytes in the buffer at data.
Definition exif-entry.h:63

libexif Generated by doxygen