3 #include <libexif/exif-loader.h>
4 #include <libexif/i18n.h>
10 #include <libjpeg/jpeg-marker.h>
14 EL_READ_SIZE_HIGH_BYTE,
15 EL_READ_SIZE_LOW_BYTE,
22 ExifLoaderState state;
27 unsigned int bytes_read;
29 unsigned int ref_count;
36 exif_loader_alloc (ExifLoader *l, unsigned int i)
40 if (!l || !i) return NULL;
42 d = exif_mem_alloc (l->mem, i);
45 EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
50 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
53 exif_loader_write_file (ExifLoader *l, const char *path)
57 unsigned char data[1024];
61 f = fopen (path, "rb");
63 exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
64 _("The file '%s' could not be opened."), path);
68 size = fread (data, 1, sizeof (data), f);
70 if (!exif_loader_write (l, data, size)) break;
76 exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
78 unsigned int i, len_remain;
80 if (!eld || !buf || !len) return 0;
81 if (eld->state == EL_FAILED) return 0;
82 if (eld->size && eld->bytes_read == eld->size) return 0;
84 exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
85 "Scanning %i byte(s) of data...", len);
87 for (i = 0; (i < len) && (eld->state != EL_EXIF_FOUND) &&
88 (eld->state != EL_FAILED); i++)
97 case EL_READ_SIZE_HIGH_BYTE:
98 eld->size = buf [i] << 8;
99 eld->state = EL_READ_SIZE_LOW_BYTE;
102 case EL_READ_SIZE_LOW_BYTE:
103 eld->size |= buf [i];
105 switch (eld->last_marker) {
106 case JPEG_MARKER_APP0:
107 case JPEG_MARKER_APP13:
108 case JPEG_MARKER_COM:
109 eld->state = EL_SKIP_BYTES;
113 case JPEG_MARKER_APP1:
114 eld->state = EL_EXIF_FOUND;
119 * Assume that we are reading EXIF data.
120 * This should probably be verified by reading
123 eld->state = EL_EXIF_FOUND;
129 eld->last_marker = 0;
133 if (buf[i] != 0xff) {
134 if (buf[i] == JPEG_MARKER_APP0 ||
135 buf[i] == JPEG_MARKER_APP1 ||
136 buf[i] == JPEG_MARKER_APP13 ||
137 buf[i] == JPEG_MARKER_COM) {
138 eld->state = EL_READ_SIZE_HIGH_BYTE;
139 eld->last_marker = buf [i];
141 } else if (buf [i] == JPEG_MARKER_SOI) {
144 /* Assume that we are reading EXIF
145 * data. This should probably be
146 * verified by reading some bytes
149 eld->last_marker = JPEG_MARKER_APP1;
150 eld->state = EL_READ_SIZE_HIGH_BYTE;
156 len_remain = len - i;
157 if (!len_remain) return 1;
159 if (eld->state == EL_EXIF_FOUND) {
160 if (eld->buf == NULL) {
161 eld->buf = exif_loader_alloc (eld, eld->size);
162 if (!eld->buf) return 0;
166 if (eld->bytes_read < eld->size) {
169 /* the number of bytes we need to copy */
170 cp_len = MIN (eld->size - eld->bytes_read, len_remain);
172 if ((cp_len + eld->bytes_read) > eld->size) return 1;
175 memcpy (eld->buf + eld->bytes_read, &buf[i], cp_len);
176 eld->bytes_read += cp_len;
184 exif_loader_new (void)
186 ExifMem *mem = exif_mem_new_default ();
187 ExifLoader *l = exif_loader_new_mem (mem);
189 exif_mem_unref (mem);
195 exif_loader_new_mem (ExifMem *mem)
199 if (!mem) return NULL;
201 loader = exif_mem_alloc (mem, sizeof (ExifLoader));
202 if (!loader) return NULL;
203 loader->ref_count = 1;
212 exif_loader_ref (ExifLoader *loader)
214 if (loader) loader->ref_count++;
218 exif_loader_free (ExifLoader *loader)
225 exif_loader_reset (loader);
226 exif_mem_free (mem, loader);
227 exif_mem_unref (mem);
231 exif_loader_unref (ExifLoader *loader)
234 if (!--loader->ref_count)
235 exif_loader_free (loader);
239 exif_loader_reset (ExifLoader *loader)
242 exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
244 loader->bytes_read = 0;
245 loader->last_marker = 0;
250 exif_loader_get_data (ExifLoader *loader)
254 if (!loader) return NULL;
256 ed = exif_data_new_mem (loader->mem);
257 exif_data_log (ed, loader->log);
258 exif_data_load_data (ed, loader->buf, loader->bytes_read);
264 exif_loader_log (ExifLoader *loader, ExifLog *log)
267 exif_log_unref (loader->log);