1171485a3fd04de350006d3e162b550624ae0a4f
[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., 51 Franklin Street, Fifth Floor,
18  * Boston, MA  02110-1301  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
74         /*! Number of bytes in the small buffer \c b */
75         unsigned char b_len;
76
77         unsigned int size;
78         unsigned char *buf;
79         unsigned int bytes_read;
80
81         unsigned int ref_count;
82
83         ExifLog *log;
84         ExifMem *mem;
85 };
86
87 /*! Magic number for EXIF header */
88 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
89
90 static void *
91 exif_loader_alloc (ExifLoader *l, unsigned int i)
92 {
93         void *d;
94
95         if (!l || !i) 
96                 return NULL;
97
98         d = exif_mem_alloc (l->mem, i);
99         if (d) 
100                 return d;
101
102         EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
103         return NULL;
104 }
105
106 void
107 exif_loader_write_file (ExifLoader *l, const char *path)
108 {
109         FILE *f;
110         int size;
111         unsigned char data[1024];
112
113         if (!l || !path)
114                 return;
115
116         f = fopen (path, "rb");
117         if (!f) {
118                 exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
119                           _("The file '%s' could not be opened."), path);
120                 return;
121         }
122         while (1) {
123                 size = fread (data, 1, sizeof (data), f);
124                 if (size <= 0) 
125                         break;
126                 if (!exif_loader_write (l, data, size)) 
127                         break;
128         }
129         fclose (f);
130 }
131
132 static unsigned int
133 exif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len)
134 {
135         if (!eld || (len && !buf) || (eld->bytes_read >= eld->size)) 
136                 return 0;
137
138         /* If needed, allocate the buffer. */
139         if (!eld->buf) 
140                 eld->buf = exif_loader_alloc (eld, eld->size);
141         if (!eld->buf) 
142                 return 0;
143
144         /* Copy memory */
145         len = MIN (len, eld->size - eld->bytes_read);
146         memcpy (eld->buf + eld->bytes_read, buf, len);
147         eld->bytes_read += len;
148
149         return (eld->bytes_read >= eld->size) ? 0 : 1;
150 }
151
152 unsigned char
153 exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
154 {
155         unsigned int i;
156
157         if (!eld || (len && !buf)) 
158                 return 0;
159
160         switch (eld->state) {
161         case EL_EXIF_FOUND:
162                 return exif_loader_copy (eld, buf, len);
163         case EL_SKIP_BYTES:
164                 if (eld->size > len) { 
165                         eld->size -= len; 
166                         return 1; 
167                 }
168                 len -= eld->size;
169                 buf += eld->size;
170                 eld->size = 0;
171                 eld->b_len = 0;
172                 switch (eld->data_format) {
173                 case EL_DATA_FORMAT_FUJI_RAW:
174                         eld->state = EL_READ_SIZE_BYTE_24;
175                         break;
176                 default:
177                         eld->state = EL_READ;
178                         break;
179                 }
180                 break;
181
182         case EL_READ:
183         default:
184                 break;
185         }
186
187         if (!len)
188                 return 1;
189         exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
190                   "Scanning %i byte(s) of data...", len);
191
192         /*
193          * First fill the small buffer. Only continue if the buffer
194          * is filled. Note that EXIF data contains at least 12 bytes.
195          */
196         i = MIN (len, sizeof (eld->b) - eld->b_len);
197         if (i) {
198                 memcpy (&eld->b[eld->b_len], buf, i);
199                 eld->b_len += i;
200                 if (eld->b_len < sizeof (eld->b)) 
201                         return 1;
202                 buf += i;
203                 len -= i;
204         }
205
206         switch (eld->data_format) {
207         case EL_DATA_FORMAT_UNKNOWN:
208
209                 /* Check the small buffer against known formats. */
210                 if (!memcmp (eld->b, "FUJIFILM", 8)) {
211
212                         /* Skip to byte 84. There is another offset there. */
213                         eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
214                         eld->size = 84;
215                         eld->state = EL_SKIP_BYTES;
216                         eld->size = 84;
217
218                 } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {
219
220                         /* Read the size (2 bytes). */
221                         eld->data_format = EL_DATA_FORMAT_EXIF;
222                         eld->state = EL_READ_SIZE_BYTE_08;
223                 }
224         default:
225                 break;
226         }
227
228         for (i = 0; i < sizeof (eld->b); i++)
229                 switch (eld->state) {
230                 case EL_EXIF_FOUND:
231                         if (!exif_loader_copy (eld, eld->b + i,
232                                         sizeof (eld->b) - i)) 
233                                 return 0;
234                         return exif_loader_copy (eld, buf, len);
235                 case EL_SKIP_BYTES:
236                         eld->size--;
237                         if (!eld->size) 
238                                 eld->state = EL_READ;
239                         break;
240
241                 case EL_READ_SIZE_BYTE_24:
242                         eld->size |= eld->b[i] << 24;
243                         eld->state = EL_READ_SIZE_BYTE_16;
244                         break;
245                 case EL_READ_SIZE_BYTE_16:
246                         eld->size |= eld->b[i] << 16;
247                         eld->state = EL_READ_SIZE_BYTE_08;
248                         break;
249                 case EL_READ_SIZE_BYTE_08:
250                         eld->size |= eld->b[i] << 8;
251                         eld->state = EL_READ_SIZE_BYTE_00;
252                         break;
253                 case EL_READ_SIZE_BYTE_00:
254                         eld->size |= eld->b[i] << 0;
255                         switch (eld->data_format) {
256                         case EL_DATA_FORMAT_JPEG:
257                                 eld->state = EL_SKIP_BYTES;
258                                 eld->size -= 2;
259                                 break;
260                         case EL_DATA_FORMAT_FUJI_RAW:
261                                 eld->data_format = EL_DATA_FORMAT_EXIF;
262                                 eld->state = EL_SKIP_BYTES;
263                                 eld->size -= 86;
264                                 break;
265                         case EL_DATA_FORMAT_EXIF:
266                                 eld->state = EL_EXIF_FOUND;
267                                 break;
268                         default:
269                                 break;
270                         }
271                         break;
272
273                 default:
274                         switch (eld->b[i]) {
275                         case JPEG_MARKER_APP1:
276                           if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) {
277                                         eld->data_format = EL_DATA_FORMAT_EXIF;
278                                 } else {
279                                         eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/
280                                 }
281                                 eld->size = 0;
282                                 eld->state = EL_READ_SIZE_BYTE_08;
283                                 break;
284                         case JPEG_MARKER_DHT:
285                         case JPEG_MARKER_DQT:
286                         case JPEG_MARKER_APP0:
287                         case JPEG_MARKER_APP2:
288                         case JPEG_MARKER_APP13:
289                         case JPEG_MARKER_COM:
290                                 eld->data_format = EL_DATA_FORMAT_JPEG;
291                                 eld->size = 0;
292                                 eld->state = EL_READ_SIZE_BYTE_08;
293                                 break;
294                         case 0xff:
295                         case JPEG_MARKER_SOI:
296                                 break;
297                         default:
298                                 exif_log (eld->log,
299                                         EXIF_LOG_CODE_CORRUPT_DATA,
300                                         "ExifLoader", _("The data supplied "
301                                                 "does not seem to contain "
302                                                 "EXIF data."));
303                                 exif_loader_reset (eld);
304                                 return 0;
305                         }
306                 }
307
308         /*
309          * If we reach this point, the buffer has not been big enough
310          * to read all data we need. Fill it with new data.
311          */
312         eld->b_len = 0;
313         return exif_loader_write (eld, buf, len);
314 }
315
316 ExifLoader *
317 exif_loader_new (void)
318 {
319         ExifMem *mem = exif_mem_new_default ();
320         ExifLoader *l = exif_loader_new_mem (mem);
321
322         exif_mem_unref (mem);
323
324         return l;
325 }
326
327 ExifLoader *
328 exif_loader_new_mem (ExifMem *mem)
329 {
330         ExifLoader *loader;
331
332         if (!mem) 
333                 return NULL;
334         
335         loader = exif_mem_alloc (mem, sizeof (ExifLoader));
336         if (!loader) 
337                 return NULL;
338         loader->ref_count = 1;
339
340         loader->mem = mem;
341         exif_mem_ref (mem);
342
343         return loader;
344 }
345
346 void
347 exif_loader_ref (ExifLoader *loader)
348 {
349         if (loader) 
350                 loader->ref_count++;
351 }
352
353 static void
354 exif_loader_free (ExifLoader *loader)
355 {
356         ExifMem *mem;
357
358         if (!loader) 
359                 return;
360
361         mem = loader->mem;
362         exif_loader_reset (loader);
363         exif_log_unref (loader->log);
364         exif_mem_free (mem, loader);
365         exif_mem_unref (mem);
366 }
367         
368 void
369 exif_loader_unref (ExifLoader *loader)
370 {
371         if (!loader) 
372                 return;
373         if (!--loader->ref_count)
374                 exif_loader_free (loader);
375 }
376
377 void
378 exif_loader_reset (ExifLoader *loader)
379 {
380         if (!loader) 
381                 return;
382         exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
383         loader->size = 0;
384         loader->bytes_read = 0;
385         loader->state = 0;
386         loader->b_len = 0;
387         loader->data_format = EL_DATA_FORMAT_UNKNOWN;
388 }
389
390 ExifData *
391 exif_loader_get_data (ExifLoader *loader)
392 {
393         ExifData *ed;
394
395         if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) ||
396             !loader->bytes_read)
397                 return NULL;
398
399         ed = exif_data_new_mem (loader->mem);
400         exif_data_log (ed, loader->log);
401         exif_data_load_data (ed, loader->buf, loader->bytes_read);
402
403         return ed;
404 }
405
406 void
407 exif_loader_get_buf (ExifLoader *loader, const unsigned char **buf,
408                                                   unsigned int *buf_size)
409 {
410         const unsigned char* b = NULL;
411         unsigned int s = 0;
412
413         if (loader) {
414                 if (loader->data_format == EL_DATA_FORMAT_UNKNOWN) {
415                         exif_log (loader->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
416                                           "Loader format unknown");
417                 } else {
418                         b = loader->buf;
419                         s = loader->bytes_read;
420                 }
421         }
422
423         if (buf)
424                 *buf = b;
425         if (buf_size)
426                 *buf_size = s;
427 }
428
429 void
430 exif_loader_log (ExifLoader *loader, ExifLog *log)
431 {
432         if (!loader) 
433                 return;
434         exif_log_unref (loader->log);
435         loader->log = log;
436         exif_log_ref (log);
437 }