2 #include "exif-loader.h"
7 #include <libjpeg/jpeg-marker.h>
11 EL_READ_SIZE_HIGH_BYTE,
12 EL_READ_SIZE_LOW_BYTE,
19 ExifLoaderState state;
26 unsigned int ref_count;
30 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
32 /* This function imitates code from libexif, written by Lutz
33 * Müller. See libexif/exif-data.c:exif_data_new_from_file. Here, it
34 * can cope with a sequence of data chunks.
37 exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
43 if (eld->state == EL_FAILED) return 0;
44 if (eld->size && eld->bytes_read == eld->size) return 0;
46 for (i = 0; (i < len) && (eld->state != EL_EXIF_FOUND) &&
47 (eld->state != EL_FAILED); i++) {
57 case EL_READ_SIZE_HIGH_BYTE:
58 eld->size = buf [i] << 8;
59 eld->state = EL_READ_SIZE_LOW_BYTE;
62 case EL_READ_SIZE_LOW_BYTE:
65 switch (eld->last_marker) {
66 case JPEG_MARKER_APP0:
67 eld->state = EL_SKIP_BYTES;
70 case JPEG_MARKER_APP1:
71 eld->state = EL_EXIF_FOUND;
76 * Assume that we are reading EXIF data.
77 * This should probably be verified by reading
80 eld->state = EL_EXIF_FOUND;
91 if (buf [i] == JPEG_MARKER_APP0 ||
92 buf [i] == JPEG_MARKER_APP1) {
93 eld->state = EL_READ_SIZE_HIGH_BYTE;
94 eld->last_marker = buf [i];
96 } else if (buf [i] == JPEG_MARKER_SOI) {
99 /* Assume that we are reading EXIF
100 * data. This should probably be
101 * verified by reading some bytes
104 eld->last_marker = JPEG_MARKER_APP1;
105 eld->state = EL_READ_SIZE_HIGH_BYTE;
112 len_remain = len - i;
113 if (!len_remain) return 1;
115 if (eld->state == EL_EXIF_FOUND && len_remain > 0) {
116 if (eld->buf == NULL) {
117 eld->buf = malloc (sizeof (unsigned char) * eld->size);
121 if (eld->bytes_read < eld->size) {
124 /* the number of bytes we need to copy */
125 cp_len = MIN (eld->size - eld->bytes_read, len_remain);
127 if ((cp_len + eld->bytes_read) > eld->size) return 1;
130 memcpy (eld->buf + eld->bytes_read, &buf[i], cp_len);
131 eld->bytes_read += cp_len;
139 exif_loader_new (void)
141 ExifLoader *loader = malloc (sizeof (ExifLoader));
143 memset (loader, 0, sizeof (ExifLoader));
149 exif_loader_ref (ExifLoader *loader)
151 if (loader) loader->ref_count++;
155 exif_loader_unref (ExifLoader *loader)
158 if (!--loader->ref_count) {
159 exif_loader_reset (loader);
165 exif_loader_reset (ExifLoader *loader)
168 free (loader->buf); loader->buf = NULL;
170 loader->bytes_read = 0;
171 loader->last_marker = 0;
176 exif_loader_get_data (ExifLoader *loader)
178 return exif_data_new_from_data (loader->buf, loader->bytes_read);