Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
authorJohn Ellis <johne@verizon.net>
Sun, 5 Jun 2005 02:48:54 +0000 (02:48 +0000)
committerJohn Ellis <johne@verizon.net>
Sun, 5 Jun 2005 02:48:54 +0000 (02:48 +0000)
        * 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. #####

13 files changed:
ChangeLog
TODO
src/Makefile.am
src/exif.c
src/exif.h
src/format_canon.c
src/format_canon.h
src/format_fuji.c
src/format_fuji.h
src/format_nikon.c [new file with mode: 0644]
src/format_nikon.h [new file with mode: 0644]
src/format_raw.c
src/format_raw.h

index 8c804c6..bbe6630 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+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].
+
 Sat Jun  4 04:02:04 2005  John Ellis  <johne@verizon.net>
 
        * README: Update credits.
diff --git a/TODO b/TODO
index d995598..c752b74 100644 (file)
--- a/TODO
+++ b/TODO
@@ -88,7 +88,7 @@ Minor (non blockers):
    > collection window
    > search window
 
- > clean up exif.c to be portable (don't assume sizeof(short)==2 and sizeof(long)==4)
+d> clean up exif.c to be portable (don't assume sizeof(short)==2 and sizeof(long)==4)
 
 
 Wishlist?:
index a1722f4..555b3b1 100644 (file)
@@ -88,6 +88,8 @@ gqview_SOURCES = \
        format_canon.h  \
        format_fuji.c   \
        format_fuji.h   \
+       format_nikon.c  \
+       format_nikon.h  \
        format_raw.c    \
        format_raw.h    \
        fullscreen.c    \
index 485083d..9eef4e9 100644 (file)
@@ -73,8 +73,6 @@
 #include "format_raw.h"
 #include "ui_fileops.h"
 
-/* makernote parsers */
-#include "format_canon.h"
 
 /*
  *-----------------------------------------------------------------------------
@@ -436,10 +434,6 @@ ExifFormattedText ExifFormattedList[] = {
  *-----------------------------------------------------------------------------
  */
 
-#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 @@ typedef struct __attribute__((packed)) {
 } 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 @@ static const ExifMarker *exif_marker_from_tag(uint16_t tag, const ExifMarker *li
  *-----------------------------------------------------------------------------
  */
 
-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 @@ ExifItem *exif_item_new(ExifFormatType format, unsigned int tag,
                        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 @@ ExifItem *exif_item_new(ExifFormatType format, unsigned int tag,
                        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 @@ static GString *string_append_raw_bytes(GString *string, gpointer data, gint ne)
        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 gchar *text_list_find_value(ExifTextList *list, gint value)
  *-------------------------------------------------------------------
  */
 
-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);
 }
-#endif
 
-static uint16_t swab_int16(uint16_t n, int bo)
+guint16 exif_byte_swab_int16(guint16 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>>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 uint32_t swab_int32(uint32_t n, int bo)
 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 int goto_next_marker(unsigned char **f, int *size, int *marker)
  *-------------------------------------------------------------------
  */
 
-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 @@ static const ExifMarker *exif_marker_from_tag(uint16_t tag, const ExifMarker *li
        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 @@ void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_
                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 @@ void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_
                                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 @@ void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_
                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 @@ void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_
                }
 }
 
-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 @@ static int exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset,
                        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 @@ static int exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset,
         */
        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 @@ static int exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset,
                                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 @@ static int exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset,
        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 @@ int exif_parse_IFD_table(ExifData *exif,
  *-------------------------------------------------------------------
  */
 
-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 @@ static int parse_TIFF(ExifData *exif, unsigned char *tiff, int size)
 
        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 @@ static int parse_JPEG(ExifData *exif, unsigned char *f, int size)
                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 @@ ExifData *exif_read(const gchar *path)
        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 @@ ExifData *exif_read(const gchar *path)
                
                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 @@ gchar *exif_item_get_data_as_text(ExifItem *item)
                                        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);
                                }
index f13828f..f11ea10 100644 (file)
@@ -49,13 +49,18 @@ typedef enum {
        EXIF_FORMAT_DOUBLE              = 12
 } ExifFormatType;
 
+typedef enum {
+       EXIF_BYTE_ORDER_INTEL,
+       EXIF_BYTE_ORDER_MOTOROLA
+} ExifByteOrder;
+
 typedef struct _ExifFormatAttrib ExifFormatAttrib;
 struct _ExifFormatAttrib
 {
        ExifFormatType type;
-       int size;
-       const char *short_name;
-       const char *description;
+       guint size;
+       const gchar *short_name;
+       const gchar *description;
 };
 
 /* the list of known tag data formats */
@@ -77,8 +82,8 @@ struct _ExifData
 typedef struct _ExifRational ExifRational;
 struct _ExifRational
 {
-       unsigned long int num;
-       unsigned long int den;
+       guint32 num;
+       guint32 den;
 };
 
 
@@ -89,20 +94,20 @@ typedef struct _ExifTextList ExifTextList;
 struct _ExifItem
 {
        ExifFormatType format;
-       int tag;
+       guint tag;
        const ExifMarker *marker;
-       int elements;
+       guint elements;
        gpointer data;
-       int data_len;
+       guint data_len;
 };
 
 struct _ExifMarker
 {
-       int             tag;
+       guint           tag;
        ExifFormatType  format;
-       int             components;
-       char            *key;
-       char            *description;
+       gint            components;
+       gchar           *key;
+       gchar           *description;
        ExifTextList    *list;
 };
 
@@ -110,8 +115,8 @@ struct _ExifMarker
 
 struct _ExifTextList
 {
-       int value;
-       const char* description;
+       gint value;
+       const gchar* description;
 };
 
 #define EXIF_TEXT_LIST_END { -1, NULL }
@@ -120,8 +125,8 @@ struct _ExifTextList
 typedef struct _ExifFormattedText ExifFormattedText;
 struct _ExifFormattedText
 {
-       const char *key;
-       const char *description;
+       const gchar *key;
+       const gchar *description;
 };
 
 
@@ -195,15 +200,24 @@ void exif_write_data_list(ExifData *exif, FILE *f, gint human_readable_list);
 
 /* These funcs for use by makernote parsers only */
 
-ExifItem *exif_item_new(ExifFormatType format, unsigned int tag,
-                       unsigned int elements, const ExifMarker *marker);
-void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_format, int byte_order);
+
+guint16 exif_byte_get_int16(unsigned char *f, ExifByteOrder bo);
+guint32 exif_byte_get_int32(unsigned char *f, ExifByteOrder bo);
+guint16 exif_byte_swab_int16(guint16 n, ExifByteOrder bo);
+guint32 exif_byte_swab_int32(guint32 n, ExifByteOrder bo);
+
+ExifItem *exif_item_new(ExifFormatType format, guint tag,
+                       guint elements, const ExifMarker *marker);
+void exif_item_copy_data(ExifItem *item, void *src, guint len,
+                        ExifFormatType src_format, ExifByteOrder byte_order);
 
 gint exif_parse_IFD_table(ExifData *exif,
-                         unsigned char *tiff, int offset,
-                         int size, int byte_order,
+                         unsigned char *tiff, guint offset,
+                         guint size, ExifByteOrder byte_order,
                          const ExifMarker *list);
 
