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