Sat Jun 4 22:24:00 2005 John Ellis <johne@verizon.net>
[geeqie.git] / src / format_raw.c
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);
+}
+
+