Improved Doxygen documentation.
[platform/upstream/libexif.git] / libexif / exif-loader.c
1 /* exif-loader.c
2  *
3  * Copyright (c) 2002 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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22
23 #include <libexif/exif-loader.h>
24 #include <libexif/exif-utils.h>
25 #include <libexif/i18n.h>
26
27 #include <sys/types.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31
32 #undef JPEG_MARKER_DHT
33 #define JPEG_MARKER_DHT  0xc4
34 #undef JPEG_MARKER_SOI
35 #define JPEG_MARKER_SOI  0xd8
36 #undef JPEG_MARKER_DQT
37 #define JPEG_MARKER_DQT  0xdb
38 #undef JPEG_MARKER_APP0
39 #define JPEG_MARKER_APP0 0xe0
40 #undef JPEG_MARKER_APP1
41 #define JPEG_MARKER_APP1 0xe1
42 #undef JPEG_MARKER_APP2
43 #define JPEG_MARKER_APP2 0xe2
44 #undef JPEG_MARKER_APP13
45 #define JPEG_MARKER_APP13 0xed
46 #undef JPEG_MARKER_COM
47 #define JPEG_MARKER_COM 0xfe
48
49 typedef enum {
50         EL_READ = 0,
51         EL_READ_SIZE_BYTE_24,
52         EL_READ_SIZE_BYTE_16,
53         EL_READ_SIZE_BYTE_08,
54         EL_READ_SIZE_BYTE_00,
55         EL_SKIP_BYTES,
56         EL_EXIF_FOUND,
57 } ExifLoaderState;
58
59 typedef enum {
60         EL_DATA_FORMAT_UNKNOWN,
61         EL_DATA_FORMAT_EXIF,
62         EL_DATA_FORMAT_JPEG,
63         EL_DATA_FORMAT_FUJI_RAW
64 } ExifLoaderDataFormat;
65
66 /*! \internal */
67 struct _ExifLoader {
68         ExifLoaderState state;
69         ExifLoaderDataFormat data_format;
70
71         /*! Small buffer used for detection of format */
72         unsigned char b[12];
73         unsigned char b_len;
74
75         unsigned int size;
76         unsigned char *buf;
77         unsigned int bytes_read;
78
79         unsigned int ref_count;
80
81         ExifLog *log;
82         ExifMem *mem;
83 };
84
85 /*! Magic number for EXIF header */
86 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
87
88 static void *
89 exif_loader_alloc (ExifLoader *l, unsigned int i)
90 {
91         void *d;
92
93         if (!l || !i) 
94                 return NULL;
95
96         d = exif_mem_alloc (l->mem, i);
97         if (d) 
98                 return d;
99
100         EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
101         return NULL;
102 }
103
104 void
105 exif_loader_write_file (ExifLoader *l, const char *path)
106 {
107         FILE *f;
108         int size;
109         unsigned char data[1024];
110
111         if (!l) 
112                 return;
113
114         f = fopen (path, "rb");
115         if (!f) {
116                 exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
117                           _("The file '%s' could not be opened."), path);
118                 return;
119         }
120         while (1) {
121                 size = fread (data, 1, sizeof (data), f);
122                 if (size <= 0) 
123                         break;
124                 if (!exif_loader_write (l, data, size)) 
125                         break;
126         }
127         fclose (f);
128 }
129
130 static unsigned int
131 exif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len)
132 {
133         if (!eld || (len && !buf) || (eld->bytes_read >= eld->size)) 
134                 return 0;
135
136         /* If needed, allocate the buffer. */
137         if (!eld->buf) 
138                 eld->buf = exif_loader_alloc (eld, eld->size);
139         if (!eld->buf) 
140                 return 0;
141
142         /* Copy memory */
143         len = MIN (len, eld->size - eld->bytes_read);
144         memcpy (eld->buf + eld->bytes_read, buf, len);
145         eld->bytes_read += len;
146
147         return (eld->bytes_read >= eld->size) ? 0 : 1;
148 }
149
150 unsigned char
151 exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
152 {
153         unsigned int i;
154
155         if (!eld || (len && !buf)) 
156                 return 0;
157
158         switch (eld->state) {
159         case EL_EXIF_FOUND:
160                 return exif_loader_copy (eld, buf, len);
161         case EL_SKIP_BYTES:
162                 if (eld->size > len) { 
163                         eld->size -= len; 
164                         return 1; 
165                 }
166                 len -= eld->size;
167                 buf += eld->size;
168                 eld->size = 0;
169                 eld->b_len = 0;
170                 switch (eld->data_format) {
171                 case EL_DATA_FORMAT_FUJI_RAW:
172                         eld->state = EL_READ_SIZE_BYTE_24;
173                         break;
174                 default:
175                         eld->state = EL_READ;
176                         break;
177                 }
178                 break;
179         default:
180                 break;
181         }
182
183         if (!len)
184                 return 1;
185         exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
186                   "Scanning %i byte(s) of data...", len);
187
188         /*
189          * First fill the small buffer. Only continue if the buffer
190          * is filled. Note that EXIF data contains at least 12 bytes.
191          */
192         i = MIN (len, sizeof (eld->b) - eld->b_len);
193         if (i) {
194                 memcpy (&eld->b[eld->b_len], buf, i);
195                 eld->b_len += i;
196                 if (eld->b_len < sizeof (eld->b)) 
197                         return 1;
198                 buf += i;
199                 len -= i;
200         }
201
202         switch (eld->data_format) {
203         case EL_DATA_FORMAT_UNKNOWN:
204
205                 /* Check the small buffer against known formats. */
206                 if (!memcmp (eld->b, "FUJIFILM", 8)) {
207
208                         /* Skip to byte 84. There is another offset there. */
209                         eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
210                         eld->size = 84;
211                         eld->state = EL_SKIP_BYTES;
212                         eld->size = 84;
213
214                 } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {
215
216                         /* Read the size (2 bytes). */
217                         eld->data_format = EL_DATA_FORMAT_EXIF;
218                         eld->state = EL_READ_SIZE_BYTE_08;
219                 }
220         default:
221                 break;
222         }
223
224         for (i = 0; i < sizeof (eld->b); i++)
225                 switch (eld->state) {
226                 case EL_EXIF_FOUND:
227                         if (!exif_loader_copy (eld, eld->b + i,
228                                         sizeof (eld->b) - i)) 
229                                 return 0;
230                         return exif_loader_copy (eld, buf, len);
231                 case EL_SKIP_BYTES:
232                         eld->size--;
233                         if (!eld->size) 
234                                 eld->state = EL_READ;
235                         break;
236
237                 case EL_READ_SIZE_BYTE_24:
238                         eld->size |= eld->b[i] << 24;
239                         eld->state = EL_READ_SIZE_BYTE_16;
240                         break;
241                 case EL_READ_SIZE_BYTE_16:
242                         eld->size |= eld->b[i] << 16;
243                         eld->state = EL_READ_SIZE_BYTE_08;
244                         break;
245                 case EL_READ_SIZE_BYTE_08:
246                         eld->size |= eld->b[i] << 8;
247                         eld->state = EL_READ_SIZE_BYTE_00;
248                         break;
249                 case EL_READ_SIZE_BYTE_00:
250                         eld->size |= eld->b[i] << 0;
251                         switch (eld->data_format) {
252                         case EL_DATA_FORMAT_JPEG:
253                                 eld->state = EL_SKIP_BYTES;
254                                 eld->size -= 2;
255                                 break;
256                         case EL_DATA_FORMAT_FUJI_RAW:
257                                 eld->data_format = EL_DATA_FORMAT_EXIF;
258                                 eld->state = EL_SKIP_BYTES;
259                                 eld->size -= 86;
260                                 break;
261                         case EL_DATA_FORMAT_EXIF:
262                                 eld->state = EL_EXIF_FOUND;
263                                 break;
264                         default:
265                                 break;
266                         }
267                         break;
268
269                 default:
270                         switch (eld->b[i]) {
271                         case JPEG_MARKER_APP1:
272                           if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) {
273                                         eld->data_format = EL_DATA_FORMAT_EXIF;
274                                 } else {
275                                         eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/
276                                 }
277                                 eld->size = 0;
278                                 eld->state = EL_READ_SIZE_BYTE_08;
279                                 break;
280                         case JPEG_MARKER_DHT:
281                         case JPEG_MARKER_DQT:
282                         case JPEG_MARKER_APP0:
283                         case JPEG_MARKER_APP2:
284                         case JPEG_MARKER_APP13:
285                         case JPEG_MARKER_COM:
286                                 eld->data_format = EL_DATA_FORMAT_JPEG;
287                                 eld->size = 0;
288                                 eld->state = EL_READ_SIZE_BYTE_08;
289                                 break;
290                         case 0xff:
291                         case JPEG_MARKER_SOI:
292                                 break;
293                         default:
294                                 exif_log (eld->log,
295                                         EXIF_LOG_CODE_CORRUPT_DATA,
296                                         "ExifLoader", _("The data supplied "
297                                                 "does not seem to contain "
298                                                 "EXIF data."));
299                                 exif_loader_reset (eld);
300                                 return 0;
301                         }
302                 }
303
304         /*
305          * If we reach this point, the buffer has not been big enough
306          * to read all data we need. Fill it with new data.
307          */
308         eld->b_len = 0;
309         return exif_loader_write (eld, buf, len);
310 }
311
312 ExifLoader *
313 exif_loader_new (void)
314 {
315         ExifMem *mem = exif_mem_new_default ();
316         ExifLoader *l = exif_loader_new_mem (mem);
317
318         exif_mem_unref (mem);
319
320         return l;
321 }
322
323 ExifLoader *
324 exif_loader_new_mem (ExifMem *mem)
325 {
326         ExifLoader *loader;
327
328         if (!mem) 
329                 return NULL;
330         
331         loader = exif_mem_alloc (mem, sizeof (ExifLoader));
332         if (!loader) 
333                 return NULL;
334         loader->ref_count = 1;
335
336         loader->mem = mem;
337         exif_mem_ref (mem);
338
339         return loader;
340 }
341
342 void
343 exif_loader_ref (ExifLoader *loader)
344 {
345         if (loader) 
346                 loader->ref_count++;
347 }
348
349 static void
350 exif_loader_free (ExifLoader *loader)
351 {
352         ExifMem *mem;
353
354         if (!loader) 
355                 return;
356
357         mem = loader->mem;
358         exif_loader_reset (loader);
359         exif_log_unref (loader->log);
360         exif_mem_free (mem, loader);
361         exif_mem_unref (mem);
362 }
363         
364 void
365 exif_loader_unref (ExifLoader *loader)
366 {
367         if (!loader) 
368                 return;
369         if (!--loader->ref_count)
370                 exif_loader_free (loader);
371 }
372
373 void
374 exif_loader_reset (ExifLoader *loader)
375 {
376         if (!loader) 
377                 return;
378         exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
379         loader->size = 0;
380         loader->bytes_read = 0;
381         loader->state = 0;
382         loader->b_len = 0;
383         loader->data_format = EL_DATA_FORMAT_UNKNOWN;
384 }
385
386 ExifData *
387 exif_loader_get_data (ExifLoader *loader)
388 {
389         ExifData *ed;
390
391         if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) ||
392             !loader->bytes_read)
393                 return NULL;
394
395         ed = exif_data_new_mem (loader->mem);
396         exif_data_log (ed, loader->log);
397         exif_data_load_data (ed, loader->buf, loader->bytes_read);
398
399         return ed;
400 }
401
402 void
403 exif_loader_log (ExifLoader *loader, ExifLog *log)
404 {
405         if (!loader) 
406                 return;
407         exif_log_unref (loader->log);
408         loader->log = log;
409         exif_log_ref (log);
410 }