Fri Jun 10 20:57:42 2005 John Ellis <johne@verizon.net>
authorJohn Ellis <johne@verizon.net>
Sat, 11 Jun 2005 01:09:30 +0000 (01:09 +0000)
committerJohn Ellis <johne@verizon.net>
Sat, 11 Jun 2005 01:09:30 +0000 (01:09 +0000)
        * exif.c (exif_parse_IFD_table): Fix offset count before testing
        against buffer size.
        * exif.h: Make exif_text_list_find_value available.
        * format_canon.c: Fix copy's length when duping Canon.SerialNumber, and
        adjust several text descriptions.
        * format_fuji.c: Remove "MkN." text from tag names.
        * format_nikon.c: Fix offset count before testing against buffer size,
        and remove "MkN." text from tag names. Add several new tags.
        * format_olympus.[ch]: New files for olympus makernote.
        * format_raw.c: Add exif olympus hook.
        * src/Makefile.am: Add format_olympus.[ch].

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

index 575d32a..f694a4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Fri Jun 10 20:57:42 2005  John Ellis  <johne@verizon.net>
+
+       * exif.c (exif_parse_IFD_table): Fix offset count before testing
+       against buffer size.
+       * exif.h: Make exif_text_list_find_value available.
+       * format_canon.c: Fix copy's length when duping Canon.SerialNumber, and
+       adjust several text descriptions.
+       * format_fuji.c: Remove "MkN." text from tag names.
+       * format_nikon.c: Fix offset count before testing against buffer size,
+       and remove "MkN." text from tag names. Add several new tags.
+       * format_olympus.[ch]: New files for olympus makernote.
+       * format_raw.c: Add exif olympus hook.
+       * src/Makefile.am: Add format_olympus.[ch].
+
 Fri Jun 10 02:19:26 2005  John Ellis  <johne@verizon.net>
 
        * pan-view.c: Add exif date sorting option to right click menu, and
diff --git a/TODO b/TODO
index b2f726d..b3e996c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -33,8 +33,8 @@ Major:
       > canon_read_int can be substituted with, or wrap exif_get_int16/32.
       > CR2 tiff code can now use exif_tiff_directory_offset.
 
-   > support olympus MakerNote, investigate RAW
-   > support konica / minolta MakerNote, investigate RAW
+  d> support olympus MakerNote, investigate RAW (raw embedded jpeg appears to be tiny).
+   > support konica / minolta MakerNote, investigate RAW.
 
    > exif.c parser should not be using EXIF tags during tiff directory search for EXIF tag.
 
index 555b3b1..e10659a 100644 (file)
@@ -90,6 +90,8 @@ gqview_SOURCES = \
        format_fuji.h   \
        format_nikon.c  \
        format_nikon.h  \
+       format_olympus.c        \
+       format_olympus.h        \
        format_raw.c    \
        format_raw.h    \
        fullscreen.c    \
index 03918df..fb9b06b 100644 (file)
@@ -562,7 +562,7 @@ static GString *string_append_raw_bytes(GString *string, gpointer data, gint ne)
        return string;
 }
 
