1548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* exif-loader.c 2548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 3548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net> 4548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 5548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is free software; you can redistribute it and/or 6548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * modify it under the terms of the GNU Lesser General Public 7548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License as published by the Free Software Foundation; either 8548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * version 2 of the License, or (at your option) any later version. 9548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 10548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is distributed in the hope that it will be useful, 11548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * but WITHOUT ANY WARRANTY; without even the implied warranty of 12548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Lesser General Public License for more details. 14548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * 15548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * You should have received a copy of the GNU Lesser General Public 16548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License along with this library; if not, write to the 17548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Boston, MA 02110-1301 USA. 19548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 20548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 21548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <config.h> 22548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 23548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-loader.h> 24548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-utils.h> 25548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/i18n.h> 26548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 27548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <sys/types.h> 28548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdlib.h> 29548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <string.h> 30548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdio.h> 31548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 32548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_DHT 33548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_DHT 0xc4 34548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_SOI 35548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_SOI 0xd8 36548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_DQT 37548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_DQT 0xdb 38548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP0 39548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP0 0xe0 40548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP1 41548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP1 0xe1 42548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP2 43548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP2 0xe2 44548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_APP13 45548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_APP13 0xed 46548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#undef JPEG_MARKER_COM 47548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define JPEG_MARKER_COM 0xfe 48548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 49548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissentypedef enum { 50548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_READ = 0, 51548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_READ_SIZE_BYTE_24, 52548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_READ_SIZE_BYTE_16, 53548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_READ_SIZE_BYTE_08, 54548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_READ_SIZE_BYTE_00, 55548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_SKIP_BYTES, 56548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_EXIF_FOUND, 57548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} ExifLoaderState; 58548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 59548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissentypedef enum { 60548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_DATA_FORMAT_UNKNOWN, 61548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_DATA_FORMAT_EXIF, 62548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_DATA_FORMAT_JPEG, 63548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EL_DATA_FORMAT_FUJI_RAW 64548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} ExifLoaderDataFormat; 65548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 66548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*! \internal */ 67548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstruct _ExifLoader { 68548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifLoaderState state; 69548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifLoaderDataFormat data_format; 70548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 71548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /*! Small buffer used for detection of format */ 72548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned char b[12]; 73548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 74548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /*! Number of bytes in the small buffer \c b */ 75548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned char b_len; 76548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 77548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int size; 78548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned char *buf; 79548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int bytes_read; 80548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 81548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int ref_count; 82548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 83548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifLog *log; 84548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMem *mem; 85548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}; 86548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 87548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*! Magic number for EXIF header */ 88548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; 89548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 90548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void * 91548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_alloc (ExifLoader *l, unsigned int i) 92548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 93548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen void *d; 94548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 95548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!l || !i) 96548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return NULL; 97548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 98548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen d = exif_mem_alloc (l->mem, i); 99548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (d) 100548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return d; 101548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 102548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i); 103548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return NULL; 104548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 105548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 106548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid 107548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_write_file (ExifLoader *l, const char *path) 108548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 109548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen FILE *f; 110548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen int size; 111548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned char data[1024]; 112548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 113548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!l) 114548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 115548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 116548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen f = fopen (path, "rb"); 117548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!f) { 118548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader", 119548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen _("The file '%s' could not be opened."), path); 120548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 121548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 122548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen while (1) { 123548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen size = fread (data, 1, sizeof (data), f); 124548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (size <= 0) 125548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 126548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!exif_loader_write (l, data, size)) 127548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 128548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 129548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen fclose (f); 130548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 131548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 132548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic unsigned int 133548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len) 134548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 135548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!eld || (len && !buf) || (eld->bytes_read >= eld->size)) 136548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 0; 137548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 138548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* If needed, allocate the buffer. */ 139548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!eld->buf) 140548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->buf = exif_loader_alloc (eld, eld->size); 141548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!eld->buf) 142548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 0; 143548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 144548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Copy memory */ 145548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen len = MIN (len, eld->size - eld->bytes_read); 146548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen memcpy (eld->buf + eld->bytes_read, buf, len); 147548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->bytes_read += len; 148548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 149548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return (eld->bytes_read >= eld->size) ? 0 : 1; 150548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 151548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 152548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenunsigned char 153548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len) 154548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 155548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int i; 156548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 157548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!eld || (len && !buf)) 158548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 0; 159548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 160548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (eld->state) { 161548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_EXIF_FOUND: 162548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return exif_loader_copy (eld, buf, len); 163548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_SKIP_BYTES: 164548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (eld->size > len) { 165548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size -= len; 166548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 1; 167548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 168548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen len -= eld->size; 169548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf += eld->size; 170548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size = 0; 171548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->b_len = 0; 172548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (eld->data_format) { 173548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_DATA_FORMAT_FUJI_RAW: 174548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_24; 175548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 176548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 177548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ; 178548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 179548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 180548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 181548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 182548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_READ: 183548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 184548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 185548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 186548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 187548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!len) 188548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 1; 189548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader", 190548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Scanning %i byte(s) of data...", len); 191548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 192548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 193548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * First fill the small buffer. Only continue if the buffer 194548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * is filled. Note that EXIF data contains at least 12 bytes. 195548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 196548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen i = MIN (len, sizeof (eld->b) - eld->b_len); 197548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (i) { 198548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen memcpy (&eld->b[eld->b_len], buf, i); 199548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->b_len += i; 200548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (eld->b_len < sizeof (eld->b)) 201548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 1; 202548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen buf += i; 203548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen len -= i; 204548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 205548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 206548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (eld->data_format) { 207548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_DATA_FORMAT_UNKNOWN: 208548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 209548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Check the small buffer against known formats. */ 210548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!memcmp (eld->b, "FUJIFILM", 8)) { 211548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 212548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Skip to byte 84. There is another offset there. */ 213548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->data_format = EL_DATA_FORMAT_FUJI_RAW; 214548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size = 84; 215548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_SKIP_BYTES; 216548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size = 84; 217548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 218548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) { 219548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 220548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* Read the size (2 bytes). */ 221548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->data_format = EL_DATA_FORMAT_EXIF; 222548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_08; 223548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 224548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 225548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 226548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 227548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 228548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen for (i = 0; i < sizeof (eld->b); i++) 229548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (eld->state) { 230548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_EXIF_FOUND: 231548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!exif_loader_copy (eld, eld->b + i, 232548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen sizeof (eld->b) - i)) 233548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 0; 234548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return exif_loader_copy (eld, buf, len); 235548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_SKIP_BYTES: 236548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size--; 237548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!eld->size) 238548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ; 239548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 240548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 241548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_READ_SIZE_BYTE_24: 242548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size |= eld->b[i] << 24; 243548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_16; 244548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 245548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_READ_SIZE_BYTE_16: 246548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size |= eld->b[i] << 16; 247548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_08; 248548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 249548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_READ_SIZE_BYTE_08: 250548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size |= eld->b[i] << 8; 251548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_00; 252548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 253548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_READ_SIZE_BYTE_00: 254548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size |= eld->b[i] << 0; 255548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (eld->data_format) { 256548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_DATA_FORMAT_JPEG: 257548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_SKIP_BYTES; 258548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size -= 2; 259548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 260548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_DATA_FORMAT_FUJI_RAW: 261548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->data_format = EL_DATA_FORMAT_EXIF; 262548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_SKIP_BYTES; 263548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size -= 86; 264548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 265548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case EL_DATA_FORMAT_EXIF: 266548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_EXIF_FOUND; 267548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 268548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 269548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 270548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 271548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 272548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 273548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 274548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen switch (eld->b[i]) { 275548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_APP1: 276548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) { 277548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->data_format = EL_DATA_FORMAT_EXIF; 278548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else { 279548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/ 280548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 281548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size = 0; 282548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_08; 283548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 284548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_DHT: 285548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_DQT: 286548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_APP0: 287548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_APP2: 288548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_APP13: 289548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_COM: 290548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->data_format = EL_DATA_FORMAT_JPEG; 291548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->size = 0; 292548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->state = EL_READ_SIZE_BYTE_08; 293548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 294548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case 0xff: 295548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen case JPEG_MARKER_SOI: 296548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen break; 297548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen default: 298548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (eld->log, 299548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen EXIF_LOG_CODE_CORRUPT_DATA, 300548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "ExifLoader", _("The data supplied " 301548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "does not seem to contain " 302548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "EXIF data.")); 303548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_loader_reset (eld); 304548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return 0; 305548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 306548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 307548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 308548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen /* 309548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * If we reach this point, the buffer has not been big enough 310548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * to read all data we need. Fill it with new data. 311548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */ 312548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen eld->b_len = 0; 313548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return exif_loader_write (eld, buf, len); 314548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 315548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 316548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifLoader * 317548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_new (void) 318548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 319548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMem *mem = exif_mem_new_default (); 320548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifLoader *l = exif_loader_new_mem (mem); 321548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 322548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_unref (mem); 323548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 324548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return l; 325548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 326548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 327548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifLoader * 328548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_new_mem (ExifMem *mem) 329548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 330548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifLoader *loader; 331548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 332548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!mem) 333548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return NULL; 334548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 335548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader = exif_mem_alloc (mem, sizeof (ExifLoader)); 336548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader) 337548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return NULL; 338548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->ref_count = 1; 339548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 340548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->mem = mem; 341548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_ref (mem); 342548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 343548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return loader; 344548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 345548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 346548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid 347548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_ref (ExifLoader *loader) 348548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 349548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (loader) 350548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->ref_count++; 351548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 352548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 353548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void 354548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_free (ExifLoader *loader) 355548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 356548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifMem *mem; 357548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 358548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader) 359548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 360548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 361548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen mem = loader->mem; 362548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_loader_reset (loader); 363548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log_unref (loader->log); 364548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_free (mem, loader); 365548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_unref (mem); 366548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 367548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 368548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid 369548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_unref (ExifLoader *loader) 370548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 371548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader) 372548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 373548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!--loader->ref_count) 374548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_loader_free (loader); 375548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 376548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 377548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid 378548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_reset (ExifLoader *loader) 379548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 380548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader) 381548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 382548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_mem_free (loader->mem, loader->buf); loader->buf = NULL; 383548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->size = 0; 384548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->bytes_read = 0; 385548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->state = 0; 386548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->b_len = 0; 387548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->data_format = EL_DATA_FORMAT_UNKNOWN; 388548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 389548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 390548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifData * 391548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_get_data (ExifLoader *loader) 392548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 393548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ExifData *ed; 394548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 395548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) || 396548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen !loader->bytes_read) 397548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return NULL; 398548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 399548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen ed = exif_data_new_mem (loader->mem); 400548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_data_log (ed, loader->log); 401548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_data_load_data (ed, loader->buf, loader->bytes_read); 402548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 403548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return ed; 404548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 405548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 406548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid 407548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_get_buf (ExifLoader *loader, const unsigned char **buf, 408548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int *buf_size) 409548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 410548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen const unsigned char* b = NULL; 411548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen unsigned int s = 0; 412548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 413548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN)) { 414548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log (loader->log, EXIF_LOG_CODE_DEBUG, "ExifLoader", 415548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen "Loader format unknown"); 416548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } else { 417548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen b = loader->buf; 418548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen s = loader->bytes_read; 419548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen } 420548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (buf) 421548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf = b; 422548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (buf_size) 423548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *buf_size = s; 424548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 425548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen 426548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenvoid 427548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_loader_log (ExifLoader *loader, ExifLog *log) 428548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{ 429548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen if (!loader) 430548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen return; 431548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log_unref (loader->log); 432548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen loader->log = log; 433548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen exif_log_ref (log); 434548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen} 435