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
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 eld->data_format = EL_DATA_FORMAT_EXIF;
00267 eld->size = 0;
00268 eld->state = EL_READ_SIZE_BYTE_08;
00269 break;
00270 case JPEG_MARKER_APP0:
00271 case JPEG_MARKER_APP13:
00272 case JPEG_MARKER_COM:
00273 eld->data_format = EL_DATA_FORMAT_JPEG;
00274 eld->size = 0;
00275 eld->state = EL_READ_SIZE_BYTE_08;
00276 break;
00277 case 0xff:
00278 case JPEG_MARKER_SOI:
00279 break;
00280 default:
00281 exif_log (eld->log,
00282 EXIF_LOG_CODE_CORRUPT_DATA,
00283 "ExifLoader", _("The data supplied "
00284 "does not seem to contain "
00285 "EXIF data."));
00286 exif_loader_reset (eld);
00287 return 0;
00288 }
00289 }
00290
00291
00292
00293
00294
00295 eld->b_len = 0;
00296 return exif_loader_write (eld, buf, len);
00297 }
00298
00299 ExifLoader *
00300 exif_loader_new (void)
00301 {
00302 ExifMem *mem = exif_mem_new_default ();
00303 ExifLoader *l = exif_loader_new_mem (mem);
00304
00305 exif_mem_unref (mem);
00306
00307 return l;
00308 }
00309
00310 ExifLoader *
00311 exif_loader_new_mem (ExifMem *mem)
00312 {
00313 ExifLoader *loader;
00314
00315 if (!mem)
00316 return NULL;
00317
00318 loader = exif_mem_alloc (mem, sizeof (ExifLoader));
00319 if (!loader)
00320 return NULL;
00321 loader->ref_count = 1;
00322
00323 loader->mem = mem;
00324 exif_mem_ref (mem);
00325
00326 return loader;
00327 }
00328
00329 void
00330 exif_loader_ref (ExifLoader *loader)
00331 {
00332 if (loader)
00333 loader->ref_count++;
00334 }
00335
00336 static void
00337 exif_loader_free (ExifLoader *loader)
00338 {
00339 ExifMem *mem;
00340
00341 if (!loader)
00342 return;
00343
00344 mem = loader->mem;
00345 exif_loader_reset (loader);
00346 exif_mem_free (mem, loader);
00347 exif_mem_unref (mem);
00348 }
00349
00350 void
00351 exif_loader_unref (ExifLoader *loader)
00352 {
00353 if (!loader)
00354 return;
00355 if (!--loader->ref_count)
00356 exif_loader_free (loader);
00357 }
00358
00359 void
00360 exif_loader_reset (ExifLoader *loader)
00361 {
00362 if (!loader)
00363 return;
00364 exif_mem_free (loader->mem, loader->buf); loader->buf = NULL;
00365 loader->size = 0;
00366 loader->bytes_read = 0;
00367 loader->state = 0;
00368 loader->b_len = 0;
00369 loader->data_format = EL_DATA_FORMAT_UNKNOWN;
00370 }
00371
00372 ExifData *
00373 exif_loader_get_data (ExifLoader *loader)
00374 {
00375 ExifData *ed;
00376
00377 if (!loader)
00378 return NULL;
00379
00380 ed = exif_data_new_mem (loader->mem);
00381 exif_data_log (ed, loader->log);
00382 exif_data_load_data (ed, loader->buf, loader->bytes_read);
00383
00384 return ed;
00385 }
00386
00387 void
00388 exif_loader_log (ExifLoader *loader, ExifLog *log)
00389 {
00390 if (!loader)
00391 return;
00392 exif_log_unref (loader->log);
00393 loader->log = log;
00394 exif_log_ref (log);
00395 }