-static gchar *text_list_find_value(ExifTextList *list, guint value)
+gchar *exif_text_list_find_value(ExifTextList *list, guint value)
 {
        gchar *result = NULL;
        gint i;
@@ -865,10 +865,10 @@ gint exif_parse_IFD_table(ExifData *exif,
        if (size < offset + 2) return -1;
 
        count = exif_byte_get_int16(tiff + offset, bo);
+       offset += 2;
 
        /* Entries and next IFD offset must be readable */
        if (size < offset + count * EXIF_TIFD_SIZE + 4) return -1;
-       offset += 2;
 
        for (i = 0; i < count; i++)
                {
@@ -1181,7 +1181,7 @@ gchar *exif_item_get_data_as_text(ExifItem *item)
                                        val = (unsigned char)(((signed char *)data)[0]);
                                        }
 
-                               result = text_list_find_value(marker->list, (guint)val);
+                               result = exif_text_list_find_value(marker->list, (guint)val);
                                string = g_string_append(string, result);
                                g_free(result);
                                }
@@ -1198,7 +1198,7 @@ gchar *exif_item_get_data_as_text(ExifItem *item)
                                {
                                gchar *result;
 
-                               result = text_list_find_value(marker->list, ((unsigned short *)data)[0]);
+                               result = exif_text_list_find_value(marker->list, ((unsigned short *)data)[0]);
                                string = g_string_append(string, result);
                                g_free(result);
                                }
@@ -1493,7 +1493,7 @@ static gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *
                if (!exif_get_integer(exif, "Flash", &n)) return NULL;
 
                /* Exif 2.1 only defines first 3 bits */
-               if (n <= 0x07) return g_strdup(text_list_find_value(ExifFlashList, n));
+               if (n <= 0x07) return g_strdup(exif_text_list_find_value(ExifFlashList, n));
 
                /* must be Exif 2.2 */
                string = g_string_new("");
index 3f313b6..f8783df 100644 (file)
@@ -231,6 +231,8 @@ gint exif_tiff_directory_offset(unsigned char *data, const guint len,
                                guint *offset, ExifByteOrder *bo);
 gint exif_tiff_parse(ExifData *exif, unsigned char *tiff, guint size, ExifMarker *list);
 
+gchar *exif_text_list_find_value(ExifTextList *list, guint value);
+
 
 #endif
 
index e4ac637..31abfc4 100644 (file)
@@ -505,14 +505,14 @@ static ExifTextList CanonSet1FlashMode[] = {
        { 2,    "on" },
        { 3,    "red-eye reduction" },
        { 4,    "slow sync" },
-       { 5,    "red-eye reduction (auto)" },
-       { 6,    "red-eye reduction (on)" },
+       { 5,    "auto + red-eye reduction" },
+       { 6,    "on + red-eye reduction" },
        { 16,   "external flash" },
        EXIF_TEXT_LIST_END
 };
 
 static ExifTextList CanonSet1DriveMode[] = {
-       { 0,    "single" },
+       { 0,    "single or timer" },
        { 1,    "continuous" },
        EXIF_TEXT_LIST_END
 };
@@ -548,7 +548,7 @@ static ExifTextList CanonSet1ShootingMode[] = {
        { 8,    "portrait" },
        { 9,    "sports" },
        { 10,   "macro" },
-       { 11,   "panoramic focus" },
+       { 11,   "pan focus" },
        EXIF_TEXT_LIST_END
 };
 
@@ -663,7 +663,7 @@ EXIF_MARKER_LIST_END
 
 static ExifTextList CanonSet2WhiteBalance[] = {
        { 0,    "auto" },
-       { 1,    "daylight" },
+       { 1,    "sunny" },
        { 2,    "cloudy" },
        { 3,    "tungsten" },
        { 4,    "fluorescent" },
@@ -834,7 +834,7 @@ static void canon_mknote_parse_convert(ExifData *exif)
 
                n = (guint32)((guint32 *)(result->data))[0];
                text = g_strdup_printf("%04X%05d", n & 0xffff0000 >> 8, n & 0x0000ffff);
-               l = strlen(text);
+               l = strlen(text) + 1;
                item = exif_item_new(marker.format, marker.tag, l, &marker);
                memcpy(item->data, text, l);
                g_free(text);
index 53e9fe4..6eef366 100644 (file)
@@ -149,22 +149,22 @@ static ExifTextList FujiTag[]= {
 
 
 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",
+{ 0x1000,      EXIF_FORMAT_STRING, 8,          "Fuji.Quality",         "Quality",      NULL },
+{ 0x1001,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Sharpness",       "Sharpness",    FujiTagSharpness },
+{ 0x1002,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.WhiteBalance",    "White balance",FujiTagWhiteBalance },
+{ 0x1003,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Color",           "Color",        FujiTagColorTone },
+{ 0x1004,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Tone",            "Tone",         FujiTagColorTone },
+{ 0x1010,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.FlashMode",       "Flash mode",   FujiTagFlashMode },
+{ 0x1011,      EXIF_FORMAT_RATIONAL, 1,        "Fuji.FlashStrength",   "Flash strength", NULL },
+{ 0x1020,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.Macro",           "Macro",        FujiTagOffOn },
+{ 0x1021,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.FocusMode",       "Focus mode",   FujiTagFocusMode },
+{ 0x1030,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.SlowSync",        "Slow synchro", FujiTagOffOn },
+{ 0x1031,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.PictureMode",     "Picture mode", FujiTagPictureMode },
+{ 0x1100,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "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 },
+{ 0x1300,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.BlurWarning",     "Blue warning", FujiTagNoYes },
+{ 0x1301,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.FocusWarning",    "Focus warning",FujiTagNoYes },
+{ 0x1302,      EXIF_FORMAT_SHORT_UNSIGNED, 1,  "Fuji.AEWarning",       "AE warning",   FujiTagNoYes },
 EXIF_MARKER_LIST_END
 };
 
index f5fcce6..a3e9f41 100644 (file)
@@ -109,9 +109,8 @@ static guint nikon_tiff_table(unsigned char *data, const guint len, guint offset
        if (len < offset + 2) return FALSE;
 
        count = exif_byte_get_int16(data + offset, bo);
-
-       if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
        offset += 2;
+       if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
 
        for (i = 0; i < count; i++)
                {
@@ -228,18 +227,17 @@ static ExifTextList NikonTag[]= {
 #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",
+{ 0x0002, EXIF_FORMAT_STRING, 6,               "Nikon.unknown",        NULL,           NULL },
+{ 0x0003, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "Nikon.Quality",        "Quality",      NikonTagQuality },
+{ 0x0004, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "Nikon.ColorMode",      "Color mode",   NikonTagColorMode },
+{ 0x0005, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "Nikon.ImageAdjustment",
                                                                "Image adjustment",     NikonTagImgAdjust },
-{ 0x0006, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.ISOSensitivity",
+{ 0x0006, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "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 },
+{ 0x0007, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "Nikon.WhiteBalance",   "White balance",NikonTagWhiteBalance },
+{ 0x0008, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,    "Nikon.Focus",          "Focus",        NULL },
+{ 0x000a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,    "Nikon.DigitalZoom",    "Digital zoom", NULL },
+{ 0x000b, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "Nikon.Converter",      "Converter",    NikonTagConverter },
 EXIF_MARKER_LIST_END
 };
 
@@ -264,8 +262,19 @@ static ExifTextList NikonTag2FlashComp[]= {
        EXIF_TEXT_LIST_END
 };
 
+static ExifTextList NikonTag2LensType[]= {
+       { 0,    "AF non D" },
+       { 1,    "manual" },
+       { 2,    "AF-D or AF-s" },
+       { 6,    "AF-D G" },
+       { 10,   "AF-D VR" },
+       EXIF_TEXT_LIST_END
+};
+
 static ExifTextList NikonTag2FlashUsed[]= {
        { 0,    "no" },
+       { 4,    "unit unknown" },
+       { 7,    "external" },
        { 9,    "yes" },
        EXIF_TEXT_LIST_END
 };
@@ -283,63 +292,71 @@ static ExifTextList NikonTagi2Saturation[]= {
 #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",
+{ 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 2,       "Nikon.ISOSpeed",       "ISO speed",    NULL },
+{ 0x0003, EXIF_FORMAT_STRING, -1,              "Nikon.ColorMode",      "Color mode",   NULL },
+{ 0x0004, EXIF_FORMAT_STRING, -1,              "Nikon.Quality",        "Quality",      NULL },
+{ 0x0005, EXIF_FORMAT_STRING, -1,              "Nikon.WhiteBalance",   "White balance",NULL },
+{ 0x0006, EXIF_FORMAT_STRING, -1,              "Nikon.Sharpening",     "Sharpening",   NULL },
+{ 0x0007, EXIF_FORMAT_STRING, -1,              "Nikon.FocusMode",      "Focus mode",   NULL },
+{ 0x0008, EXIF_FORMAT_STRING, -1,              "Nikon.FlashSetting",   "Flash setting",NULL },
+{ 0x0009, EXIF_FORMAT_STRING, -1,              "Nikon.AutoFlashMode","Auto flash mode",NULL },
+{ 0x000b, EXIF_FORMAT_SHORT, 1,                        "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",
+/* { 0x000c, EXIF_FORMAT_SHORT_UNSIGNED, 1,    "Nikon.WhiteBalanceRB",
+                                               "White balance red/blue coefficients",  NULL }, */
+/* { 0x000f, EXIF_FORMAT_STRING, -1,           "Nikon.ISOSelect",      "ISO selection",NULL }, */
+{ 0x0012, EXIF_FORMAT_UNDEFINED, 4,            "Nikon.FlashCompensation",
                                                                "Flash compensation",   NikonTag2FlashComp },
-{ 0x0013, EXIF_FORMAT_SHORT_UNSIGNED, 2,       "MkN.Nikon.ISOSpeedRequest",
+{ 0x0013, EXIF_FORMAT_SHORT_UNSIGNED, 2,       "Nikon.ISOSpeedRequest",
                                                                "ISO speed requested",  NULL },
-{ 0x0016, EXIF_FORMAT_SHORT_UNSIGNED, 4,       "MkN.Nikon.CornerCoord",
+{ 0x0016, EXIF_FORMAT_SHORT_UNSIGNED, 4,       "Nikon.CornerCoord",
                                                                "Corner coordinates",   NULL },
-{ 0x0018, EXIF_FORMAT_UNDEFINED, 4,            "MkN.Nikon.FlashBracketCompensation",
+{ 0x0018, EXIF_FORMAT_UNDEFINED, 4,            "Nikon.FlashBracketCompensation",
                                                        "Flash bracket compensation",   NikonTag2FlashComp },
-{ 0x0019, EXIF_FORMAT_RATIONAL, 1,             "MkN.Nikon.AEBracketCompensation",
+{ 0x0019, EXIF_FORMAT_RATIONAL, 1,             "Nikon.AEBracketCompensation",
                                                        "AE bracket compensation",      NULL },
-{ 0x0080, EXIF_FORMAT_STRING, -1,              "MkN.Nikon.ImageAdjustment",
+{ 0x0080, EXIF_FORMAT_STRING, -1,              "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",
+{ 0x0081, EXIF_FORMAT_STRING, -1,              "Nikon.Contrast",       "Contrast",     NULL },
+{ 0x0082, EXIF_FORMAT_STRING, -1,              "Nikon.AuxLens", "Aux lens adapter",    NULL },
+{ 0x0083, EXIF_FORMAT_BYTE_UNSIGNED, -1,       "Nikon.LensType",       "Lens type",    NikonTag2LensType },
+{ 0x0084, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,   "Nikon.LensFocalLength",
                                                        "Lens min/max focal length and aperture", NULL },
-{ 0x0085, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "MkN.Nikon.ManualFocusDistance",
+{ 0x0085, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "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 },
+{ 0x0086, EXIF_FORMAT_RATIONAL, 1,             "Nikon.DigitalZoomFactor",
+                                                       "Digital zoom factor",          NULL },
+{ 0x0087, EXIF_FORMAT_BYTE_UNSIGNED, 1,                "Nikon.FlashUsed",      "Flash used",   NikonTag2FlashUsed },
+{ 0x0088, EXIF_FORMAT_UNDEFINED, 4,            "Nikon.AutoFocusArea","Auto focus area",NULL },
+/* { 0x0089, EXIF_FORMAT_SHORT_UNSIGNED, -1,   "Nikon.Bracket/ShootingMode", NULL,     NULL }, */
+{ 0x008d, EXIF_FORMAT_STRING, -1,              "Nikon.ColorMode",      "Color mode",   NULL },
+{ 0x008f, EXIF_FORMAT_SHORT_UNSIGNED, 1,       "Nikon.SceneMode",      "Scene mode",   NULL },
+{ 0x0090, EXIF_FORMAT_STRING, -1,              "Nikon.LightingType",   "Lighting type",NULL },
+{ 0x0092, EXIF_FORMAT_SHORT, 1,                        "Nikon.HueAdjust",      "Hue adjustment",NULL },
+/* { 0x0094, EXIF_FORMAT_SHORT_UNSIGNED, 1,    "Nikon.Saturation",     "Saturation",   NikonTag2Saturation }, */
+{ 0x0095, EXIF_FORMAT_STRING, -1,              "Nikon.NoiseReduction", "Noise reduction", NULL },
+{ 0x00a7, EXIF_FORMAT_LONG_UNSIGNED, 1,                "Nikon.ShutterCount", "Shutter release count", NULL },
+{ 0x00a9, EXIF_FORMAT_STRING, -1,              "Nikon.ImageOptimization", "Image optimization", NULL },
+{ 0x00aa, EXIF_FORMAT_STRING, -1,              "Nikon.Saturation", "Saturation",       NULL },
+{ 0x00ab, EXIF_FORMAT_STRING, -1,              "Nikon.DigitalVariProg", "Digital Vari-program", NULL },
 EXIF_MARKER_LIST_END
 };
 
+static ExifTextList NikonAFPoint[]= {
+       { 0,    "center" },
+       { 1,    "top" },
+       { 2,    "bottom" },
+       { 3,    "left" },
+       { 4,    "right" },
+       EXIF_TEXT_LIST_END
+};
+
 
 gint format_nikon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
                            guint size, ExifByteOrder bo)
 {
        unsigned char *data;
+       ExifItem *item;
 
        if (offset + 8 + 4 >= size) return FALSE;
 
@@ -368,16 +385,61 @@ gint format_nikon_makernote(ExifData *exif, unsigned char *tiff, guint offset,
                        {
                        return FALSE;
                        }
-               return TRUE;
                }
-
        /* Nikon tag format 3 uses format 2 tags without "Nikon" and tiff header */
-       if (exif_parse_IFD_table(exif, tiff, offset, size,
-                                bo, 0, NikonExifMarkersList2) != 0)
+       else if (exif_parse_IFD_table(exif, tiff, offset, size,
+                                     bo, 0, NikonExifMarkersList2) != 0)
                {
                return FALSE;
                }
 
-       return FALSE;
+       item = exif_get_item(exif, "Nikon.AutoFocusArea");
+       if (item && item->data_len == 4 * sizeof(guchar))
+               {
+               static ExifMarker marker = { 0x0088, EXIF_FORMAT_STRING, -1,
+                                            "Nikon.AutoFocusPoint", "Auto focus point", NULL };
+               guchar *array = item->data;
+               const gchar *text;
+
+               text = exif_text_list_find_value(NikonAFPoint, (gint)array[1]);
+               if (text)
+                       {
+                       gint l;
+
+                       l = strlen(text) + 1;
+                       item = exif_item_new(marker.format, marker.tag, l, &marker);
+                       memcpy(item->data, text, l);
+
+                       exif->items = g_list_prepend(exif->items, item);
+                       }
+               }
+
+       item = exif_get_item(exif, "Nikon.ISOSpeed");
+       if (item && item->data_len == 2 * 2)
+               {
+               static ExifMarker marker = { 0x0002, EXIF_FORMAT_SHORT_UNSIGNED, 1,
+                                            "ISOSpeedRatings", "ISO speed", NULL };
+               ExifItem *shadow;
+
+               shadow = exif_item_new(marker.format, marker.tag, 1, &marker);
+               memcpy(shadow->data, item->data + 2, 2);
+
+               exif->items = g_list_prepend(exif->items, shadow);
+               }
+
+       item = exif_get_item(exif, "Nikon.WhiteBalance");
+       if (item && item->format == EXIF_FORMAT_STRING)
+               {
+               static ExifMarker marker = { 0x0005, EXIF_FORMAT_STRING, -1,
+                                            "LightSource", "Light source", NULL };
+               ExifItem *shadow;
+
+               shadow = exif_item_new(marker.format, marker.tag, item->data_len, &marker);
+               memcpy(shadow->data, item->data, item->data_len);
+
+               exif->items = g_list_prepend(exif->items, shadow);
+               }
+
+       return TRUE;
 }
 
diff --git a/src/format_olympus.c b/src/format_olympus.c
new file mode 100644 (file)
index 0000000..b0fa572
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ *  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_olympus.h"
+#include "format_raw.h"
+
+#include "exif.h"
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * EXIF Makernote for Olympus
+ *-----------------------------------------------------------------------------
+ */
+
+static ExifTextList KonMinTagColorMode[]= {
+       { 0,    "natural" },
+       { 1,    "black and white" },
+       { 2,    "vivid" },
+       { 3,    "solarization" },
+       { 4,    "Adobe RGB" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList KonMinTagQuality[]= {
+       { 0,    "raw" },
+       { 1,    "super fine" },
+       { 2,    "find" },
+       { 3,    "standard" },
+       { 4,    "extra fine" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusTagJpegQuality[]= {
+       { 1,    "standard" },
+       { 2,    "high" },
+       { 3,    "super high" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusTagMacro[]= {
+       { 0,    "off" },
+       { 1,    "on" },
+       { 2,    "view" },
+       { 3,    "manual" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusTagFlashMode[]= {
+       { 0,    "auto" },
+       { 1,    "red-eye reduction" },
+       { 2,    "fill" },
+       { 3,    "off" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusTagFocusMode[]= {
+       { 0,    "auto" },
+       { 1,    "manual" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusTagSharpness[]= {
+       { 0,    "normal" },
+       { 1,    "hard" },
+       { 2,    "soft" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusTagContrast[]= {
+       { 0,    "hard" },
+       { 1,    "normal" },
+       { 2,    "soft" },
+       EXIF_TEXT_LIST_END
+};
+
+#if 0
+static ExifTextList OlympusTag[]= {
+       { ,     "" },
+       { ,     "" },
+       EXIF_TEXT_LIST_END
+};
+#endif
+
+
+static ExifMarker OlympusExifMarkersList[] = {
+{ 0x0001, EXIF_FORMAT_LONG_UNSIGNED, -1, "Konica/MinoltaSettings", "Konica / Minolta settings", NULL },
+{ 0x0003, EXIF_FORMAT_LONG_UNSIGNED, -1, "Konica/MinoltaSettings", "Konica / Minolta settings", NULL },
+{ 0x0040, EXIF_FORMAT_LONG_UNSIGNED, -1, "CompressedImageSize",        "Compressed image size", NULL },
+{ 0x0081, EXIF_FORMAT_LONG_UNSIGNED, 1,  "ThumbnailOffset",    "Thumbnail offset",     NULL },
+{ 0x0088, EXIF_FORMAT_LONG_UNSIGNED, 1,  "ThumbnailOffset",    "Thumbnail offset",     NULL },
+{ 0x0089, EXIF_FORMAT_LONG_UNSIGNED, 1,  "ThumbnailLength",    "Thumbnail length",     NULL },
+{ 0x0101, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Konica/Minolta.ColorMode", "Color mode",     KonMinTagColorMode },
+{ 0x0102, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Konica/Minolta.Quality", "Quality",          KonMinTagQuality },
+{ 0x0103, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Konica/Minolta.Quality", "Quality",          KonMinTagQuality },
+{ 0x0200, EXIF_FORMAT_LONG_UNSIGNED, 3,  "Olympus.SpecialMode",        "Special mode",         NULL },
+{ 0x0201, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.JpegQuality",        "Jpeg quality",         OlympusTagJpegQuality },
+{ 0x0202, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.Macro",      "Macro",                OlympusTagMacro },
+{ 0x0204, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "Olympus.DigitalZoom", "Digital zoom",     NULL },
+{ 0x0207, EXIF_FORMAT_STRING, -1,       "Olympus.Firmware",    "Firmware version",     NULL },
+{ 0x0208, EXIF_FORMAT_STRING, -1,       "Olympus.PictureInfo", "Picture info",         NULL },
+{ 0x0209, EXIF_FORMAT_UNDEFINED, -1,    "Olympus.CameraID",    "Camera ID",            NULL },
+{ 0x020b, EXIF_FORMAT_LONG_UNSIGNED, 1,         "Epson.ImageWidth",    "Image width",          NULL },
+{ 0x020c, EXIF_FORMAT_LONG_UNSIGNED, 1,  "Epson.ImageHeight",  "Image height",         NULL },
+{ 0x020d, EXIF_FORMAT_STRING, -1,       "Epson.Manufacturer",  "Manufacturer",         NULL },
+{ 0x0e00, EXIF_FORMAT_BYTE, -1,                 "Olympus.PrintImageMatching", "Print image matching", NULL },
+{ 0x1004, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.FlashMode",  "Flash mode",           OlympusTagFlashMode },
+{ 0x1006, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.Bracket",    "Bracket",              NULL },
+{ 0x100b, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.FocusMode",  "Focus mode",           OlympusTagFocusMode },
+{ 0x100c, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.FocusDistance", "Focus distance",    NULL },
+{ 0x100d, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.Zoom",       "Zoom",                 NULL },
+{ 0x1006, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.MacroFocus", "Macro focus",          NULL },
+{ 0x100f, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.Sharpness",  "Sharpness",            OlympusTagSharpness },
+{ 0x1011, EXIF_FORMAT_SHORT_UNSIGNED, 9, "Olympus.ColorMatrix",        "Color matrix",         NULL },
+{ 0x1012, EXIF_FORMAT_SHORT_UNSIGNED, 4, "Olympus.BlackLevel", "Black level",          NULL },
+{ 0x1015, EXIF_FORMAT_SHORT_UNSIGNED, 2, "Olympus.WhiteBalance", "White balance",      NULL },
+{ 0x1017, EXIF_FORMAT_SHORT_UNSIGNED, 2, "Olympus.RedBias",    "Red bias",             NULL },
+{ 0x1018, EXIF_FORMAT_SHORT_UNSIGNED, 2, "Olympus.BlueBias",   "Blue bias",            NULL },
+{ 0x101a, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.SerialNumber", "Serial number",      NULL },
+{ 0x1023, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.FlashBias",  "Flash bias",           NULL },
+{ 0x1029, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.Contrast",   "Contrast",             OlympusTagContrast },
+{ 0x102a, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.SharpnessFactor", "Sharpness factor",        NULL },
+{ 0x102b, EXIF_FORMAT_SHORT_UNSIGNED, 6, "Olympus.ColorControl", "Color control",      NULL },
+{ 0x102c, EXIF_FORMAT_SHORT_UNSIGNED, 2, "Olympus.ValidBits",  "Valid bits",           NULL },
+{ 0x102d, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.CoringFilter", "Coring filter",      NULL },
+{ 0x102e, EXIF_FORMAT_LONG_UNSIGNED, 1,  "Olympus.FinalWidth", "Final width",          NULL },
+{ 0x102f, EXIF_FORMAT_LONG_UNSIGNED, 1,  "Olympus.FinalHeight",        "Final height",         NULL },
+{ 0x1034, EXIF_FORMAT_SHORT_UNSIGNED, 1, "Olympus.CompressionRatio", "Compression ratio", NULL },
+EXIF_MARKER_LIST_END
+};
+
+static ExifTextList OlympusShootingMode[]= {
+       { 0,    "normal" },
+       { 1,    "unknown" },
+       { 2,    "fast" },
+       { 3,    "panorama" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusPanoramaDirection[]= {
+       { 1,    "left to right" },
+       { 2,    "right to left" },
+       { 3,    "bottom to top" },
+       { 4,    "top to bottom" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusWB[]= {
+       { 1,    "auto" },
+       { 2,    "manual" },
+       { 3,    "one-touch" },
+       EXIF_TEXT_LIST_END
+};
+
+static ExifTextList OlympusWBColorTemp[]= {
+       { 2,    "3000" },
+       { 3,    "3700" },
+       { 4,    "4000" },
+       { 5,    "4500" },
+       { 6,    "5500" },
+       { 7,    "6500" },
+       { 8,    "7500" },
+       EXIF_TEXT_LIST_END
+};
+
+gint format_olympus_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                             guint size, ExifByteOrder bo)
+{
+       unsigned char *data;
+       ExifItem *item;
+
+       if (offset + 8 + 4 >= size) return FALSE;
+
+       data = tiff + offset;
+
+       /* Olympus tag format starts with "OLYMP\x00\x01" or "OLYMP\x00\x02",
+        * plus an unknown byte,
+        * followed by IFD data using Olympus tags.
+        */
+       if (memcmp(data, "OLYMP\x00\x01", 7) != 0 &&
+           memcmp(data, "OLYMP\x00\x02", 7) != 0) return FALSE;
+
+       if (exif_parse_IFD_table(exif, tiff, offset + 8, size,
+                                bo, 0, OlympusExifMarkersList) != 0)
+               {
+               return FALSE;
+               }
+
+       item = exif_get_item(exif, "Olympus.SpecialMode");
+       if (item && item->data_len == 3 * sizeof(guint32))
+               {
+               static ExifMarker marker = { 0x0200, EXIF_FORMAT_STRING, -1,
+                                            "Olympus.ShootingMode", "Shooting mode", NULL };
+               guint32 *array = item->data;
+               const gchar *mode;
+               const gchar *pdir = NULL;
+               gchar *text;
+               gint l;
+
+               mode = exif_text_list_find_value(OlympusShootingMode, array[0]);
+               if (array[0] == 3)
+                       {
+                       pdir = exif_text_list_find_value(OlympusPanoramaDirection, array[2]);
+                       }
+
+               text = g_strdup_printf("%s%s%s, seq %d", (mode) ? mode : "unknown",
+                                      (pdir) ? " " : "", (pdir) ? pdir : "",
+                                      array[1] + 1);
+               l = strlen(text) + 1;
+               item = exif_item_new(marker.format, marker.tag, l, &marker);
+               memcpy(item->data, text, l);
+               g_free(text);
+
+               exif->items = g_list_prepend(exif->items, item);
+               }
+
+       item = exif_get_item(exif, "Olympus.WhiteBalance");
+       if (item && item->data_len == 2 * sizeof(guint16))
+               {
+               static ExifMarker marker = { 0x1015, EXIF_FORMAT_STRING, -1,
+                                            "Olympus.WhiteBalance", "White balance", NULL };
+               guint16 *array = item->data;
+               const gchar *mode;
+               const gchar *color = NULL;
+               gchar *text;
+               gint l;
+
+               mode = exif_text_list_find_value(OlympusWB, array[0]);
+               if (array[0] == 2)
+                       {
+                       color = exif_text_list_find_value(OlympusWBColorTemp, array[1]);
+                       }
+
+               text = g_strdup_printf("%s%s%s", (mode) ? mode : "unknown",
+                                      (color) ? " " : "", (color) ? color : "");
+               l = strlen(text) + 1;
+               item = exif_item_new(marker.format, marker.tag, l, &marker);
+               memcpy(item->data, text, l);
+               g_free(text);
+
+               exif->items = g_list_prepend(exif->items, item);
+               }
+
+       return TRUE;
+}
+
+
diff --git a/src/format_olympus.h b/src/format_olympus.h
new file mode 100644 (file)
index 0000000..7dac58c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  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_OLYMPUS_H
+#define __FORMAT_OLYMPUS_H
+
+
+#include "exif.h"
+
+
+#if 0
+gint format_olympus_raw(unsigned char *data, const guint len,
+                       guint *image_offset, guint *exif_offset);
+
+
+#define FORMAT_RAW_OLYMPUS { "orf", \
+                            FORMAT_RAW_MATCH_MAGIC, 0, "IIRS", 4, \
+                            "Olympus raw", format_olympus_raw }
+#endif
+
+
+gint format_olympus_makernote(ExifData *exif, unsigned char *tiff, guint offset,
+                             guint size, ExifByteOrder bo);
+
+#define FORMAT_EXIF_OLYMPUS { FORMAT_EXIF_MATCH_MAKERNOTE, "OLYMP\x00\x01", 7, \
+                             "Olympus", format_olympus_makernote }, \
+                           { FORMAT_EXIF_MATCH_MAKERNOTE, "OLYMP\x00\x02", 7, \
+                             "Olympus", format_olympus_makernote }
+
+
+#endif
+
index 150f88c..db2977d 100644 (file)
@@ -31,6 +31,7 @@
 #include "format_canon.h"
 #include "format_fuji.h"
 #include "format_nikon.h"
+#include "format_olympus.h"
 
 
 /* so that debugging is honored */
@@ -69,6 +70,7 @@ static FormatExifEntry format_exif_list[] = {
        FORMAT_EXIF_CANON,
        FORMAT_EXIF_FUJI,
        FORMAT_EXIF_NIKON,
+       FORMAT_EXIF_OLYMPUS,
        { 0, NULL, 0, NULL }
 };