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 exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader",
00180 "Scanning %i byte(s) of data...", len);
00181
00182
00183
00184
00185
00186 i = MIN (len, sizeof (eld->b) - eld->b_len);
00187 if (i) {
00188 memcpy (&eld->b[eld->b_len], buf, i);
00189 eld->b_len += i;
00190 if (eld->b_len < sizeof (eld->b))
00191 return 1;
00192 buf += i;
00193 len -= i;
00194 }
00195
00196 switch (eld->data_format) {
00197 case EL_DATA_FORMAT_UNKNOWN:
00198
00199
00200 if (!memcmp (eld->b, "FUJIFILM", 8)) {
00201
00202
00203 eld->data_format = EL_DATA_FORMAT_FUJI_RAW;
00204 eld->size = 84;
00205 eld->state = EL_SKIP_BYTES;
00206 eld->size = 84;
00207
00208 } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) {
00209
00210
00211 eld->data_format = EL_DATA_FORMAT_EXIF;
00212 eld->state = EL_READ_SIZE_BYTE_08;
00213 }
00214 default:
00215 break;
00216 }
00217
00218 for (i = 0; i < sizeof (eld->b); i++)
00219 switch (eld->state) {
00220 case EL_EXIF_FOUND:
00221 if (!exif_loader_copy (eld, eld->b + i,
00222 sizeof (eld->b) - i))
00223 return 0;
00224 return exif_loader_copy (eld, buf, len);
00225 case EL_SKIP_BYTES:
00226 eld->size--;
00227 if (!eld->size)
00228 eld->state = EL_READ;
00229 break;
00230
00231 case EL_READ_SIZE_BYTE_24:
00232 eld->size |= eld->b[i] << 24;
00233 eld->state = EL_READ_SIZE_BYTE_16;
00234 break;
00235 case EL_READ_SIZE_BYTE_16:
00236 eld->size |= eld->b[i] << 16;
00237 eld->state = EL_READ_SIZE_BYTE_08;
00238 break;
00239 case EL_READ_SIZE_BYTE_08:
00240 eld->size |= eld->b[i] << 8;
00241 eld->state = EL_READ_SIZE_BYTE_00;
00242 break;
00243 case EL_READ_SIZE_BYTE_00:
00244 eld->size |= eld->b[i] << 0;
00245 switch (eld->data_format) {
00246 case EL_DATA_FORMAT_JPEG:
00247 eld->state = EL_SKIP_BYTES;
00248 eld->size -= 2;
00249 break;
00250 case EL_DATA_FORMAT_FUJI_RAW:
00251 eld->data_format = EL_DATA_FORMAT_EXIF;
00252 eld->state = EL_SKIP_BYTES;
00253 eld->size -= 86;
00254 break;
00255 case EL_DATA_FORMAT_EXIF:
00256 eld->state = EL_EXIF_FOUND;
00257 break;
00258 default:
00259 break;
00260 }
00261 break;
00262
00263 default:
00264 switch (eld->b[i]) {
00265 case JPEG_MARKER_APP1:
00266 if (!memcmp (eld->b + i + 3, ExifHeader, MIN(sizeof (ExifHeader), MAX(0, sizeof (eld->b) - i - 3)))) {
00267 eld->data_format = EL_DATA_FORMAT_EXIF;
00268 } else {
00269 eld->data_format = EL_DATA_FORMAT_JPEG;
00270 }
00271 eld->size = 0;
00272 eld->state = EL_READ_SIZE_BYTE_08;
00273 break;
00274 case JPEG_MARKER_APP0:
00275 case JPEG_MARKER_APP2:
00276 case JPEG_MARKER_APP13:
00277 case JPEG_MARKER_COM:
00278 eld->data_format = EL_DATA_FORMAT_JPEG;
00279 eld->size = 0;
00280 eld->state = EL_READ_SIZE_BYTE_08;
00281 break;
00282 case 0xff:
00283 case JPEG_MARKER_SOI:
00284 break;
00285 default:
00286 exif_log (eld->log,
00287 EXIF_LOG_CODE_CORRUPT_DATA,
00288 "ExifLoader", _("The data supplied "
00289 "does not seem to contain "
00290 "EXIF data."));
00291 exif_loader_reset (eld);
00292 return 0;
00293 }
00294 }
00295
00296
00297
00298
00299
00300 eld->b_len = 0;
00301 return exif_loader_write (eld, buf, len);
00302 }
00303
00304 ExifLoader *
00305 exif_loader_new (void)
00306 {
00307 ExifMem *mem = exif_mem_new_default ();
00308 ExifLoader *l = exif_loader_new_mem (mem);
00309
00310 exif_mem_unref (mem);
00311
00312 return l;
00313 }
00314
00315 ExifLoader *
00316 exif_loader_new_mem (ExifMem *mem)
00317 {
00318 ExifLoader *loader;
00319
00320 if (!mem)
00321 return NULL;
00322
00323 loader = exif_mem_alloc (mem, sizeof (ExifLoader));
00324 if (!loader)
00325 return NULL;
00326 loader->ref_count = 1;
00327
00328 loader->mem = mem;
00329 exif_mem_ref (mem);
00330
00331 return loader;
00332 }
00333
00334 void
00335 exif_loader_ref (ExifLoader *loader)
00336 {
00337 if (loader)
00338 loader->ref_count++;
00339 }
00340
00341 static void
00342 exif_loader_free (ExifLoader *loader)
00343 {
00344 ExifMem *mem;
00345
00346 if (!loader)
00347 return;
00348
00349 mem = loader->mem;
00350 exif_loader_reset (loader);
00351 exif_mem_free (mem, loader);
00352 exif_mem_unref (mem);
00353 }
00354
00355 void
00356 exif_loader_unref (ExifLoader *loader)
00357 {
00358 if (!loader)
00359 return;
00360 if (!--loader->ref_count)
00361 exif_loader_free (loader);
00362 }
00363
00364 void
00365 exif_loader_reset (ExifLoader *loader)
00366 {
00367 if (!loader)
00368 return;
00369 exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
00370 loader->size = 0;
00371 loader->bytes_read = 0;
00372 loader->state = 0;
00373 loader->b_len = 0;
00374 loader->data_format = EL_DATA_FORMAT_UNKNOWN;
00375 }
00376
00377 ExifData *
00378 exif_loader_get_data (ExifLoader *loader)
00379 {
00380 ExifData *ed;
00381
00382 if (!loader)
00383 return NULL;
00384
00385 ed = exif_data_new_mem (loader->mem);
00386 exif_data_log (ed, loader->log);
00387 exif_data_load_data (ed, loader->buf, loader->bytes_read);
00388
00389 return ed;
00390 }
00391
00392 void
00393 exif_loader_log (ExifLoader *loader, ExifLog *log)
00394 {
00395 if (!loader)
00396 return;
00397 exif_log_unref (loader->log);
00398 loader->log = log;
00399 exif_log_ref (log);
00400 }