Mercurial > geeqie.yaz
diff src/exif.c @ 51:276ea4c98d33
Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
* exif.[ch]: Use glib provided data types and byte order functions for
consistency with rest of application. Made several more functions
available in the header. Use MakerNote parsing from format_raw.c.
* format_canon.[ch]: Changes to match exif.h and format_raw.h.
* format_fuji.[ch]: Add support for Fuji EXIF MakerNote.
* format_nikon.[ch]: New files, add support for Nikon EXIF MakerNote.
* format_raw.[ch]: Add EXIF MakerNote parser functions to gather all
camera formats here (similar to existing raw format list).
* src/Makefile.am: Add format_nikon.[ch].
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
##### an offical release when making enhancements and translation updates. #####
author | gqview |
---|---|
date | Sun, 05 Jun 2005 02:48:54 +0000 |
parents | aa4c0e1b54b0 |
children | b58cac75ad12 |
line wrap: on
line diff
--- a/src/exif.c Sat Jun 04 08:06:47 2005 +0000 +++ b/src/exif.c Sun Jun 05 02:48:54 2005 +0000 @@ -73,8 +73,6 @@ #include "format_raw.h" #include "ui_fileops.h" -/* makernote parsers */ -#include "format_canon.h" /* *----------------------------------------------------------------------------- @@ -436,10 +434,6 @@ *----------------------------------------------------------------------------- */ -#define BYTE_ORDER_INTEL 1 -#define BYTE_ORDER_MOTOROLA 2 - - #define MARKER_UNKNOWN 0x00 #define MARKER_SOI 0xD8 #define MARKER_APP1 0xE1 @@ -461,7 +455,7 @@ } IFDEntry; -static const ExifMarker *exif_marker_from_tag(uint16_t tag, const ExifMarker *list); +static const ExifMarker *exif_marker_from_tag(guint16 tag, const ExifMarker *list); /* *----------------------------------------------------------------------------- @@ -469,8 +463,8 @@ *----------------------------------------------------------------------------- */ -ExifItem *exif_item_new(ExifFormatType format, unsigned int tag, - unsigned int elements, const ExifMarker *marker) +ExifItem *exif_item_new(ExifFormatType format, guint tag, + guint elements, const ExifMarker *marker) { ExifItem *item; @@ -495,10 +489,10 @@ item->data_len = sizeof(char) * elements; break; case EXIF_FORMAT_SHORT_UNSIGNED: - item->data_len = sizeof(unsigned short int) * elements; + item->data_len = sizeof(guint16) * elements; break; case EXIF_FORMAT_LONG_UNSIGNED: - item->data_len = sizeof(unsigned long int) * elements; + item->data_len = sizeof(guint32) * elements; break; case EXIF_FORMAT_RATIONAL_UNSIGNED: item->data_len = sizeof(ExifRational) * elements; @@ -510,10 +504,10 @@ item->data_len = sizeof(char) * elements; break; case EXIF_FORMAT_SHORT: - item->data_len = sizeof(short int) * elements; + item->data_len = sizeof(gint16) * elements; break; case EXIF_FORMAT_LONG: - item->data_len = sizeof(long int) * elements; + item->data_len = sizeof(gint32) * elements; break; case EXIF_FORMAT_RATIONAL: item->data_len = sizeof(ExifRational) * elements; @@ -596,7 +590,7 @@ return string; } -static gchar *text_list_find_value(ExifTextList *list, gint value) +static gchar *text_list_find_value(ExifTextList *list, guint value) { gchar *result = NULL; gint i; @@ -618,45 +612,42 @@ *------------------------------------------------------------------- */ -static uint16_t get_int16(unsigned char *f, int bo) +guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo) { - if (bo == BYTE_ORDER_INTEL) - return *f + (*(f+1)<<8); + if (bo == EXIF_BYTE_ORDER_INTEL) + return GUINT16_FROM_LE(*(guint16*)f); else - return ((*f)<<8) + *(f+1); + return GUINT16_FROM_BE(*(guint16*)f); } -#if 0 -/* not used ? */ -static uint32_t get_int32(unsigned char *f, int bo) +guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo) { - if (bo == BYTE_ORDER_INTEL) - return get_int16(f, BYTE_ORDER_INTEL) + (get_int16(f+2, BYTE_ORDER_INTEL)<<16); + if (bo == EXIF_BYTE_ORDER_INTEL) + return GUINT32_FROM_LE(*(guint32*)f); else - return (get_int16(f, BYTE_ORDER_MOTOROLA)<<16) + get_int16(f+2, BYTE_ORDER_MOTOROLA); + return GUINT32_FROM_BE(*(guint32*)f); } + +guint16 exif_byte_swab_int16(guint16 n, ExifByteOrder bo) +{ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (bo == EXIF_BYTE_ORDER_MOTOROLA) +#else + if (bo == EXIF_BYTE_ORDER_INTEL) #endif - -static uint16_t swab_int16(uint16_t n, int bo) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - if (bo == BYTE_ORDER_MOTOROLA) -#else - if (bo == BYTE_ORDER_INTEL) -#endif - return n>>8 | n<<8 ; + return GUINT16_SWAP_LE_BE(n); else return n; } -static uint32_t swab_int32(uint32_t n, int bo) +guint32 exif_byte_swab_int32(guint32 n, ExifByteOrder bo) { -#if BYTE_ORDER == LITTLE_ENDIAN - if (bo == BYTE_ORDER_MOTOROLA) +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (bo == EXIF_BYTE_ORDER_MOTOROLA) #else - if (bo == BYTE_ORDER_INTEL) + if (bo == EXIF_BYTE_ORDER_INTEL) #endif - return n<<24 | n>>24 | (n & 0xFF0000)>>8 | (n & 0xFF00)<<8; + return GUINT32_SWAP_LE_BE(n); else return n; } @@ -670,7 +661,7 @@ static int get_marker_size(unsigned char *f) { /* Size is always in Motorola byte order */ - return get_int16(f+2, BYTE_ORDER_MOTOROLA); + return exif_byte_get_int16(f+2, EXIF_BYTE_ORDER_MOTOROLA); } static int goto_next_marker(unsigned char **f, int *size, int *marker) @@ -713,9 +704,9 @@ *------------------------------------------------------------------- */ -static const ExifMarker *exif_marker_from_tag(uint16_t tag, const ExifMarker *list) +static const ExifMarker *exif_marker_from_tag(guint16 tag, const ExifMarker *list) { - int i = 0; + gint i = 0; if (!list) return NULL; @@ -727,18 +718,19 @@ return (list[i].tag == 0 ? NULL : &list[i]); } -static void rational_from_data(ExifRational *r, void *src, int byte_order) +static void rational_from_data(ExifRational *r, void *src, ExifByteOrder byte_order) { - r->num = swab_int32(*(uint32_t*)src, byte_order); - r->den = swab_int32(*(uint32_t*)(src + sizeof(uint32_t)), byte_order); + r->num = exif_byte_swab_int32(*(guint32*)src, byte_order); + r->den = exif_byte_swab_int32(*(guint32*)(src + sizeof(guint32)), byte_order); } -void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_format, int byte_order) +void exif_item_copy_data(ExifItem *item, void *src, guint len, + ExifFormatType src_format, ExifByteOrder byte_order) { - int bs; - int ne; + gint bs; + gint ne; gpointer dest; - int i; + gint i; bs = ExifFormatList[item->format].size; ne = item->elements; @@ -768,7 +760,7 @@ case EXIF_FORMAT_SHORT: for (i = 0; i < ne; i++) { - ((short *)dest)[i] = swab_int16(*(uint16_t*)(src + i * bs), byte_order); + ((guint16 *)dest)[i] = exif_byte_swab_int16(*(guint16*)(src + i * bs), byte_order); } break; case EXIF_FORMAT_LONG_UNSIGNED: @@ -782,14 +774,16 @@ ss = ExifFormatList[src_format].size; for (i = 0; i < ne; i++) { - ((long *)dest)[i] = (long)swab_int16(*(uint16_t*)(src + i * ss), byte_order); + ((gint32 *)dest)[i] = + (gint32)exif_byte_swab_int16(*(guint16*)(src + i * ss), byte_order); } } else { for (i = 0; i < ne; i++) { - ((long *)dest)[i] = swab_int32(*(uint32_t*)(src + i * bs), byte_order); + ((gint32 *)dest)[i] = + exif_byte_swab_int32(*(guint32*)(src + i * bs), byte_order); } } break; @@ -803,7 +797,7 @@ case EXIF_FORMAT_FLOAT: for (i = 0; i < ne; i++) { - ((float *)dest)[i] = swab_int32(*(uint32_t*)(src + i * bs), byte_order); + ((float *)dest)[i] = exif_byte_swab_int32(*(guint32*)(src + i * bs), byte_order); } break; case EXIF_FORMAT_DOUBLE: @@ -818,21 +812,21 @@ } } -static int exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset, - int size, int byte_order, - const ExifMarker *list) +static gint exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, guint offset, + guint size, ExifByteOrder byte_order, + const ExifMarker *list) { IFDEntry *ent = (IFDEntry*)(tiff+offset); - uint32_t swabed_data; + guint32 swabed_data; void *data; - int data_len; + guint data_len; const ExifMarker *marker; ExifItem *item; - ent->tag = swab_int16(ent->tag, byte_order); - ent->format = swab_int16(ent->format, byte_order); - ent->nb = swab_int32(ent->nb, byte_order); - swabed_data = swab_int32(ent->data, byte_order); + ent->tag = exif_byte_swab_int16(ent->tag, byte_order); + ent->format = exif_byte_swab_int16(ent->format, byte_order); + ent->nb = exif_byte_swab_int32(ent->nb, byte_order); + swabed_data = exif_byte_swab_int32(ent->data, byte_order); /* Check tag type. If it does not match, either the format is wrong, * either it is a unknown tag; so it is not really an error. @@ -866,12 +860,14 @@ if (ent->format <= EXIF_FORMAT_DOUBLE) { printf("warning: exif tag %s format mismatch, found %s exif spec requests %s\n", - marker->key, ExifFormatList[ent->format].short_name, ExifFormatList[marker->format].short_name); + marker->key, ExifFormatList[ent->format].short_name, + ExifFormatList[marker->format].short_name); } else { printf("warning: exif tag %s format mismatch, found unknown id %d exif spec requests %d (%s)\n", - marker->key, ent->format, marker->format, ExifFormatList[marker->format].short_name); + marker->key, ent->format, marker->format, + ExifFormatList[marker->format].short_name); } return 0; } @@ -881,7 +877,8 @@ */ if (marker->components > 0 && marker->components != ent->nb) { - printf("warning: exif tag %s has %d elements, exif spec requests %d\n", marker->key, ent->nb, marker->components); + printf("warning: exif tag %s has %d elements, exif spec requests %d\n", + marker->key, ent->nb, marker->components); } data_len = ExifFormatList[marker->format].size * ent->nb; if (data_len > sizeof(ent->data)) @@ -910,7 +907,7 @@ exif_parse_IFD_table(exif, tiff, swabed_data, size, byte_order, list); break; case TAG_EXIFMAKERNOTE: - format_exif_makernote_canon_parse(exif, tiff, swabed_data, size, byte_order); + format_exif_makernote_parse(exif, tiff, swabed_data, size, byte_order); break; } } @@ -918,17 +915,17 @@ return 0; } -int exif_parse_IFD_table(ExifData *exif, - unsigned char *tiff, int offset, - int size, int byte_order, - const ExifMarker *list) +gint exif_parse_IFD_table(ExifData *exif, + unsigned char *tiff, guint offset, + guint size, ExifByteOrder byte_order, + const ExifMarker *list) { - int i, nb_entries; + gint i, nb_entries; /* We should be able to read number of entries in IFD0) */ if (size < offset+2) return -1; - nb_entries = get_int16(tiff+offset, byte_order); + nb_entries = exif_byte_get_int16(tiff+offset, byte_order); /* Entries and next IFD offset must be readable */ if (size < offset+nb_entries*12+4) return -1; @@ -947,9 +944,10 @@ *------------------------------------------------------------------- */ -static int parse_TIFF(ExifData *exif, unsigned char *tiff, int size) +gint exif_parse_TIFF(ExifData *exif, unsigned char *tiff, guint size, ExifMarker *list) { - int byte_order, offset=0; + ExifByteOrder byte_order; + guint offset=0; if (size < sizeof(TIFFHeader)) { @@ -958,30 +956,30 @@ if (strncmp(((TIFFHeader*)tiff)->byte_order, "II", 2) == 0) { - byte_order = BYTE_ORDER_INTEL; + byte_order = EXIF_BYTE_ORDER_INTEL; } else if (strncmp(((TIFFHeader*)tiff)->byte_order, "MM", 2) == 0) { - byte_order = BYTE_ORDER_MOTOROLA; + byte_order = EXIF_BYTE_ORDER_MOTOROLA; } else { return -1; } - if (swab_int16(((TIFFHeader*)tiff)->magic, byte_order) != 0x002A) + if (exif_byte_swab_int16(((TIFFHeader*)tiff)->magic, byte_order) != 0x002A) { return -1; } - offset = swab_int32(((TIFFHeader*)tiff)->IFD_offset, byte_order); + offset = exif_byte_swab_int32(((TIFFHeader*)tiff)->IFD_offset, byte_order); - return exif_parse_IFD_table(exif, tiff, offset, size, byte_order, ExifKnownMarkersList); + return exif_parse_IFD_table(exif, tiff, offset, size, byte_order, list); } -static int parse_JPEG(ExifData *exif, unsigned char *f, int size) +static gint exif_parse_JPEG(ExifData *exif, unsigned char *f, guint size, ExifMarker *list) { - int marker, marker_size; + guint marker, marker_size; if (size<2 || *f!=0xFF || *(f+1)!=MARKER_SOI) { @@ -1007,7 +1005,7 @@ return -2; } - return parse_TIFF(exif, f+10, marker_size-6); + return exif_parse_TIFF(exif, f+10, marker_size-6, list); } static gint map_file(const gchar *path, void **mapping, int *size) @@ -1090,9 +1088,9 @@ exif = g_new0(ExifData, 1); exif->items = NULL; - if ((res = parse_JPEG(exif, (unsigned char *)f, size)) == -2) + if ((res = exif_parse_JPEG(exif, (unsigned char *)f, size, ExifKnownMarkersList)) == -2) { - res = parse_TIFF(exif, (unsigned char *)f, size); + res = exif_parse_TIFF(exif, (unsigned char *)f, size, ExifKnownMarkersList); } if (res != 0) @@ -1101,7 +1099,7 @@ if (format_raw_img_exif_offsets(f, size, NULL, &offset)) { - res = parse_TIFF(exif, (unsigned char*)f + offset, size - offset); + res = exif_parse_TIFF(exif, (unsigned char*)f + offset, size - offset, ExifKnownMarkersList); } } @@ -1180,7 +1178,7 @@ val = (unsigned char)(((signed char *)data)[0]); } - result = text_list_find_value(marker->list, (unsigned short)val); + result = text_list_find_value(marker->list, (guint)val); string = g_string_append(string, result); g_free(result); }