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