00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <libexif/exif-loader.h>
00024 #include <libexif/i18n.h>
00025
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <stdio.h>
00029
00030 #undef JPEG_MARKER_SOI
00031 #define JPEG_MARKER_SOI 0xd8
00032 #undef JPEG_MARKER_APP0
00033 #define JPEG_MARKER_APP0 0xe0
00034 #undef JPEG_MARKER_APP1
00035 #define JPEG_MARKER_APP1 0xe1
00036 #undef JPEG_MARKER_APP13
00037 #define JPEG_MARKER_APP13 0xed
00038 #undef JPEG_MARKER_COM
00039 #define JPEG_MARKER_COM 0xfe
00040
00041 typedef enum {
00042 EL_READ = 0,
00043 EL_READ_SIZE_BYTE_24,
00044 EL_READ_SIZE_BYTE_16,
00045 EL_READ_SIZE_BYTE_08,
00046 EL_READ_SIZE_BYTE_00,
00047 EL_SKIP_BYTES,
00048 EL_EXIF_FOUND,
00049 } ExifLoaderState;
00050
00051 typedef enum {
00052 EL_DATA_FORMAT_UNKNOWN,
00053 EL_DATA_FORMAT_EXIF,
00054 EL_DATA_FORMAT_JPEG,
00055 EL_DATA_FORMAT_FUJI_RAW
00056 } ExifLoaderDataFormat;
00057
00058 struct _ExifLoader {
00059 ExifLoaderState state;
00060 ExifLoaderDataFormat data_format;
00061
00062
00063 unsigned char b[12];
00064 unsigned char b_len;
00065
00066 unsigned int size;
00067 unsigned char *buf;
00068 unsigned int bytes_read;
00069
00070 unsigned int ref_count;
00071
00072 ExifLog *log;
00073 ExifMem *mem;
00074 };
00075
00076 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
00077
00078 static void *
00079 exif_loader_alloc (ExifLoader *l, unsigned int i)
00080 {
00081 void *d;
00082
00083 if (!l || !i)
00084 return NULL;
00085
00086 d = exif_mem_alloc (l->mem, i);
00087 if (d)
00088 return d;
00089
00090 EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i);
00091 return NULL;
00092 }
00093
00094 #undef MIN
00095 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
00096
00097 void
00098 exif_loader_write_file (ExifLoader *l, const char *path)
00099 {
00100 FILE *f;
00101 int size;
00102 unsigned char data[1024];
00103
00104 if (!l)
00105 return;
00106
00107 f = fopen (path, "rb");
00108 if (!f) {
00109 exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader",
00110 _("The file '%s' could not be opened."), path);
00111 return;
00112 }
00113 while (1) {
00114 size = fread (data, 1, sizeof (data), f);
00115 if (size <= 0)
00116 break;
00117 if (!exif_loader_write (l, data, size))
00118 break;
00119 }
00120 fclose (f);
00121 }
00122
00123 static unsigned int
00124 exif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len)
00125 {
00126 if (!eld || (len && !buf) || (eld->bytes_read >= eld->size))
00127 return 0;
00128
00129
00130 if (!eld->buf)
00131 eld->buf = exif_loader_alloc (eld, eld->size);
00132 if (!eld->buf)
00133 return 0;
00134
00135
00136 len = MIN (len, eld->size - eld->bytes_read);
00137 memcpy (eld->buf + eld->bytes_read, buf, len);
00138 eld->bytes_read += len;
00139
00140 return (eld->bytes_read >= eld->size) ? 0 : 1;
00141 }
00142
00143 unsigned char
00144 exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
00145 {
00146 unsigned int i;
00147
00148 if (!eld || (len && !buf))
00149 return 0;
00150
00151 switch (eld->state) {
00152 case EL_EXIF_FOUND:
00153 return exif_loader_copy (eld, buf, len);
00154 case EL_SKIP_BYTES:
00155 if (eld->size > len) {
00156 eld->size -= len;
00157 return 1;
00158 }
00159 len -= eld->size;
00160 buf += eld->size;
00161 eld->size = 0;
00162 eld->b_len = 0;
00163 switch (eld->data_format) {
00164 case EL_DATA_FORMAT_FUJI_RAW:
00165 eld->state = EL_READ_SIZE_BYTE_24;
00166 break;
00167 default:
00168 eld->state = EL_READ;
00169 break;
00170 }
00171 break;
00172 default:
00173 break;
00174 }
00175
00176 if (!len)
00177 return 1;
00178 exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
00179 "Scanning %i byte(s) of data...", len);
00180
00181
00182
00183
00184
00185 i = MIN (len, sizeof (eld->b) - eld->b_len);
00186 if (i) {
00187 memcpy (&eld->b[eld->b_len], buf, i);
00188 eld->b_len += i;
00189 if (eld->b_len < sizeof (eld->b))
00190 return 1;
00191 buf += i;
00192 len -= i;
00193 }
00194
00195 switch (eld->data_format) {
00196 case EL_DATA_FORMAT_UNKNOWN:
00197
00198
00199 if (!memcmp (eld->b, "FUJIFILM", 8)) {
00200
00201
00202 eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
00203 eld->size = 84;
00204 eld->state = EL_SKIP_BYTES;
00205 eld->size = 84;
00206
00207 } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {
00208
00209
00210 eld->data_format = EL_DATA_FORMAT_EXIF;
00211 eld->state = EL_READ_SIZE_BYTE_08;
00212 }
00213 default:
00214 break;
00215 }
00216
00217 for (i = 0; i < sizeof (eld->b); i++)
00218 switch (eld->state) {
00219 case EL_EXIF_FOUND:
00220 if (!exif_loader_copy (eld, eld->b + i,
00221 sizeof (eld->b) - i))
00222 return 0;
00223 return exif_loader_copy (eld, buf, len);
00224 case EL_SKIP_BYTES:
00225 eld->size--;
00226 if (!eld->size)
00227 eld->state = EL_READ;
00228 break;
00229
00230 case EL_READ_SIZE_BYTE_24:
00231 eld->size |= eld->b[i] << 24;
00232 eld->state = EL_READ_SIZE_BYTE_16;
00233 break;
00234 case EL_READ_SIZE_BYTE_16:
00235 eld->size |= eld->b[i] << 16;
00236 eld->state = EL_READ_SIZE_BYTE_08;
00237 break;
00238 case EL_READ_SIZE_BYTE_08:
00239 eld->size |= eld->b[i] << 8;
00240 eld->state = EL_READ_SIZE_BYTE_00;
00241 break;
00242 case EL_READ_SIZE_BYTE_00:
00243 eld->size |= eld->b[i] << 0;
00244 switch (eld->data_format) {
00245 case EL_DATA_FORMAT_JPEG:
00246 eld->state = EL_SKIP_BYTES;
00247 eld->size -= 2;
00248 break;
00249 case EL_DATA_FORMAT_FUJI_RAW:
00250 eld->data_format = EL_DATA_FORMAT_EXIF;
00251 eld->state = EL_SKIP_BYTES;
00252 eld->size -= 86;
00253 break;
00254 case EL_DATA_FORMAT_EXIF:
00255 eld->state = EL_EXIF_FOUND;
00256 break;
00257 default:
00258 break;
00259 }
00260 break;
00261
00262 default:
00263 switch (eld->b[i]) {
00264 case JPEG_MARKER_APP1:
00265 eld->data_format = EL_DATA_FORMAT_EXIF;
00266 eld->size = 0;
00267 eld->state = EL_READ_SIZE_BYTE_08;
00268 break;
00269 case JPEG_MARKER_APP0:
00270 case JPEG_MARKER_APP13:
00271 case JPEG_MARKER_COM:
00272 eld->data_format = EL_DATA_FORMAT_JPEG;
00273 eld->size = 0;
00274 eld->state = EL_READ_SIZE_BYTE_08;
00275 break;
00276 case 0xff:
00277 case JPEG_MARKER_SOI:
00278 break;
00279 default:
00280 exif_log (eld->log,
00281 EXIF_LOG_CODE_CORRUPT_DATA,
00282 "ExifLoader", _("The data supplied "
00283 "does not seem to contain "
00284 "EXIF data."));
00285 exif_loader_reset (eld);
00286 return 0;
00287 }
00288 }
00289
00290
00291
00292
00293
00294 eld->b_len = 0;
00295 return exif_loader_write (eld, buf, len);
00296 }
00297
00298 ExifLoader *
00299 exif_loader_new (void)
00300 {
00301 ExifMem *mem = exif_mem_new_default ();
00302 ExifLoader *l = exif_loader_new_mem (mem);
00303
00304 exif_mem_unref (mem);
00305
00306 return l;
00307 }
00308
00309 ExifLoader *
00310 exif_loader_new_mem (ExifMem *mem)
00311 {
00312 ExifLoader *loader;
00313
00314 if (!mem)
00315 return NULL;
00316
00317 loader = exif_mem_alloc (mem, sizeof (ExifLoader));
00318 if (!loader)
00319 return NULL;
00320 loader->ref_count = 1;
00321
00322 loader->mem = mem;
00323 exif_mem_ref (mem);
00324
00325 return loader;
00326 }
00327
00328 void
00329 exif_loader_ref (ExifLoader *loader)
00330 {
00331 if (loader)
00332 loader->ref_count++;
00333 }
00334
00335 static void
00336 exif_loader_free (ExifLoader *loader)
00337 {
00338 ExifMem *mem;
00339
00340 if (!loader)
00341 return;
00342
00343 mem = loader->mem;
00344 exif_loader_reset (loader);
00345 exif_mem_free (mem, loader);
00346 exif_mem_unref (mem);
00347 }
00348
00349 void
00350 exif_loader_unref (ExifLoader *loader)
00351 {
00352 if (!loader)
00353 return;
00354 if (!--loader->ref_count)
00355 exif_loader_free (loader);
00356 }
00357
00358 void
00359 exif_loader_reset (ExifLoader *loader)
00360 {
00361 if (!loader)
00362 return;
00363 exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
00364 loader->size = 0;
00365 loader->bytes_read = 0;
00366 loader->state = 0;
00367 loader->b_len = 0;
00368 loader->data_format = EL_DATA_FORMAT_UNKNOWN;
00369 }
00370
00371 ExifData *
00372 exif_loader_get_data (ExifLoader *loader)
00373 {
00374 ExifData *ed;
00375
00376 if (!loader)
00377 return NULL;
00378
00379 ed = exif_data_new_mem (loader->mem);
00380 exif_data_log (ed, loader->log);
00381 exif_data_load_data (ed, loader->buf, loader->bytes_read);
00382
00383 return ed;
00384 }
00385
00386 void
00387 exif_loader_log (ExifLoader *loader, ExifLog *log)
00388 {
00389 if (!loader)
00390 return;
00391 exif_log_unref (loader->log);
00392 loader->log = log;
00393 exif_log_ref (log);
00394 }