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