1548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* exif-loader.c
2548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
3548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
4548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
5548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is free software; you can redistribute it and/or
6548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * modify it under the terms of the GNU Lesser General Public
7548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License as published by the Free Software Foundation; either
8548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * version 2 of the License, or (at your option) any later version.
9548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
10548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is distributed in the hope that it will be useful,
11548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * but WITHOUT ANY WARRANTY; without even the implied warranty of
12548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Lesser General Public License for more details.
14548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
15548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * You should have received a copy of the GNU Lesser General Public
16548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License along with this library; if not, write to the
17548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Boston, MA  02110-1301  USA.
19548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */
20548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
21548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <config.h>
22548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
23548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-loader.h>
24548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-utils.h>
25548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/i18n.h>
26548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
27548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <sys/types.h>
28548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdlib.h>
29548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <string.h>
30548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdio.h>
31548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
32548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_DHT
33548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_DHT  0xc4
34548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_SOI
35548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_SOI  0xd8
36548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_DQT
37548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_DQT  0xdb
38548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP0
39548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP0 0xe0
40548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP1
41548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP1 0xe1
42548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP2
43548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP2 0xe2
44548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP13
45548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP13 0xed
46548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_COM
47548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_COM 0xfe
48548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
49548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissentypedef enum {
50548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_READ = 0,
51548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_READ_SIZE_BYTE_24,
52548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_READ_SIZE_BYTE_16,
53548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_READ_SIZE_BYTE_08,
54548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_READ_SIZE_BYTE_00,
55548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_SKIP_BYTES,
56548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_EXIF_FOUND,
57548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} ExifLoaderState;
58548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
59548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissentypedef enum {
60548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_DATA_FORMAT_UNKNOWN,
61548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_DATA_FORMAT_EXIF,
62548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_DATA_FORMAT_JPEG,
63548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EL_DATA_FORMAT_FUJI_RAW
64548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} ExifLoaderDataFormat;
65548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
66548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*! \internal */
67548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstruct _ExifLoader {
68548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifLoaderState state;
69548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifLoaderDataFormat data_format;
70548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
71548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/*! Small buffer used for detection of format */
72548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned char b[12];
73548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
74548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/*! Number of bytes in the small buffer \c b */
75548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned char b_len;
76548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
77548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int size;
78548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned char *buf;
79548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int bytes_read;
80548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
81548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int ref_count;
82548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
83548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifLog *log;
84548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMem *mem;
85548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen};
86548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
87548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*! Magic number for EXIF header */
88548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
89548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
90548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void *
91548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_alloc (ExifLoader *l, unsigned int i)
92548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
93548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	void *d;
94548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
95548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!l || !i)
96548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return NULL;
97548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
98548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d = exif_mem_alloc (l->mem, i);
99548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (d)
100548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return d;
101548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
102548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
103548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return NULL;
104548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
105548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
106548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid
107548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_write_file (ExifLoader *l, const char *path)
108548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
109548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	FILE *f;
110548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	int size;
111548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned char data[1024];
112548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
113548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!l)
114548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
115548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
116548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	f = fopen (path, "rb");
117548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!f) {
118548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
119548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			  _("The file '%s' could not be opened."), path);
120548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
121548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
122548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	while (1) {
123548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		size = fread (data, 1, sizeof (data), f);
124548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (size <= 0)
125548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
126548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!exif_loader_write (l, data, size))
127548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
128548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
129548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	fclose (f);
130548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
131548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
132548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic unsigned int
133548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len)
134548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
135548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!eld || (len && !buf) || (eld->bytes_read >= eld->size))
136548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return 0;
137548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
138548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* If needed, allocate the buffer. */
139548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!eld->buf)
140548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		eld->buf = exif_loader_alloc (eld, eld->size);
141548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!eld->buf)
142548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return 0;
143548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
144548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Copy memory */
145548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	len = MIN (len, eld->size - eld->bytes_read);
146548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	memcpy (eld->buf + eld->bytes_read, buf, len);
147548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	eld->bytes_read += len;
148548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
149548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return (eld->bytes_read >= eld->size) ? 0 : 1;
150548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
151548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
152548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenunsigned char
153548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
154548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
155548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int i;
156548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
157548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!eld || (len && !buf))
158548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return 0;
159548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
160548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	switch (eld->state) {
161548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case EL_EXIF_FOUND:
162548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return exif_loader_copy (eld, buf, len);
163548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case EL_SKIP_BYTES:
164548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (eld->size > len) {
165548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size -= len;
166548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return 1;
167548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
168548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		len -= eld->size;
169548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		buf += eld->size;
170548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		eld->size = 0;
171548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		eld->b_len = 0;
172548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		switch (eld->data_format) {
173548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_DATA_FORMAT_FUJI_RAW:
174548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_READ_SIZE_BYTE_24;
175548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
176548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		default:
177548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_READ;
178548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
179548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
180548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
181548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
182548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case EL_READ:
183548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	default:
184548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
185548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
186548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
187548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!len)
188548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return 1;
189548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
190548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		  "Scanning %i byte(s) of data...", len);
191548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
192548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/*
193548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * First fill the small buffer. Only continue if the buffer
194548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * is filled. Note that EXIF data contains at least 12 bytes.
195548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 */
196548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	i = MIN (len, sizeof (eld->b) - eld->b_len);
197548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (i) {
198548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		memcpy (&eld->b[eld->b_len], buf, i);
199548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		eld->b_len += i;
200548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (eld->b_len < sizeof (eld->b))
201548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return 1;
202548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		buf += i;
203548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		len -= i;
204548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
205548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
206548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	switch (eld->data_format) {
207548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case EL_DATA_FORMAT_UNKNOWN:
208548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
209548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Check the small buffer against known formats. */
210548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!memcmp (eld->b, "FUJIFILM", 8)) {
211548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
212548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			/* Skip to byte 84. There is another offset there. */
213548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
214548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size = 84;
215548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_SKIP_BYTES;
216548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size = 84;
217548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
218548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		} else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {
219548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
220548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			/* Read the size (2 bytes). */
221548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->data_format = EL_DATA_FORMAT_EXIF;
222548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_READ_SIZE_BYTE_08;
223548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
224548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	default:
225548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
226548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
227548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
228548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	for (i = 0; i < sizeof (eld->b); i++)
229548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		switch (eld->state) {
230548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_EXIF_FOUND:
231548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (!exif_loader_copy (eld, eld->b + i,
232548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					sizeof (eld->b) - i))
233548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				return 0;
234548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return exif_loader_copy (eld, buf, len);
235548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_SKIP_BYTES:
236548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size--;
237548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (!eld->size)
238548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->state = EL_READ;
239548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
240548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
241548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_READ_SIZE_BYTE_24:
242548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size |= eld->b[i] << 24;
243548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_READ_SIZE_BYTE_16;
244548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
245548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_READ_SIZE_BYTE_16:
246548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size |= eld->b[i] << 16;
247548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_READ_SIZE_BYTE_08;
248548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
249548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_READ_SIZE_BYTE_08:
250548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size |= eld->b[i] << 8;
251548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->state = EL_READ_SIZE_BYTE_00;
252548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
253548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		case EL_READ_SIZE_BYTE_00:
254548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			eld->size |= eld->b[i] << 0;
255548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			switch (eld->data_format) {
256548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case EL_DATA_FORMAT_JPEG:
257548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->state = EL_SKIP_BYTES;
258548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->size -= 2;
259548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
260548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case EL_DATA_FORMAT_FUJI_RAW:
261548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->data_format = EL_DATA_FORMAT_EXIF;
262548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->state = EL_SKIP_BYTES;
263548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->size -= 86;
264548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
265548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case EL_DATA_FORMAT_EXIF:
266548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->state = EL_EXIF_FOUND;
267548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
268548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			default:
269548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
270548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
271548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
272548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
273548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		default:
274548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			switch (eld->b[i]) {
275548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_APP1:
276548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			  if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) {
277548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					eld->data_format = EL_DATA_FORMAT_EXIF;
278548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				} else {
279548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/
280548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				}
281548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->size = 0;
282548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->state = EL_READ_SIZE_BYTE_08;
283548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
284548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_DHT:
285548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_DQT:
286548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_APP0:
287548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_APP2:
288548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_APP13:
289548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_COM:
290548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->data_format = EL_DATA_FORMAT_JPEG;
291548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->size = 0;
292548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				eld->state = EL_READ_SIZE_BYTE_08;
293548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
294548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case 0xff:
295548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			case JPEG_MARKER_SOI:
296548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				break;
297548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			default:
298548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				exif_log (eld->log,
299548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					EXIF_LOG_CODE_CORRUPT_DATA,
300548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					"ExifLoader", _("The data supplied "
301548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						"does not seem to contain "
302548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						"EXIF data."));
303548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				exif_loader_reset (eld);
304548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				return 0;
305548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
306548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
307548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
308548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/*
309548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * If we reach this point, the buffer has not been big enough
310548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * to read all data we need. Fill it with new data.
311548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 */
312548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	eld->b_len = 0;
313548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return exif_loader_write (eld, buf, len);
314548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
315548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
316548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifLoader *
317548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_new (void)
318548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
319548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMem *mem = exif_mem_new_default ();
320548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifLoader *l = exif_loader_new_mem (mem);
321548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
322548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mem_unref (mem);
323548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
324548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return l;
325548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
326548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
327548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifLoader *
328548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_new_mem (ExifMem *mem)
329548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
330548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifLoader *loader;
331548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
332548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!mem)
333548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return NULL;
334548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
335548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader = exif_mem_alloc (mem, sizeof (ExifLoader));
336548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader)
337548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return NULL;
338548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->ref_count = 1;
339548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
340548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->mem = mem;
341548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mem_ref (mem);
342548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
343548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return loader;
344548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
345548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
346548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid
347548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_ref (ExifLoader *loader)
348548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
349548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (loader)
350548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		loader->ref_count++;
351548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
352548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
353548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
354548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_free (ExifLoader *loader)
355548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
356548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMem *mem;
357548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
358548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader)
359548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
360548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
361548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	mem = loader->mem;
362548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_loader_reset (loader);
363548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_log_unref (loader->log);
364548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mem_free (mem, loader);
365548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mem_unref (mem);
366548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
367548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
368548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid
369548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_unref (ExifLoader *loader)
370548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
371548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader)
372548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
373548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!--loader->ref_count)
374548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_loader_free (loader);
375548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
376548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
377548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid
378548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_reset (ExifLoader *loader)
379548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
380548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader)
381548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
382548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
383548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->size = 0;
384548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->bytes_read = 0;
385548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->state = 0;
386548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->b_len = 0;
387548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->data_format = EL_DATA_FORMAT_UNKNOWN;
388548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
389548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
390548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifData *
391548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_get_data (ExifLoader *loader)
392548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
393548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifData *ed;
394548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
395548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) ||
396548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    !loader->bytes_read)
397548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return NULL;
398548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
399548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ed = exif_data_new_mem (loader->mem);
400548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_data_log (ed, loader->log);
401548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_data_load_data (ed, loader->buf, loader->bytes_read);
402548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
403548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return ed;
404548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
405548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
406548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid
407548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_get_buf (ExifLoader *loader, const unsigned char **buf,
408548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						  unsigned int *buf_size)
409548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
410548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	const unsigned char* b = NULL;
411548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int s = 0;
412548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
413548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN)) {
414548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (loader->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
415548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			  "Loader format unknown");
416548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	} else {
417548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		b = loader->buf;
418548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		s = loader->bytes_read;
419548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
420548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (buf)
421548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf = b;
422548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (buf_size)
423548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf_size = s;
424548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
425548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
426548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid
427548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_log (ExifLoader *loader, ExifLog *log)
428548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
429548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!loader)
430548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
431548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_log_unref (loader->log);
432548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	loader->log = log;
433548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_log_ref (log);
434548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
435