replace (c) and (C) by ©
[platform/upstream/libexif.git] / libexif / exif-data.c
1 /* exif-data.c
2  *
3  * Copyright © 2001 Lutz Müller <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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include "exif-data.h"
23 #include "exif-ifd.h"
24 #include "exif-utils.h"
25 #include "jpeg-marker.h"
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #undef MAX
32 #define MAX(a, b)  (((a) > (b)) ? (a) : (b))
33
34 //#define DEBUG
35
36 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
37
38 struct _ExifDataPrivate
39 {
40         ExifByteOrder order;
41
42         unsigned int ref_count;
43 };
44
45 ExifData *
46 exif_data_new (void)
47 {
48         ExifData *data;
49         unsigned int i;
50
51         data = malloc (sizeof (ExifData));
52         if (!data)
53                 return (NULL);
54         memset (data, 0, sizeof (ExifData));
55         data->priv = malloc (sizeof (ExifDataPrivate));
56         if (!data->priv) {
57                 free (data);
58                 return (NULL);
59         }
60         memset (data->priv, 0, sizeof (ExifDataPrivate));
61         data->priv->ref_count = 1;
62
63         for (i = 0; i < EXIF_IFD_COUNT; i++) {
64                 data->ifd[i] = exif_content_new ();
65                 if (!data->ifd[i]) {
66                         exif_data_free (data);
67                         return (NULL);
68                 }
69                 data->ifd[i]->parent = data;
70         }
71
72         return (data);
73 }
74
75 ExifData *
76 exif_data_new_from_data (const unsigned char *data, unsigned int size)
77 {
78         ExifData *edata;
79
80         edata = exif_data_new ();
81         exif_data_load_data (edata, data, size);
82         return (edata);
83 }
84
85 static void
86 exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
87                            const unsigned char *d,
88                            unsigned int size, unsigned int offset)
89 {
90         unsigned int s, doff;
91
92         entry->tag        = exif_get_short (d + offset + 0, data->priv->order);
93         entry->format     = exif_get_short (d + offset + 2, data->priv->order);
94         entry->components = exif_get_long  (d + offset + 4, data->priv->order);
95
96         /*
97          * Size? If bigger than 4 bytes, the actual data is not
98          * in the entry but somewhere else (offset).
99          */
100         s = exif_format_get_size (entry->format) * entry->components;
101         if (!s)
102                 return;
103         if (s > 4)
104                 doff = exif_get_long (d + offset + 8, data->priv->order);
105         else
106                 doff = offset + 8;
107
108         /* Sanity check */
109         if (size < doff + s)
110                 return;
111
112         entry->data = malloc (sizeof (char) * s);
113         if (!entry->data)
114                 return;
115         entry->size = s;
116         memcpy (entry->data, d + doff, s);
117 }
118
119 static void
120 exif_data_save_data_entry (ExifData *data, ExifEntry *entry,
121                            unsigned char **d, unsigned int *ds,
122                            unsigned int offset)
123 {
124         unsigned int doff, s;
125
126         /*
127          * Each entry is 12 bytes long. The memory for the entry has
128          * already been allocated.
129          */
130         exif_set_short (*d + 6 + offset + 0,
131                         data->priv->order, entry->tag);
132         exif_set_short (*d + 6 + offset + 2,
133                         data->priv->order, entry->format);
134         exif_set_long  (*d + 6 + offset + 4,
135                         data->priv->order, entry->components);
136
137         /*
138          * Size? If bigger than 4 bytes, the actual data is not in
139          * the entry but somewhere else.
140          */
141         s = exif_format_get_size (entry->format) * entry->components;
142         if (!s)
143                 return;
144         if (s > 4) {
145                 *ds += entry->size;
146                 *d = realloc (*d, sizeof (char) * *ds);
147                 doff = *ds - 6 - entry->size;
148                 exif_set_long (*d + 6 + offset + 8,
149                                data->priv->order, doff);
150         } else
151                 doff = offset + 8;
152         memcpy (*d + 6 + doff, entry->data, entry->size);
153 }
154
155 static void
156 exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d,
157                                unsigned int ds, ExifLong offset, ExifLong size)
158 {
159         if (ds < offset + size) {
160 #ifdef DEBUG
161                 printf ("Bogus thumbnail offset and size: %i < %i + %i.\n",
162                         (int) ds, (int) offset, (int) size);
163 #endif
164                 return;
165         }
166         if (data->data)
167                 free (data->data);
168         data->size = size;
169         data->data = malloc (sizeof (char) * data->size);
170         memcpy (data->data, d + offset, data->size);
171 }
172
173 static void
174 exif_data_load_data_content (ExifData *data, ExifContent *ifd,
175                              const unsigned char *d,
176                              unsigned int ds, unsigned int offset)
177 {
178         ExifLong o, thumbnail_offset = 0, thumbnail_length = 0;
179         ExifShort n;
180         ExifEntry *entry;
181         unsigned int i;
182         ExifTag tag;
183
184         /* Read the number of entries */
185         n = exif_get_short (d + offset, data->priv->order);
186 #ifdef DEBUG
187         printf ("Loading %i entries...\n", n);
188 #endif
189         offset += 2;
190         for (i = 0; i < n; i++) {
191
192                 tag = exif_get_short (d + offset + 12 * i, data->priv->order);
193 #ifdef DEBUG
194                 printf ("Loading entry '%s' (%i of %i)...\n",
195                         exif_tag_get_name (tag), i + 1, n);
196 #endif
197                 switch (tag) {
198                 case EXIF_TAG_EXIF_IFD_POINTER:
199                 case EXIF_TAG_GPS_INFO_IFD_POINTER:
200                 case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
201                 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
202                 case EXIF_TAG_JPEG_INTERCHANGE_FORMAT:
203                         o = exif_get_long (d + offset + 12 * i + 8,
204                                            data->priv->order);
205                         switch (tag) {
206                         case EXIF_TAG_EXIF_IFD_POINTER:
207                                 exif_data_load_data_content (data,
208                                         data->ifd[EXIF_IFD_EXIF], d, ds, o);
209                                 break;
210                         case EXIF_TAG_GPS_INFO_IFD_POINTER:
211                                 exif_data_load_data_content (data,
212                                         data->ifd[EXIF_IFD_GPS], d, ds, o);
213                                 break;
214                         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
215                                 exif_data_load_data_content (data,
216                                         data->ifd[EXIF_IFD_INTEROPERABILITY], d, ds, o);
217                                 break;
218                         case EXIF_TAG_JPEG_INTERCHANGE_FORMAT:
219 #ifdef DEBUG
220                                 printf ("Thumbnail at %i.\n", (int) o);
221 #endif
222                                 thumbnail_offset = o;
223                                 if (thumbnail_offset && thumbnail_length)
224                                         exif_data_load_data_thumbnail (data, d,
225                                                 ds, thumbnail_offset,
226                                                 thumbnail_length);
227                                 break;
228                         case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH:
229 #ifdef DEBUG
230                                 printf ("Thumbnail size: %i.\n", (int) o);
231 #endif
232                                 thumbnail_length = o;
233                                 if (thumbnail_offset && thumbnail_length)
234                                         exif_data_load_data_thumbnail (data, d,
235                                                 ds, thumbnail_offset,
236                                                 thumbnail_length);
237                                 break;
238                         default:
239                                 return;
240                         }
241                         break;
242                 default:
243                         entry = exif_entry_new ();
244                         exif_content_add_entry (ifd, entry);
245                         exif_data_load_data_entry (data, entry, d, ds,
246                                                    offset + 12 * i);
247                         exif_entry_unref (entry);
248                         break;
249                 }
250         }
251 }
252
253 static void
254 exif_data_save_data_content (ExifData *data, ExifContent *ifd,
255                              unsigned char **d, unsigned int *ds,
256                              unsigned int offset)
257 {
258         unsigned int j, n_ptr = 0, n_thumb = 0;
259         ExifIfd i;
260
261         if (!data || !ifd || !d || !ds)
262                 return;
263
264         for (i = 0; i < EXIF_IFD_COUNT; i++)
265                 if (ifd == data->ifd[i])
266                         break;
267         if (i == EXIF_IFD_COUNT)
268                 return;
269
270         /*
271          * Check if we need some extra entries for pointers or the thumbnail.
272          */
273         switch (i) {
274         case EXIF_IFD_0:
275
276                 /*
277                  * The pointer to IFD_EXIF is in IFD_0. The pointer to
278                  * IFD_INTEROPERABILITY is in IFD_EXIF.
279                  */
280                 if (data->ifd[EXIF_IFD_EXIF]->count ||
281                     data->ifd[EXIF_IFD_INTEROPERABILITY]->count)
282                         n_ptr++;
283
284                 /* The pointer to IFD_GPS is in IFD_0. */
285                 if (data->ifd[EXIF_IFD_GPS]->count)
286                         n_ptr++;
287
288                 break;
289         case EXIF_IFD_1:
290                 if (data->size)
291                         n_thumb = 2;
292                 break;
293         case EXIF_IFD_EXIF:
294                 if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count)
295                         n_ptr++;
296         default:
297                 break;
298         }
299
300         /*
301          * Allocate enough memory for all entries
302          * and the number of entries.
303          */
304         *ds += (2 + (ifd->count + n_ptr + n_thumb) * 12 + 4);
305         *d = realloc (*d, sizeof (char) * *ds);
306
307         /* Save the number of entries */
308         exif_set_short (*d + 6 + offset, data->priv->order,
309                         ifd->count + n_ptr + n_thumb);
310         offset += 2;
311
312 #ifdef DEBUG
313         printf ("Saving %i entries (IFD '%s', offset: %i)...\n",
314                 ifd->count, exif_ifd_get_name (i), offset);
315 #endif
316
317         /* Save each entry */
318         for (j = 0; j < ifd->count; j++)
319                 exif_data_save_data_entry (data, ifd->entries[j],
320                                 d, ds, offset + 12 * j);
321         offset += 12 * ifd->count;
322
323         /* Now save special entries. */
324         switch (i) {
325         case EXIF_IFD_0:
326
327                 /*
328                  * The pointer to IFD_EXIF is in IFD_0.
329                  * However, the pointer to IFD_INTEROPERABILITY is in IFD_EXIF,
330                  * therefore, if IFD_INTEROPERABILITY is not empty, we need
331                  * IFD_EXIF even if latter is empty.
332                  */
333                 if (data->ifd[EXIF_IFD_EXIF]->count ||
334                     data->ifd[EXIF_IFD_INTEROPERABILITY]->count) {
335                         exif_set_short (*d + 6 + offset + 0, data->priv->order,
336                                         EXIF_TAG_EXIF_IFD_POINTER);
337                         exif_set_short (*d + 6 + offset + 2, data->priv->order,
338                                         EXIF_FORMAT_LONG);
339                         exif_set_long  (*d + 6 + offset + 4, data->priv->order,
340                                         1);
341                         exif_set_long  (*d + 6 + offset + 8, data->priv->order,
342                                         *ds - 6);
343                         exif_data_save_data_content (data,
344                                 data->ifd[EXIF_IFD_EXIF], d, ds, *ds - 6);
345                         offset += 12;
346                 }
347
348                 /* The pointer to IFD_GPS is in IFD_0, too. */
349                 if (data->ifd[EXIF_IFD_GPS]->count) {
350                         exif_set_short (*d + 6 + offset + 0, data->priv->order,
351                                         EXIF_TAG_GPS_INFO_IFD_POINTER);
352                         exif_set_short (*d + 6 + offset + 2, data->priv->order,
353                                         EXIF_FORMAT_LONG);
354                         exif_set_long  (*d + 6 + offset + 4, data->priv->order,
355                                         1);
356                         exif_set_long  (*d + 6 + offset + 8, data->priv->order,
357                                         *ds - 6);
358                         exif_data_save_data_content (data,
359                                 data->ifd[EXIF_IFD_GPS], d, ds, *ds - 6);
360                         offset += 12;
361                 }
362
363                 break;
364         case EXIF_IFD_EXIF:
365
366                 /*
367                  * The pointer to IFD_INTEROPERABILITY is in IFD_EXIF.
368                  * See note above.
369                  */
370                 if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) {
371                         exif_set_short (*d + 6 + offset + 0, data->priv->order,
372                                         EXIF_TAG_INTEROPERABILITY_IFD_POINTER);
373                         exif_set_short (*d + 6 + offset + 2, data->priv->order,
374                                         EXIF_FORMAT_LONG);
375                         exif_set_long  (*d + 6 + offset + 4, data->priv->order,
376                                         1);
377                         exif_set_long  (*d + 6 + offset + 8, data->priv->order,
378                                         *ds - 6);
379                         exif_data_save_data_content (data,
380                                 data->ifd[EXIF_IFD_INTEROPERABILITY], d, ds,
381                                 *ds - 6);
382                         offset += 12;
383                 }
384
385                 break;
386         case EXIF_IFD_1:
387
388                 /*
389                  * Information about the thumbnail (if any) is saved in
390                  * IFD_1.
391                  */
392                 if (data->size) {
393
394                         /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT */
395                         exif_set_short (*d + 6 + offset + 0, data->priv->order,
396                                         EXIF_TAG_JPEG_INTERCHANGE_FORMAT);
397                         exif_set_short (*d + 6 + offset + 2, data->priv->order,
398                                         EXIF_FORMAT_LONG);
399                         exif_set_long  (*d + 6 + offset + 4, data->priv->order,
400                                         1);
401                         exif_set_long  (*d + 6 + offset + 8, data->priv->order,
402                                         *ds - 6);
403                         *ds += data->size;
404                         *d = realloc (*d, sizeof (char) * *ds);
405                         memcpy (*d + *ds - data->size, data->data, data->size);
406                         offset += 12;
407 #ifdef DEBUG
408                         printf ("Wrote %i bytes of thumbnail data at offset "
409                                 "%i.\n", data->size, *ds - data->size);
410                         printf ("We currently have %i bytes EXIF data.\n", *ds);
411 #endif
412
413                         /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH */
414                         exif_set_short (*d + 6 + offset + 0, data->priv->order,
415                                 EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
416                         exif_set_short (*d + 6 + offset + 2, data->priv->order,
417                                         EXIF_FORMAT_LONG);
418                         exif_set_long  (*d + 6 + offset + 4, data->priv->order,
419                                         1);
420                         exif_set_long  (*d + 6 + offset + 8, data->priv->order, 
421                                         data->size);
422                         offset += 12;
423                 }
424
425                 break;
426         default:
427                 break;
428         }
429
430         /* Correctly terminate the directory */
431         if (i == EXIF_IFD_0 && (data->ifd[EXIF_IFD_1]->count ||
432                                              data->size)) {
433
434                 /*
435                  * We are saving IFD 0. Tell where IFD 1 starts and save
436                  * IFD 1.
437                  */
438                 exif_set_long (*d + 6 + offset, data->priv->order, *ds - 6);
439                 exif_data_save_data_content (data, data->ifd[EXIF_IFD_1], d, ds,
440                                              *ds - 6);
441         } else
442                 exif_set_long (*d + 6 + offset, data->priv->order, 0);
443 }
444
445 void
446 exif_data_load_data (ExifData *data, const unsigned char *d, unsigned int size)
447 {
448         unsigned int l, len = size;
449         ExifLong offset;
450         ExifShort n;
451
452         if (!data)
453                 return;
454         if (!d || !size)
455                 return;
456
457 #ifdef DEBUG
458         printf ("Parsing %i byte(s) EXIF data...\n", size);
459 #endif
460
461         /*
462          * It can be that the data starts with the EXIF header. If it does
463          * not, search the EXIF marker.
464          */
465         if (size < 6) {
466 #ifdef DEBUG
467                 printf ("Size too small.\n");
468 #endif
469                 return;
470         }
471         if (!memcmp (d, ExifHeader, 6)) {
472 #ifdef DEBUG
473                 printf ("Found EXIF header.\n");
474 #endif
475         } else {
476 #ifdef DEBUG
477                 printf ("Data begins with 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x "
478                         "0x%x...\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6]);
479 #endif
480                 while (1) {
481                         while ((d[0] == 0xff) && size) {
482                                 d++;
483                                 size--;
484                         }
485
486                         /* JPEG_MARKER_SOI */
487                         if (d[0] == JPEG_MARKER_SOI) {
488                                 d++;
489                                 size--;
490                                 continue;
491                         }
492
493                         /* JPEG_MARKER_APP0 */
494                         if (d[0] == JPEG_MARKER_APP0) {
495                                 d++;
496                                 size--;
497                                 l = (d[0] << 8) | d[1];
498                                 if (l > size)
499                                         return;
500                                 d += l;
501                                 size -= l;
502                                 continue;
503                         }
504
505                         /* JPEG_MARKER_APP1 */
506                         if (d[0] == JPEG_MARKER_APP1)
507                                 break;
508
509                         /* Unknown marker or data. Give up. */
510 #ifdef DEBUG
511                         printf ("EXIF marker not found.\n");
512 #endif
513                         return;
514                 }
515                 d++;
516                 size--;
517                 if (size < 2) {
518 #ifdef DEBUG
519                         printf ("Size too small.\n");
520 #endif
521                         return;
522                 }
523                 len = (d[0] << 8) | d[1];
524 #ifdef DEBUG
525                 printf ("We have to deal with %i byte(s) of EXIF data.\n", len);
526 #endif
527                 d += 2;
528                 size -= 2;
529         }
530
531         /*
532          * Verify the exif header
533          * (offset 2, length 6).
534          */
535         if (size < 6) {
536 #ifdef DEBUG
537                 printf ("Size too small.\n");
538 #endif
539                 return;
540         }
541         if (memcmp (d, ExifHeader, 6)) {
542 #ifdef DEBUG
543                 printf ("EXIF header not found.\n");
544 #endif
545                 return;
546         }
547
548 #ifdef DEBUG
549         printf ("Found EXIF header.\n");
550 #endif
551
552         /* Byte order (offset 6, length 2) */
553         if (size < 12)
554                 return;
555         if (!memcmp (d + 6, "II", 2))
556                 data->priv->order = EXIF_BYTE_ORDER_INTEL;
557         else if (!memcmp (d + 6, "MM", 2))
558                 data->priv->order = EXIF_BYTE_ORDER_MOTOROLA;
559         else
560                 return;
561
562         /* Fixed value */
563         if (exif_get_short (d + 8, data->priv->order) != 0x002a)
564                 return;
565
566         /* IFD 0 offset */
567         offset = exif_get_long (d + 10, data->priv->order);
568 #ifdef DEBUG
569         printf ("IFD 0 at %i.\n", (int) offset);
570 #endif
571
572         /* Parse the actual exif data (offset 14) */
573         exif_data_load_data_content (data, data->ifd[EXIF_IFD_0], d + 6,
574                                      size - 6, offset);
575
576         /* IFD 1 offset */
577         n = exif_get_short (d + 6 + offset, data->priv->order);
578         offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order);
579         if (offset) {
580 #ifdef DEBUG
581                 printf ("IFD 1 at %i.\n", (int) offset);
582 #endif
583
584                 /* Sanity check. */
585                 if (offset > size - 6) {
586 #ifdef DEBUG
587                         printf ("Bogus offset!\n");
588 #endif
589                         return;
590                 }
591
592                 exif_data_load_data_content (data, data->ifd[EXIF_IFD_1], d + 6,
593                                              size - 6, offset);
594         }
595 }
596
597 void
598 exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds)
599 {
600         if (!data)
601                 return;
602         if (!d || !ds)
603                 return;
604
605         /* Header */
606         *ds = 6;
607         *d = malloc (sizeof (char) * *ds);
608         memcpy (*d, ExifHeader, 6);
609
610         /* Order (offset 6) */
611         *ds += 2;
612         *d = realloc (*d, sizeof (char) * *ds);
613         if (data->priv->order == EXIF_BYTE_ORDER_INTEL) {
614                 memcpy (*d + 6, "II", 2);
615         } else {
616                 memcpy (*d + 6, "MM", 2);
617         }
618
619         /* Fixed value (2 bytes, offset 8) */
620         *ds += 2;
621         *d = realloc (*d, sizeof (char) * *ds);
622         exif_set_short (*d + 8, data->priv->order, 0x002a);
623
624         /*
625          * IFD 0 offset (4 bytes, offset 10).
626          * We will start 8 bytes after the
627          * EXIF header (2 bytes for order, another 2 for the test, and 
628          * 4 bytes for the IFD 0 offset make 8 bytes together).
629          */
630         *ds += 4;
631         *d = realloc (*d, sizeof (char) * *ds);
632         exif_set_long (*d + 10, data->priv->order, 8);
633
634         /* Now save IFD 0. IFD 1 will be saved automatically. */
635 #ifdef DEBUG
636         printf ("Saving IFDs...\n");
637 #endif
638         exif_data_save_data_content (data, data->ifd[EXIF_IFD_0], d, ds,
639                                      *ds - 6);
640
641 #ifdef DEBUG
642         printf ("Saved %i byte(s) EXIF data.\n", *ds);
643 #endif
644 }
645
646 ExifData *
647 exif_data_new_from_file (const char *path)
648 {
649         FILE *f;
650         unsigned int size;
651         unsigned char *data;
652         ExifData *edata;
653         int marker, ll, lh;
654
655         f = fopen (path, "rb");
656         if (!f)
657                 return (NULL);
658
659         while (1) {
660                 while ((marker = fgetc (f)) == 0xff);
661
662                 /* JPEG_MARKER_SOI */
663                 if (marker == JPEG_MARKER_SOI)
664                         continue;
665
666                 /* JPEG_MARKER_APP0 */
667                 if (marker == JPEG_MARKER_APP0) {
668                         lh = fgetc (f);
669                         ll = fgetc (f);
670                         size = (lh << 8) | ll;
671                         if (fseek (f, size - 2, SEEK_CUR) < 0)
672                                 return (NULL);
673                         continue;
674                 }
675
676                 /* JPEG_MARKER_APP1 */
677                 if (marker == JPEG_MARKER_APP1)
678                         break;
679
680                 /* Unknown marker or data. Give up. */
681                 return (NULL);
682         }
683
684         /* EXIF data found. Allocate the necessary memory and read the data. */
685         lh = fgetc (f);
686         ll = fgetc (f);
687         size = (lh << 8) | ll;
688         data = malloc (sizeof (char) * size);
689         if (!data)
690                 return (NULL);
691         if (fread (data, 1, size, f) != size) {
692                 free (data);
693                 return (NULL);
694         }
695
696         edata = exif_data_new_from_data (data, size);
697         free (data);
698
699         fclose (f);
700
701         return (edata);
702 }
703
704 void
705 exif_data_ref (ExifData *data)
706 {
707         if (!data)
708                 return;
709
710         data->priv->ref_count++;
711 }
712
713 void
714 exif_data_unref (ExifData *data)
715 {
716         if (!data)
717                 return;
718
719         data->priv->ref_count--;
720         if (!data->priv->ref_count)
721                 exif_data_free (data);
722 }
723
724 void
725 exif_data_free (ExifData *data)
726 {
727         unsigned int i;
728
729         if (!data)
730                 return;
731
732         for (i = 0; i < EXIF_IFD_COUNT; i++) {
733                 if (data->ifd[i]) {
734                         exif_content_unref (data->ifd[i]);
735                         data->ifd[i] = NULL;
736                 }
737         }
738         if (data->data) {
739                 free (data->data);
740                 data->data = NULL;
741         }
742         if (data->priv) {
743                 free (data->priv);
744                 data->priv = NULL;
745         }
746         free (data);
747 }
748
749 void
750 exif_data_dump (ExifData *data)
751 {
752         unsigned int i;
753
754         if (!data)
755                 return;
756
757         for (i = 0; i < EXIF_IFD_COUNT; i++) {
758                 if (data->ifd[i] && data->ifd[i]->count) {
759                         printf ("Dumping IFD '%s'...\n",
760                                 exif_ifd_get_name (i));
761                         exif_content_dump (data->ifd[i], 0);
762                 }
763         }
764
765         if (data->data) {
766                 printf ("%i byte(s) thumbnail data available.", data->size);
767                 if (data->size >= 4) {
768                         printf ("0x%02x 0x%02x ... 0x%02x 0x%02x\n",
769                                 data->data[0], data->data[1],
770                                 data->data[data->size - 2],
771                                 data->data[data->size - 1]);
772                 }
773         }
774 }
775
776 ExifByteOrder
777 exif_data_get_byte_order (ExifData *data)
778 {
779         if (!data)
780                 return (0);
781
782         return (data->priv->order);
783 }
784
785 void
786 exif_data_foreach_content (ExifData *data, ExifDataForeachContentFunc func,
787                            void *user_data)
788 {
789         unsigned int i;
790
791         if (!data || !func)
792                 return;
793
794         for (i = 0; i < EXIF_IFD_COUNT; i++)
795                 func (data->ifd[i], user_data);
796 }
797
798 typedef struct _ByteOrderChangeData ByteOrderChangeData;
799 struct _ByteOrderChangeData {
800         ExifByteOrder old, new;
801 };
802
803 static void
804 entry_set_byte_order (ExifEntry *e, void *data)
805 {
806         ByteOrderChangeData *d = data;
807         unsigned int i;
808         ExifShort s;
809         ExifLong l;
810         ExifSLong sl;
811         ExifRational r;
812         ExifSRational sr;
813
814         if (!e)
815                 return;
816
817         switch (e->format) {
818         case EXIF_FORMAT_SHORT:
819                 for (i = 0; i < e->components; i++) {
820                         s = exif_get_short (e->data +
821                                 (i * exif_format_get_size (e->format)),
822                                 d->old);
823                         exif_set_short (e->data + 
824                                 (i * exif_format_get_size (e->format)),
825                                 d->new, s);
826                 }
827                 break;
828         case EXIF_FORMAT_LONG:
829                 for (i = 0; i < e->components; i++) {
830                         l = exif_get_long (e->data +
831                                 (i * exif_format_get_size (e->format)),
832                                 d->old);
833                         exif_set_long (e->data +
834                                 (i * exif_format_get_size (e->format)),
835                                 d->new, l);
836                 }
837                 break;
838         case EXIF_FORMAT_RATIONAL:
839                 for (i = 0; i < e->components; i++) {
840                         r = exif_get_rational (e->data +
841                                 (i * exif_format_get_size (e->format)),
842                                 d->old);
843                         exif_set_rational (e->data +
844                                 (i * exif_format_get_size (e->format)),
845                                 d->new, r);
846                 }
847                 break;
848         case EXIF_FORMAT_SLONG:
849                 for (i = 0; i < e->components; i++) {
850                         sl = exif_get_slong (e->data +
851                                 (i * exif_format_get_size (e->format)),
852                                 d->old);
853                         exif_set_slong (e->data +
854                                 (i * exif_format_get_size (e->format)),
855                                 d->new, sl);
856                 }
857                 break;
858         case EXIF_FORMAT_SRATIONAL:
859                 for (i = 0; i < e->components; i++) {
860                         sr = exif_get_srational (e->data +
861                                 (i * exif_format_get_size (e->format)),
862                                 d->old);
863                         exif_set_srational (e->data +
864                                 (i * exif_format_get_size (e->format)),
865                                 d->new, sr);
866                 }
867                 break;
868         case EXIF_FORMAT_UNDEFINED:
869         case EXIF_FORMAT_BYTE:
870         case EXIF_FORMAT_ASCII:
871         default:
872                 /* Nothing here. */
873                 break;
874         }
875 }
876
877 static void
878 content_set_byte_order (ExifContent *content, void *data)
879 {
880         exif_content_foreach_entry (content, entry_set_byte_order, data);
881 }
882
883 void
884 exif_data_set_byte_order (ExifData *data, ExifByteOrder order)
885 {
886         ByteOrderChangeData d;
887
888         if (!data || (order == data->priv->order))
889                 return;
890
891         d.old = data->priv->order;
892         d.new = order;
893         exif_data_foreach_content (data, content_set_byte_order, &d);
894         data->priv->order = order;
895 }