3 * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
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.
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.
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.
23 #include <libexif/exif-loader.h>
24 #include <libexif/exif-utils.h>
25 #include <libexif/i18n.h>
27 #include <sys/types.h>
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
60 EL_DATA_FORMAT_UNKNOWN,
63 EL_DATA_FORMAT_FUJI_RAW
64 } ExifLoaderDataFormat;
68 ExifLoaderState state;
69 ExifLoaderDataFormat data_format;
71 /*! Small buffer used for detection of format */
77 unsigned int bytes_read;
79 unsigned int ref_count;
85 /*! Magic number for EXIF header */
86 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
89 exif_loader_alloc (ExifLoader *l, unsigned int i)
96 d = exif_mem_alloc (l->mem, i);
100 EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
105 exif_loader_write_file (ExifLoader *l, const char *path)
109 unsigned char data[1024];
114 f = fopen (path, "rb");
116 exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
117 _("The file '%s' could not be opened."), path);
121 size = fread (data, 1, sizeof (data), f);
124 if (!exif_loader_write (l, data, size))
131 exif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len)
133 if (!eld || (len && !buf) || (eld->bytes_read >= eld->size))
136 /* If needed, allocate the buffer. */
138 eld->buf = exif_loader_alloc (eld, eld->size);
143 len = MIN (len, eld->size - eld->bytes_read);
144 memcpy (eld->buf + eld->bytes_read, buf, len);
145 eld->bytes_read += len;
147 return (eld->bytes_read >= eld->size) ? 0 : 1;
151 exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
155 if (!eld || (len && !buf))
158 switch (eld->state) {
160 return exif_loader_copy (eld, buf, len);
162 if (eld->size > len) {
170 switch (eld->data_format) {
171 case EL_DATA_FORMAT_FUJI_RAW:
172 eld->state = EL_READ_SIZE_BYTE_24;
175 eld->state = EL_READ;
185 exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
186 "Scanning %i byte(s) of data...", len);
189 * First fill the small buffer. Only continue if the buffer
190 * is filled. Note that EXIF data contains at least 12 bytes.
192 i = MIN (len, sizeof (eld->b) - eld->b_len);
194 memcpy (&eld->b[eld->b_len], buf, i);
196 if (eld->b_len < sizeof (eld->b))
202 switch (eld->data_format) {
203 case EL_DATA_FORMAT_UNKNOWN:
205 /* Check the small buffer against known formats. */
206 if (!memcmp (eld->b, "FUJIFILM", 8)) {
208 /* Skip to byte 84. There is another offset there. */
209 eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
211 eld->state = EL_SKIP_BYTES;
214 } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {
216 /* Read the size (2 bytes). */
217 eld->data_format = EL_DATA_FORMAT_EXIF;
218 eld->state = EL_READ_SIZE_BYTE_08;
224 for (i = 0; i < sizeof (eld->b); i++)
225 switch (eld->state) {
227 if (!exif_loader_copy (eld, eld->b + i,
228 sizeof (eld->b) - i))
230 return exif_loader_copy (eld, buf, len);
234 eld->state = EL_READ;
237 case EL_READ_SIZE_BYTE_24:
238 eld->size |= eld->b[i] << 24;
239 eld->state = EL_READ_SIZE_BYTE_16;
241 case EL_READ_SIZE_BYTE_16:
242 eld->size |= eld->b[i] << 16;
243 eld->state = EL_READ_SIZE_BYTE_08;
245 case EL_READ_SIZE_BYTE_08:
246 eld->size |= eld->b[i] << 8;
247 eld->state = EL_READ_SIZE_BYTE_00;
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;
256 case EL_DATA_FORMAT_FUJI_RAW:
257 eld->data_format = EL_DATA_FORMAT_EXIF;
258 eld->state = EL_SKIP_BYTES;
261 case EL_DATA_FORMAT_EXIF:
262 eld->state = EL_EXIF_FOUND;
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;
275 eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/
278 eld->state = EL_READ_SIZE_BYTE_08;
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;
288 eld->state = EL_READ_SIZE_BYTE_08;
291 case JPEG_MARKER_SOI:
295 EXIF_LOG_CODE_CORRUPT_DATA,
296 "ExifLoader", _("The data supplied "
297 "does not seem to contain "
299 exif_loader_reset (eld);
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.
309 return exif_loader_write (eld, buf, len);
313 exif_loader_new (void)
315 ExifMem *mem = exif_mem_new_default ();
316 ExifLoader *l = exif_loader_new_mem (mem);
318 exif_mem_unref (mem);
324 exif_loader_new_mem (ExifMem *mem)
331 loader = exif_mem_alloc (mem, sizeof (ExifLoader));
334 loader->ref_count = 1;
343 exif_loader_ref (ExifLoader *loader)
350 exif_loader_free (ExifLoader *loader)
358 exif_loader_reset (loader);
359 exif_log_unref (loader->log);
360 exif_mem_free (mem, loader);
361 exif_mem_unref (mem);
365 exif_loader_unref (ExifLoader *loader)
369 if (!--loader->ref_count)
370 exif_loader_free (loader);
374 exif_loader_reset (ExifLoader *loader)
378 exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
380 loader->bytes_read = 0;
383 loader->data_format = EL_DATA_FORMAT_UNKNOWN;
387 exif_loader_get_data (ExifLoader *loader)
391 if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) ||
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);
403 exif_loader_log (ExifLoader *loader, ExifLog *log)
407 exif_log_unref (loader->log);