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;
24 unsigned int bytes_read;
26 unsigned int ref_count;
30 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
33 * This function imitates code from libexif, written by Lutz
34 * Müller. See libexif/exif-data.c:exif_data_new_from_file. Here, it
35 * can cope with a sequence of data chunks.
38 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++)
56 case EL_READ_SIZE_HIGH_BYTE:
57 eld->size = buf [i] << 8;
58 eld->state = EL_READ_SIZE_LOW_BYTE;
61 case EL_READ_SIZE_LOW_BYTE:
64 switch (eld->last_marker) {
65 case JPEG_MARKER_APP0:
66 case JPEG_MARKER_APP13:
67 eld->state = EL_SKIP_BYTES;
71 case JPEG_MARKER_APP1:
72 eld->state = EL_EXIF_FOUND;
77 * Assume that we are reading EXIF data.
78 * This should probably be verified by reading
81 eld->state = EL_EXIF_FOUND;
92 if (buf[i] == JPEG_MARKER_APP0 ||
93 buf[i] == JPEG_MARKER_APP1 ||
94 buf[i] == JPEG_MARKER_APP13) {
95 eld->state = EL_READ_SIZE_HIGH_BYTE;
96 eld->last_marker = buf [i];
98 } else if (buf [i] == JPEG_MARKER_SOI) {
101 /* Assume that we are reading EXIF
102 * data. This should probably be
103 * verified by reading some bytes
106 eld->last_marker = JPEG_MARKER_APP1;
107 eld->state = EL_READ_SIZE_HIGH_BYTE;
113 len_remain = len - i;
114 if (!len_remain) return 1;
116 if (eld->state == EL_EXIF_FOUND && len_remain > 0) {
117 if (eld->buf == NULL) {
118 eld->buf = malloc (sizeof (unsigned char) * eld->size);
122 if (eld->bytes_read < eld->size) {
125 /* the number of bytes we need to copy */
126 cp_len = MIN (eld->size - eld->bytes_read, len_remain);
128 if ((cp_len + eld->bytes_read) > eld->size) return 1;
131 memcpy (eld->buf + eld->bytes_read, &buf[i], cp_len);
132 eld->bytes_read += cp_len;
140 exif_loader_new (void)
142 ExifLoader *loader = malloc (sizeof (ExifLoader));
144 memset (loader, 0, sizeof (ExifLoader));
145 loader->ref_count = 1;
151 exif_loader_ref (ExifLoader *loader)
153 if (loader) loader->ref_count++;
157 exif_loader_unref (ExifLoader *loader)
160 if (!--loader->ref_count) {
161 exif_loader_reset (loader);
167 exif_loader_reset (ExifLoader *loader)
170 free (loader->buf); loader->buf = NULL;
172 loader->bytes_read = 0;
173 loader->last_marker = 0;
178 exif_loader_get_data (ExifLoader *loader)
180 return exif_data_new_from_data (loader->buf, loader->bytes_read);