+gint exif_parse_TIFF(ExifData *exif, unsigned char *tiff, guint size, ExifMarker *list);
 
 
 #endif
+
index 03f1926..bdc632a 100644 (file)
@@ -251,8 +251,8 @@ return_only:
 }
 
 
-gint format_raw_test_canon(const void *data, const guint len,
-                          guint *image_offset, guint *exif_offset)
+gint format_canon_raw(const void *data, const guint len,
+                     guint *image_offset, guint *exif_offset)
 {
 
 
@@ -478,13 +478,6 @@ return_only:
  *-----------------------------------------------------------------------------
  */
 
-typedef struct _CanonTag CanonTag;
-struct _CanonTag {
-       guint id;
-       const gchar *description;
-       ExifTextList *list;
-};
-
 static ExifTextList CanonSet1MacroMode[] = {
        { 1,    "macro" },
        { 2,    "normal" },
@@ -728,21 +721,27 @@ static ExifTextList CanonCustomShutterCurtainSync[] = {
        EXIF_TEXT_LIST_END
 };
 
-static CanonTag CanonCustom[] = {
-       { 1,    "Noise reduction",              CanonCustomEnable },
-/*     { 2,    "Shutter/Auto Exposure Button Function", CanonCustomBTNShutter }, */
-       { 3,    "Mirror lockup",                CanonCustomEnable },
-       { 4,    "Tv/Av and exposure level",     CanonCustomExposureLevel },
-       { 5,    "AF assist light",              CanonCustomEnableInvert },
-       { 6,    "Shutter speed in Av mode",     CanonCustomAVShutterSpeed },
-/*     { 7,    "Auto-Exposure bracketting sequence/auto cancellation", CanonCustom }, */
-       { 8,    "Shutter sync",                 CanonCustomShutterCurtainSync },
-/*     { 9,    "AF button function",           CanonCustom }, */
-       { 10,   "Fill flash auto reduction",    CanonCustomEnableInvert },
-/*     { 11,   "Menu button function",         CanonCustom }, */
-/*     { 12,   "Set button function",          CanonCustom }, */
-       { 13,   "Sensor cleaning",              CanonCustomEnable },
-       { 0,    NULL, NULL }
+static ExifMarker CanonCustom[] = {
+{ 1,   EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.NoiseReduction", "Noise reduction",  CanonCustomEnable },
+/*{ 2, EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.BtnFuncShutter",
+                                               "Shutter/Auto exposure button function",CanonCustomBTNShutter }, */
+{ 3,   EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.MirrorLockup", "Mirror lockup",      CanonCustomEnable },
+{ 4,   EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.TvAvExposureLevel",
+                                                       "Tv/Av and exposure level",     CanonCustomExposureLevel },
+{ 5,   EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.AFAssistLight", "AF assist light",   CanonCustomEnableInvert },
+{ 6,   EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.AvShutterSpeed",
+                                                       "Shutter speed in Av mode",     CanonCustomAVShutterSpeed },
+/*{ 7, EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.AutoBracket",
+                               "Auto-Exposure bracketting sequence/auto cancellation", CanonCustom }, */
+{ 8,   EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.ShutterSync", "Shutter sync",        CanonCustomShutterCurtainSync },
+/* { 9,        EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.BtnFuncAF",  "AF button function",   CanonCustom }, */
+{ 10,  EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.FillFlashReduction",
+                                                       "Fill flash auto reduction",    CanonCustomEnableInvert },
+/*{ 11,        EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.BtnFuncMenu",
+                                                       "Menu button function",         CanonCustom }, */
+/*{ 12,        EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.BtnFuncSet", "Set button function",  CanonCustom }, */
+{ 13,  EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Canon.SensorCleaning", "Sensor cleaning",  CanonCustomEnable },
+EXIF_MARKER_LIST_END
 };
 
 #endif
@@ -760,7 +759,7 @@ static ExifMarker CanonExifMarkersList[] = {
 };
 
 static void canon_mknote_parse_settings(ExifData *exif,
-                                       guint16 *data, guint32 len, int byte_order,
+                                       guint16 *data, guint32 len, ExifByteOrder byte_order,
                                        ExifMarker *list)
 {
        gint i;
@@ -825,19 +824,12 @@ static void canon_mknote_parse_convert(ExifData *exif)
 }
 #endif
 
-gint format_exif_makernote_canon_parse(ExifData *exif, unsigned char *tiff, int offset,
-                                      int size, int byte_order)
+gint format_canon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                           guint size, ExifByteOrder byte_order)
 {
        ExifItem *item;
-       gchar *text;
-       gint found;
-
-       text = exif_get_data_as_text(exif, "Make");
-       found = (text && strncasecmp(text, "Canon", 5) == 0);
-       g_free(text);
 
-       if (!found ||
-           exif_parse_IFD_table(exif, tiff, offset, size, byte_order, CanonExifMarkersList) != 0)
+       if (exif_parse_IFD_table(exif, tiff, offset, size, byte_order, CanonExifMarkersList) != 0)
                {
                return FALSE;
                }
index 61eaef2..987de1e 100644 (file)
  *
  */
 
-#ifndef __FORMAT_RAW_CANON_H
-#define __FORMAT_RAW_CANON_H
+#ifndef __FORMAT_CANON_H
+#define __FORMAT_CANON_H
 
 
 #include "exif.h"
 
 
-gint format_raw_test_canon(const void *data, const guint len,
-                          guint *image_offset, guint *exif_offset);
+gint format_canon_raw(const void *data, const guint len,
+                     guint *image_offset, guint *exif_offset);
 
 
-#define FORMAT_RAW_CANON { "II", 2, "Canon crw format", format_raw_test_canon }, \
-                        { "\x49\x49\x2a\00", 4, "Canon cr2 format", format_raw_test_canon }
+#define FORMAT_RAW_CANON { "II", 2, "Canon crw format", format_canon_raw }, \
+                        { "\x49\x49\x2a\00", 4, "Canon cr2 format", format_canon_raw }
 
 
-gint format_exif_makernote_canon_parse(ExifData *exif, unsigned char *tiff, int offset,
-                                      int size, int byte_order);
+gint format_canon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                           guint size, ExifByteOrder byte_order);
+
+#define FORMAT_EXIF_CANON { FORMAT_EXIF_MATCH_MAKE, "Canon", 5, format_canon_makernote }
 
 
 #endif
index 5395f11..f2d73c0 100644 (file)
 #include "format_fuji.h"
 #include "format_raw.h"
 
+#include "exif.h"
 
-gint format_raw_test_fuji(const void *data, const guint len,
-                         guint *image_offset, guint *exif_offset)
+
+gint format_fuji_raw(const void *data, const guint len,
+                    guint *image_offset, guint *exif_offset)
 {
        guint io;
        guint eo;
@@ -57,3 +59,130 @@ gint format_raw_test_fuji(const void *data, const guint len,
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ * EXIF Makernote for Fujifilm
+ *-----------------------------------------------------------------------------
+ */
+
+static ExifTextList FujiTagSharpness[] = {
+       { 1,    "soft" },
+       { 2,    "soft" },
+       { 3,    "normal" },
+       { 4,    "hard" },
+       { 5,    "hard" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagWhiteBalance[]= {
+       { 0,    "auto" },
+       { 256,  "daylight" },
+       { 512,  "cloudy" },
+       { 768,  "daylight color-fluorescence" },
+       { 769,  "daywhite color-fluorescence" },
+       { 770,  "white-fluorescence" },
+       { 1024, "incandescent" },
+       { 3840, "custom" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagColorTone[]= {
+       { 0,    "normal" },
+       { 256,  "high" },
+       { 512,  "low" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagFlashMode[]= {
+       { 0,    "auto" },
+       { 1,    "on" },
+       { 2,    "off" },
+       { 3,    "red-eye reduction" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagOffOn[]= {
+       { 0,    "off" },
+       { 1,    "on" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagFocusMode[]= {
+       { 0,    "auto" },
+       { 1,    "manual" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagPictureMode[]= {
+       { 0,    "auto" },
+       { 1,    "portrait" },
+       { 2,    "landscape" },
+       { 4,    "sports" },
+       { 5,    "night" },
+       { 6,    "program AE" },
+       { 256,  "aperture priority AE" },
+       { 512,  "shutter priority AE" },
+       { 768,  "manual" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList FujiTagNoYes[]= {
+       { 0,    "no" },
+       { 1,    "yes" },
+       EXIF_TEXT_LIST_END
+};
+
+#if 0
+static ExifTextList FujiTag[]= {
+       { ,     "" },
+       { ,     "" },
+       EXIF_TEXT_LIST_END
+};
+#endif
+
+
+static ExifMarker FujiExifMarkersList[] = {
+{ 0x1000,      EXIF_FORMAT_STRING, 8,          "MkN.Fuji.Quality",     "Quality",      NULL },
+{ 0x1001,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.Sharpness",   "Sharpness",    FujiTagSharpness },
+{ 0x1002,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.WhiteBalance","White balance",FujiTagWhiteBalance },
+{ 0x1003,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.Color",       "Color",        FujiTagColorTone },
+{ 0x1004,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.Tone",        "Tone",         FujiTagColorTone },
+{ 0x1010,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.FlashMode",   "Flash mode",   FujiTagFlashMode },
+{ 0x1011,      EXIF_FORMAT_RATIONAL, 1,        "MkN.Fuji.FlashStrength", "Flash strength", NULL },
+{ 0x1020,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.Macro",       "Macro",        FujiTagOffOn },
+{ 0x1021,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.FocusMode",   "Focus mode",   FujiTagFocusMode },
+{ 0x1030,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.SlowSync",    "Slow synchro", FujiTagOffOn },
+{ 0x1031,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.PictureMode", "Picture mode", FujiTagPictureMode },
+{ 0x1100,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.ContTake/Bracket",
+                                                       "Continuous / Auto bracket",    FujiTagOffOn },
+{ 0x1300,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.BlurWarning", "Blue warning", FujiTagNoYes },
+{ 0x1301,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.FocusWarning","Focus warning",FujiTagNoYes },
+{ 0x1302,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "MkN.Fuji.AEWarning",   "AE warning",   FujiTagNoYes },
+EXIF_MARKER_LIST_END
+};
+
+
+
+gint format_fuji_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                          guint size, ExifByteOrder byte_order)
+{
+       unsigned char *data;
+       guint ifdstart;
+
+       if (offset + 8 + 4 >= size) return FALSE;
+
+       data = tiff + offset;
+       if (memcmp(data, "FUJIFILM", 8) != 0) return FALSE;
+
+       ifdstart = exif_byte_get_int32(data + 8, EXIF_BYTE_ORDER_INTEL);
+       if (offset + ifdstart >= size) return FALSE;
+
+       if (exif_parse_IFD_table(exif, tiff + offset, ifdstart, size - offset,
+                                EXIF_BYTE_ORDER_INTEL, FujiExifMarkersList) != 0)
+               {
+               return FALSE;
+               }
+
+       return TRUE;
+}
+
index d4c7e4a..467a689 100644 (file)
  * This software comes with no warranty of any kind, use at your own risk!
  */
 
-#ifndef __FORMAT_RAW_FUJI_H
-#define __FORMAT_RAW_FUJI_H
+#ifndef __FORMAT_FUJI_H
+#define __FORMAT_FUJI_H
 
 
-gint format_raw_test_fuji(const void *data, const guint len,
-                         guint *image_offset, guint *exif_offset);
+#include "exif.h"
 
 
-#define FORMAT_RAW_FUJI { "FUJIFILM", 8, "Fuji raw format", format_raw_test_fuji }
+gint format_fuji_raw(const void *data, const guint len,
+                    guint *image_offset, guint *exif_offset);
+
+
+#define FORMAT_RAW_FUJI { "FUJIFILM", 8, "Fuji raw format", format_fuji_raw }
+
+
+gint format_fuji_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                          guint size, ExifByteOrder byte_order);
+
+#define FORMAT_EXIF_FUJI { FORMAT_EXIF_MATCH_MAKERNOTE, "FUJIFILM", 8, format_fuji_makernote }
+
 
 
 #endif
diff --git a/src/format_nikon.c b/src/format_nikon.c
new file mode 100644 (file)
index 0000000..60ec3cc
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ *  GQView
+ *  (C) 2005 John Ellis
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "intl.h"
+
+#include "format_nikon.h"
+
+#include "exif.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXIF Makernote for Nikon
+ *-----------------------------------------------------------------------------
+ */
+
+static ExifTextList NikonTagQuality[]= {
+       { 1,    "VGA basic" },
+       { 2,    "VGA normal" },
+       { 3,    "VGA fine" },
+       { 4,    "SXGA basic" },
+       { 5,    "SXGA normal" },
+       { 6,    "SXGA fine" },
+       { 7,    "XGA basic (?)" },
+       { 8,    "XGA normal (?)" },
+       { 9,    "XGA fine (?)" },
+       { 10,   "UXGA basic" },
+       { 11,   "UXGA normal" },
+       { 12,   "UXGA fine" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList NikonTagColorMode[]= {
+       { 1,    "color" },
+       { 2,    "monochrome" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList NikonTagImgAdjust[]= {
+       { 0,    "normal" },
+       { 1,    "bright+" },
+       { 2,    "bright-" },
+       { 3,    "contrast+" },
+       { 4,    "contrast-" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList NikonTagISOSensitivity[]= {
+       { 0,    "80" },
+       { 2,    "160" },
+       { 4,    "320" },
+       { 5,    "100" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList NikonTagWhiteBalance[]= {
+       { 0,    "auto" },
+       { 1,    "preset" },
+       { 2,    "daylight" },
+       { 3,    "incandescent" },
+       { 4,    "fluorescence" },
+       { 5,    "cloudy" },
+       { 6,    "speedlight" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList NikonTagConverter[]= {
+       { 0,    "none" },
+       { 1,    "Fisheye" },
+       EXIF_TEXT_LIST_END
+};
+
+#if 0
+static ExifTextList NikonTag[]= {
+       { ,     "" },
+       { ,     "" },
+       EXIF_TEXT_LIST_END
+};
+#endif
+
+static ExifMarker NikonExifMarkersList1[] = {
+{ 0x0002, EXIF_FORMAT_STRING, 6,               "MkN.Nikon.unknown",    NULL,           NULL },
+{ 0x0003, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.Quality",    "Quality",      NikonTagQuality },
+{ 0x0004, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.ColorMode",  "Color mode",   NikonTagColorMode },
+{ 0x0005, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.ImageAdjustment",
+                                                               "Image adjustment",     NikonTagImgAdjust },
+{ 0x0006, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.ISOSensitivity",
+                                                               "ISO sensitivity",      NikonTagISOSensitivity },
+{ 0x0007, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.WhiteBalance",
+                                                               "White balance",        NikonTagWhiteBalance },
+{ 0x0008, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,    "MkN.Nikon.Focus",      "Focus",        NULL },
+{ 0x000a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,    "MkN.Nikon.DigitalZoom","Digital zoom", NULL },
+{ 0x000b, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.Converter",  "Converter",    NikonTagConverter },
+EXIF_MARKER_LIST_END
+};
+
+static ExifTextList NikonTag2FlashComp[]= {
+       { 0x06, "+1.0 EV" },
+       { 0x04, "+0.7 EV" },
+       { 0x03, "+0.5 EV" },
+       { 0x02, "+0.3 EV" },
+       { 0x00, "0.0 EV" },
+       { 0xfe, "-0.3 EV" },
+       { 0xfd, "-0.5 EV" },
+       { 0xfc, "-0.7 EV" },
+       { 0xfa, "-1.0 EV" },
+       { 0xf8, "-1.3 EV" },
+       { 0xf7, "-1.5 EV" },
+       { 0xf6, "-1.7 EV" },
+       { 0xf4, "-2.0 EV" },
+       { 0xf2, "-2.3 EV" },
+       { 0xf1, "-2.5 EV" },
+       { 0xf0, "-2.7 EV" },
+       { 0xee, "-3.0 EV" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList NikonTag2FlashUsed[]= {
+       { 0,    "no" },
+       { 9,    "yes" },
+       EXIF_TEXT_LIST_END
+};
+
+#if 0
+static ExifTextList NikonTagi2Saturation[]= {
+       { -3,   "black and white" },
+       { -2,   "-2" },
+       { -1,   "-1" },
+       { 0,    "normal" },
+       { 1,    "+1" },
+       { 2,    "+2" },
+       EXIF_TEXT_LIST_END
+};
+#endif
+
+static ExifMarker NikonExifMarkersList2[] = {
+{ 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 2,       "MkN.Nikon.ISOSpeed",   "ISO speed",    NULL },
+{ 0x0003, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.ColorMode",  "Color mode",   NULL },
+{ 0x0004, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.Quality",    "Quality",      NULL },
+{ 0x0005, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.WhiteBalance",
+                                                               "White balance",        NULL },
+{ 0x0006, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.Sharpening", "Sharpening",   NULL },
+{ 0x0007, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.FocusMode",  "Focus mode",   NULL },
+{ 0x0008, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.FlashSetting",
+                                                               "Flash setting",        NULL },
+{ 0x0009, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.AutoFlashMode","Auto flash mode",NULL },
+{ 0x000b, EXIF_FORMAT_SHORT, 1,                        "MkN.Nikon.WhiteBalanceBias",
+                                                       "White balance bias value",     NULL },
+/* { 0x000c, EXIF_FORMAT_SHORT_UNSIGNED, 1,    "MkN.Nikon.WhiteBalanceCoeff",
+                                               "White balance red/blue coefficents",   NULL }, */
+/* { 0x000f, EXIF_FORMAT_STRING, -1,           "MkN.Nikon.ISOSelect",  "ISO selection",NULL }, */
+{ 0x0012, EXIF_FORMAT_UNDEFINED, 4,            "MkN.Nikon.FlashCompensation",
+                                                               "Flash compensation",   NikonTag2FlashComp },
+{ 0x0013, EXIF_FORMAT_SHORT_UNSIGNED, 2,       "MkN.Nikon.ISOSpeedRequest",
+                                                               "ISO speed requested",  NULL },
+{ 0x0016, EXIF_FORMAT_SHORT_UNSIGNED, 4,       "MkN.Nikon.CornerCoord",
+                                                               "Corner coordinates",   NULL },
+{ 0x0018, EXIF_FORMAT_UNDEFINED, 4,            "MkN.Nikon.FlashBracketCompensation",
+                                                       "Flash bracket compensation",   NikonTag2FlashComp },
+{ 0x0019, EXIF_FORMAT_RATIONAL, 1,             "MkN.Nikon.AEBracketCompensation",
+                                                       "AE bracket compensation",      NULL },
+{ 0x0080, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.ImageAdjustment",
+                                                               "Image adjustment",     NULL },
+{ 0x0081, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.Contrast",   "Contrast",     NULL },
+{ 0x0082, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.AuxLens","Aux lens adapter", NULL },
+{ 0x0083, EXIF_FORMAT_BYTE_UNSIGNED, -1,       "MkN.Nikon.LensType",   "Lens type",    NULL },
+{ 0x0084, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,   "MkN.Nikon.LensFocalLength",
+                                                       "Lens min/max focal length and aperture", NULL },
+{ 0x0085, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.ManualFocusDistance",
+                                                       "Manual focus distance",        NULL },
+{ 0x0086, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.DigitalZoomFactor",
+                                                       "Digital zoom facotr",          NULL },
+{ 0x0087, EXIF_FORMAT_BYTE_UNSIGNED, 1,                "MkN.Nikon.FlashUsed",  "Flash used",   NikonTag2FlashUsed },
+{ 0x0088, EXIF_FORMAT_UNDEFINED, -1,           "MkN.Nikon.AutoFocusArea", NULL,        NULL },
+/* { 0x0089, EXIF_FORMAT_SHORT_UNSIGNED, -1,   "MkN.Nikon.Bracket/ShootingMode", NULL, NULL }, */
+{ 0x008d, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.ColorMode",  "Color mode",   NULL },
+{ 0x008f, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.SceneMode",  NULL,           NULL },
+{ 0x0090, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.LightingType", "Lighting type", NULL },
+{ 0x0092, EXIF_FORMAT_SHORT, 1,                        "MkN.Nikon.HueAdjust",  "Hue adjustment", NULL },
+/* { 0x0094, EXIF_FORMAT_SHORT_UNSIGNED, 1,    "MkN.Nikon.Saturation", "Saturation",   NikonTag2Saturation }, */
+{ 0x0095, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.NoiseReduction", "Noise reduction", NULL },
+{ 0x00a7, EXIF_FORMAT_LONG_UNSIGNED, 1,                "MkN.Nikon.ShutterCount", "Shutter release count", NULL },
+{ 0x00a9, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.ImageOptimization", "Image optimization", NULL },
+{ 0x00aa, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.Saturation", "Saturation",   NULL },
+{ 0x00ab, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.DigitalVariProg", "Digital Vari-program", NULL },
+EXIF_MARKER_LIST_END
+};
+
+
+gint format_nikon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                           guint size, ExifByteOrder byte_order)
+{
+       unsigned char *data;
+
+       if (offset + 8 + 4 >= size) return FALSE;
+
+       data = tiff + offset;
+       if (memcmp(data, "Nikon\x00\x01\x00", 8) == 0)
+               {
+               if (exif_parse_IFD_table(exif, tiff, offset + 8, size,
+                                        byte_order, NikonExifMarkersList1) != 0)
+                       {
+                       return FALSE;
+                       }
+               return TRUE;
+               }
+
+       if (memcmp(data, "Nikon\x00\x02\x00\x00\x00", 10) == 0 ||
+           memcmp(data, "Nikon\x00\x02\x10\x00\x00", 10) == 0)
+               {
+               guint tiff_header;
+
+               tiff_header = offset + 10;
+               if (exif_parse_TIFF(exif, tiff + tiff_header, size - tiff_header,
+                   NikonExifMarkersList2) != 0)
+                       {
+                       return FALSE;
+                       }
+               return TRUE;
+               }
+
+       /* fixme: support E990 and D1 */
+       if (exif_parse_IFD_table(exif, tiff, offset, size,
+                                byte_order, NikonExifMarkersList2) != 0)
+               {
+               return FALSE;
+               }
+
+       return FALSE;
+}
+
diff --git a/src/format_nikon.h b/src/format_nikon.h
new file mode 100644 (file)
index 0000000..1988750
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  GQView
+ *  (C) 2005 John Ellis
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#ifndef __FORMAT_NIKON_H
+#define __FORMAT_NIKON_H
+
+
+#include "exif.h"
+
+
+gint format_nikon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                           guint size, ExifByteOrder byte_order);
+
+#define FORMAT_EXIF_NIKON { FORMAT_EXIF_MATCH_MAKERNOTE, "Nikon\x00", 6, format_nikon_makernote }, \
+                         { FORMAT_EXIF_MATCH_MAKE,      "NIKON",     5, format_nikon_makernote }
+
+
+#endif
+
index ce62c55..86c6dd9 100644 (file)
 
 #include "format_canon.h"
 #include "format_fuji.h"
+#include "format_nikon.h"
 
 
-typedef struct _FormatEntry FormatEntry;
-struct _FormatEntry {
+typedef struct _FormatRawEntry FormatRawEntry;
+struct _FormatRawEntry {
        const void *header_pattern;
        const guint header_length;
        const gchar *description;
        FormatRawParseFunc func_parse;
 };
 
-
-static FormatEntry format_list[] = {
+static FormatRawEntry format_raw_list[] = {
        FORMAT_RAW_CANON,
        FORMAT_RAW_FUJI,
        { NULL, 0, NULL, NULL }
 };
 
 
-static FormatEntry *format_raw_find(const void *data, const guint len)
+typedef struct _FormatExifEntry FormatExifEntry;
+struct _FormatExifEntry {
+       FormatExifMatchType header_type;
+       const void *header_pattern;
+       const guint header_length;
+       FormatExifParseFunc func_parse;
+};
+
+static FormatExifEntry format_exif_list[] = {
+       FORMAT_EXIF_CANON,
+       FORMAT_EXIF_FUJI,
+       FORMAT_EXIF_NIKON,
+       { 0, NULL, 0, NULL }
+};
+
+
+static FormatRawEntry *format_raw_find(const void *data, const guint len)
 {
        gint n;
 
        n = 0;
-       while (format_list[n].header_pattern)
+       while (format_raw_list[n].header_pattern)
                {
-               if (format_list[n].header_length <= len &&
-                   memcmp(data, format_list[n].header_pattern, format_list[n].header_length) == 0)
+               if (format_raw_list[n].header_length <= len &&
+                   memcmp(data, format_raw_list[n].header_pattern, format_raw_list[n].header_length) == 0)
                        {
-                       return &format_list[n];
+                       return &format_raw_list[n];
                        }
                n++;
                }
@@ -66,7 +82,7 @@ static FormatEntry *format_raw_find(const void *data, const guint len)
        return NULL;
 }
 
-static gint format_raw_parse(FormatEntry *entry,
+static gint format_raw_parse(FormatRawEntry *entry,
                             const void *data, const guint len,
                             guint *image_offset, guint *exif_offset)
 {
@@ -94,7 +110,7 @@ static gint format_raw_parse(FormatEntry *entry,
 gint format_raw_img_exif_offsets(const void *data, const guint len,
                                 guint *image_offset, guint *exif_offset)
 {
-       FormatEntry *entry;
+       FormatRawEntry *entry;
 
        if (!data || len < 1) return FALSE;
 
@@ -109,7 +125,7 @@ gint format_raw_img_exif_offsets(const void *data, const guint len,
 gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint header_len,
                                    guint *image_offset, guint *exif_offset)
 {
-       FormatEntry *entry;
+       FormatRawEntry *entry;
        void *map_data = NULL;
        size_t map_len = 0;
        struct stat st;
@@ -157,3 +173,53 @@ gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint
 }
 
 
+static FormatExifEntry *format_exif_makernote_find(ExifData *exif, unsigned char *tiff,
+                                                  guint offset, guint size)
+{
+       ExifItem *make;
+       gint n;
+
+       make = exif_get_item(exif, "Make");
+
+       n = 0;
+       while (format_exif_list[n].header_pattern)
+               {
+               switch (format_exif_list[n].header_type)
+                       {
+                       case FORMAT_EXIF_MATCH_MAKERNOTE:
+                               if (format_exif_list[n].header_length + offset < size &&
+                                   memcmp(tiff + offset, format_exif_list[n].header_pattern,
+                                                         format_exif_list[n].header_length) == 0)
+                                       {
+                                       return &format_exif_list[n];
+                                       }
+                               break;
+                       case FORMAT_EXIF_MATCH_MAKE:
+                               if (make &&
+                                   make->data_len >= format_exif_list[n].header_length &&
+                                   memcmp(make->data, format_exif_list[n].header_pattern,
+                                                      format_exif_list[n].header_length) == 0)
+                                       {
+                                       return &format_exif_list[n];
+                                       }
+                               break;
+                       }
+               n++;
+               }
+
+       return FALSE;
+}
+
+gint format_exif_makernote_parse(ExifData *exif, unsigned char *tiff, guint offset,
+                                guint size, ExifByteOrder byte_order)
+{
+       FormatExifEntry *entry;
+
+       entry = format_exif_makernote_find(exif, tiff, offset, size);
+
+       if (!entry || !entry->func_parse) return FALSE;
+
+       return entry->func_parse(exif, tiff, offset, size, byte_order);
+}
+
+
index 2c1609c..5c6c963 100644 (file)
 #define __FORMAT_RAW_H
 
 
+#include "exif.h"
+
+
 typedef gint (* FormatRawParseFunc)(const void *data, const guint len,
                                    guint *image_offset, guint *exif_offset);
 
-
 gint format_raw_img_exif_offsets(const void *data, const guint len,
                                 guint *image_offset, guint *exif_offset);
 gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint header_len,
                                    guint *image_offset, guint *exif_offset);
 
 
+typedef enum {
+       FORMAT_EXIF_MATCH_MAKE,
+       FORMAT_EXIF_MATCH_MAKERNOTE
+} FormatExifMatchType;
+
+typedef gint (* FormatExifParseFunc)(ExifData *exif, unsigned char *tiff, guint offset,
+                                   guint size, ExifByteOrder byte_order);
+
+gint format_exif_makernote_parse(ExifData *exif, unsigned char *tiff, guint offset,
+                                guint size, ExifByteOrder byte_order);
+
+
 #endif