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