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