changeset 57:a8c9992320f4

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].
author gqview
date Sat, 11 Jun 2005 01:09:30 +0000
parents c722cbf9ad25
children df73b94154e4
files 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 src/format_olympus.h src/format_raw.c
diffstat 11 files changed, 471 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jun 10 06:23:22 2005 +0000
+++ b/ChangeLog	Sat Jun 11 01:09:30 2005 +0000
@@ -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
--- a/TODO	Fri Jun 10 06:23:22 2005 +0000
+++ b/TODO	Sat Jun 11 01:09:30 2005 +0000
@@ -33,8 +33,8 @@
       > 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.
 
--- a/src/Makefile.am	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/Makefile.am	Sat Jun 11 01:09:30 2005 +0000
@@ -90,6 +90,8 @@
 	format_fuji.h	\
 	format_nikon.c	\
 	format_nikon.h	\
+	format_olympus.c	\
+	format_olympus.h	\
 	format_raw.c	\
 	format_raw.h	\
 	fullscreen.c	\
--- a/src/exif.c	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/exif.c	Sat Jun 11 01:09:30 2005 +0000
@@ -562,7 +562,7 @@
 	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 @@
 	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 @@
 					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 *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 @@
 		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("");
--- a/src/exif.h	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/exif.h	Sat Jun 11 01:09:30 2005 +0000
@@ -231,6 +231,8 @@
 				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
 
--- a/src/format_canon.c	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/format_canon.c	Sat Jun 11 01:09:30 2005 +0000
@@ -505,14 +505,14 @@
 	{ 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 @@
 	{ 8,	"portrait" },
 	{ 9,	"sports" },
 	{ 10,	"macro" },
-	{ 11,	"panoramic focus" },
+	{ 11,	"pan focus" },
 	EXIF_TEXT_LIST_END
 };
 
@@ -663,7 +663,7 @@
 
 static ExifTextList CanonSet2WhiteBalance[] = {
 	{ 0,	"auto" },
-	{ 1,	"daylight" },
+	{ 1,	"sunny" },
 	{ 2,	"cloudy" },
 	{ 3,	"tungsten" },
 	{ 4,	"fluorescent" },
@@ -834,7 +834,7 @@
 
 		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);
--- a/src/format_fuji.c	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/format_fuji.c	Sat Jun 11 01:09:30 2005 +0000
@@ -149,22 +149,22 @@
 
 
 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
 };
 
--- a/src/format_nikon.c	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/format_nikon.c	Sat Jun 11 01:09:30 2005 +0000
@@ -109,9 +109,8 @@
 	if (len < offset + 2) return FALSE;
 
 	count = exif_byte_get_int16(data + offset, bo);
-
+	offset += 2;
 	if (len < offset + count * EXIF_TIFD_SIZE + 4) return 0;
-	offset += 2;
 
 	for (i = 0; i < count; i++)
 		{
@@ -228,18 +227,17 @@
 #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 @@
 	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 @@
 #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 @@
 			{
 			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;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/format_olympus.c	Sat Jun 11 01:09:30 2005 +0000
@@ -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;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/format_olympus.h	Sat Jun 11 01:09:30 2005 +0000
@@ -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
+
--- a/src/format_raw.c	Fri Jun 10 06:23:22 2005 +0000
+++ b/src/format_raw.c	Sat Jun 11 01:09:30 2005 +0000
@@ -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 @@
 	FORMAT_EXIF_CANON,
 	FORMAT_EXIF_FUJI,
 	FORMAT_EXIF_NIKON,
+	FORMAT_EXIF_OLYMPUS,
 	{ 0, NULL, 0, NULL }
 };