changeset 222:77f1bcc6c161

various exif improvements based on patch by Uwe Ohse try to compute 35mm focal length
author nadvornik
date Wed, 02 Apr 2008 20:44:40 +0000
parents 79ef86f3b325
children 73efc1ba150f
files src/bar_exif.c src/bar_exif.h src/exif-common.c src/exif.c src/image.c src/preferences.c src/rcfile.c
diffstat 7 files changed, 356 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/src/bar_exif.c	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/bar_exif.c	Wed Apr 02 20:44:40 2008 +0000
@@ -36,6 +36,7 @@
 	"fExposureBias",
 	"fISOSpeedRating",
 	"fFocalLength",
+	"fFocalLength35mmFilm",
 	"fSubjectDistance",
 	"Exif.Photo.MeteringMode",
 	"fFlash",
@@ -49,6 +50,27 @@
 const gchar **bar_exif_key_list = bar_exif_key_list_real;
 const gint bar_exif_key_count = (sizeof(bar_exif_key_list_real) / sizeof(gchar *));
 
+ExifUI ExifUIList[]={
+	{ 0, 0, EXIF_UI_ON,    "fCamera"},
+	{ 0, 0, EXIF_UI_ON,    "fDateTime"},
+	{ 0, 0, EXIF_UI_ON,    "fShutterSpeed"},
+	{ 0, 0, EXIF_UI_ON,    "fAperture"},
+	{ 0, 0, EXIF_UI_IFSET, "Exif.Photo.ExposureProgram"},
+	{ 0, 0, EXIF_UI_IFSET, "fExposureBias"},
+	{ 0, 0, EXIF_UI_IFSET, "fISOSpeedRating"},
+	{ 0, 0, EXIF_UI_ON,    "fFocalLength"},
+	{ 0, 0, EXIF_UI_IFSET, "fFocalLength35mmFilm"},
+	{ 0, 0, EXIF_UI_IFSET, "fSubjectDistance"},
+	{ 0, 0, EXIF_UI_IFSET, "Exif.Photo.MeteringMode"},
+	{ 0, 0, EXIF_UI_ON,    "fFlash"},
+	{ 0, 0, EXIF_UI_IFSET, "Exif.Photo.LightSource"},
+	{ 0, 0, EXIF_UI_OFF,   "fResolution"},
+	{ 0, 0, EXIF_UI_IFSET, "Exif.Image.Orientation"},
+	{ 0, 0, EXIF_UI_IFSET, "Exif.Image.ImageDescription"},
+	{ 0, 0, EXIF_UI_IFSET, "Exif.Image.Copyright"},
+	{ 0, 0, EXIF_UI_OFF,   NULL}
+};
+
 
 /*
  *-------------------------------------------------------------------
@@ -87,7 +109,8 @@
 }
 
 static GtkWidget *table_add_line(GtkWidget *table, gint x, gint y,
-				 const gchar *description, const gchar *text)
+				 const gchar *description, const gchar *text,
+				GtkWidget **keyret)
 {
 	GtkWidget *key;
 	GtkWidget *label;
@@ -95,6 +118,7 @@
 	table_add_line_custom(table, x, y, description, text, &key, &label);
 	gtk_widget_show(key);
 	gtk_widget_show(label);
+	if (keyret) *keyret = key;
 
 	return label;
 }
@@ -114,6 +138,7 @@
 	GtkWidget *table;
 	GtkWidget *advanced_scrolled;
 	GtkWidget *listview;
+	GtkWidget **keys;
 	GtkWidget **labels;
 
 	GtkWidget *custom_sep;
@@ -185,12 +210,27 @@
 	if (GTK_WIDGET_VISIBLE(eb->scrolled))
 		{
 		GList *list;
-		len = bar_exif_key_count;
-		for (i = 0; i < len; i++)
+		for (i = 0; ExifUIList[i].key; i++)
 			{
 			gchar *text;
-			text = exif_get_data_as_text(exif, bar_exif_key_list[i]);
+
+			if (ExifUIList[i].current == EXIF_UI_OFF)
+				{
+				gtk_widget_hide(eb->labels[i]);
+				gtk_widget_hide(eb->keys[i]);
+				continue;
+				}
+			text = exif_get_data_as_text(exif, ExifUIList[i].key);
 			text = bar_exif_validate_text(text);
+			if (ExifUIList[i].current == EXIF_UI_IFSET
+			    && (!text || !*text))
+			    	{
+				gtk_widget_hide(eb->labels[i]);
+				gtk_widget_hide(eb->keys[i]);
+				continue;
+				}
+			gtk_widget_show(eb->labels[i]);
+			gtk_widget_show(eb->keys[i]);
 			gtk_label_set_text(GTK_LABEL(eb->labels[i]), text);
 			g_free(text);
 			}
@@ -286,13 +326,11 @@
 
 static void bar_exif_clear(ExifBar *eb)
 {
-	gint len;
 	gint i;
 
 	if (!GTK_WIDGET_SENSITIVE(eb->labels[0])) return;
 
-	len = bar_exif_key_count;
-	for (i = 0; i < len; i++)
+	for (i = 0; ExifUIList[i].key; i++)
 		{
 		gtk_label_set_text(GTK_LABEL(eb->labels[i]), "");
 		}
@@ -519,6 +557,7 @@
 {
 	ExifBar *eb = data;
 
+	g_free(eb->keys);
 	g_free(eb->labels);
 	file_data_unref(eb->fd);
 	g_free(eb);
@@ -533,10 +572,15 @@
 	GtkWidget *button;
 	gint len;
 	gint i;
+	gint exif_len;
+
+	for (exif_len = 0; ExifUIList[exif_len].key; exif_len++)
+	      ;
 
 	eb = g_new0(ExifBar, 1);
 
-	eb->labels = g_new0(GtkWidget *, bar_exif_key_count);
+	eb->keys = g_new0(GtkWidget *, exif_len);
+	eb->labels = g_new0(GtkWidget *, exif_len);
 
 	eb->vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP);
 	g_object_set_data(G_OBJECT(eb->vbox), "bar_exif_data", eb);
@@ -590,27 +634,28 @@
 		gtk_widget_show(box);
 		}
 
-	table = gtk_table_new(2, bar_exif_key_count + 1 + EXIF_BAR_CUSTOM_COUNT, FALSE);
+
+	table = gtk_table_new(2, exif_len + 1 + EXIF_BAR_CUSTOM_COUNT, FALSE);
 
 	eb->table = table;
 
-	len = bar_exif_key_count;
-	for (i = 0; i < len; i++)
+	for (i = 0; ExifUIList[i].key; i++)
 		{
 		const gchar *text;
 
-		text = exif_get_description_by_key(bar_exif_key_list[i]);
-		eb->labels[i] = table_add_line(table, 0, i, text, NULL);
+		text = exif_get_description_by_key(ExifUIList[i].key);
+		eb->labels[i] = table_add_line(table, 0, i, text, NULL, 
+		      &eb->keys[i]);
 		}
 
 	eb->custom_sep = gtk_hseparator_new();
 	gtk_table_attach(GTK_TABLE(table), eb->custom_sep, 0, 1,
-					   bar_exif_key_count, bar_exif_key_count + 1,
+					   exif_len, exif_len + 1,
 					   GTK_FILL, GTK_FILL, 2, 2);
 
 	for (i = 0; i < EXIF_BAR_CUSTOM_COUNT; i++)
 		{
-		table_add_line_custom(table, 0, bar_exif_key_count + 1 + i,
+		table_add_line_custom(table, 0, exif_len + 1 + i,
 				      "", "",  &eb->custom_name[i], &eb->custom_value[i]);
 		}
 
--- a/src/bar_exif.h	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/bar_exif.h	Wed Apr 02 20:44:40 2008 +0000
@@ -13,6 +13,19 @@
 #ifndef BAR_EXIF_H
 #define BAR_EXIF_H
 
+#define EXIF_UI_OFF     0
+#define EXIF_UI_IFSET   1
+#define EXIF_UI_ON      2
+
+typedef struct _ExifUI ExifUI;
+struct _ExifUI {
+	gint         current;
+	gint         temp;
+	gint         default_value;
+	const gchar *key;
+};
+extern ExifUI ExifUIList[];
+
 
 GtkWidget *bar_exif_new(gint show_title, FileData *fd, gint advanced, GtkWidget *bounding_widget);
 void bar_exif_close(GtkWidget *bar);
--- a/src/exif-common.c	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/exif-common.c	Wed Apr 02 20:44:40 2008 +0000
@@ -38,6 +38,7 @@
 	{ "fExposureBias",	N_("Exposure bias") },
 	{ "fISOSpeedRating",	N_("ISO sensitivity") },
 	{ "fFocalLength",	N_("Focal length") },
+	{ "fFocalLength35mmFilm",N_("Focal length 35mm") },
 	{ "fSubjectDistance",	N_("Subject distance") },
 	{ "fFlash",		N_("Flash") },
 	{ "fResolution",	N_("Resolution") },
@@ -52,7 +53,6 @@
 	EXIF_TEXT_LIST_END
 };
 
-
 double exif_rational_to_double(ExifRational *r, gint sign)
 {
 	if (!r || r->den == 0.0) return 0.0;
@@ -78,6 +78,58 @@
 	return string;
 }
 
+static gchar *remove_common_prefix(gchar *s, gchar *t)
+{
+	gint i;
+
+	if (!s || !t) return t;
+
+	for (i = 0; s[i] == t[i]; i++)
+		;
+	if (!i) 
+		return t;
+	if (s[i]==' ' || s[i]==0)
+		{
+		while (t[i] == ' ')
+			i++;
+		return t + i;
+		}
+	return s;
+}
+
+static double get_crop_factor(ExifData *exif)
+{
+        double res_unit_tbl[] = {0.0, 25.4, 25.4, 10.0, 1.0, 0.001 };
+
+        double xres = exif_get_rational_as_double(exif, "Exif.Photo.FocalPlaneXResolution");
+        double yres = exif_get_rational_as_double(exif, "Exif.Photo.FocalPlaneYResolution");
+        int res_unit;
+        int w, h;
+        double xsize, ysize, size, ratio;
+        
+        if (xres == 0.0 || yres == 0.0) return 0.0;
+        
+        if (!exif_get_integer(exif, "Exif.Photo.FocalPlaneResolutionUnit", &res_unit)) return 0.0;
+        if (res_unit < 1 || res_unit > 5) return 0.0;
+        
+        if (!exif_get_integer(exif, "Exif.Photo.PixelXDimension", &w)) return 0.0;
+        if (!exif_get_integer(exif, "Exif.Photo.PixelYDimension", &h)) return 0.0;
+        
+        xsize = w * res_unit_tbl[res_unit] / xres;
+        ysize = h * res_unit_tbl[res_unit] / yres;
+        
+        ratio = xsize / ysize;
+        
+        if (ratio < 0.5 || ratio > 2.0) return 0.0; /* reasonable ratio */
+        
+        size = sqrt(xsize * xsize + ysize * ysize);
+        
+        if (size < 1.0 || size > 100.0) return 0.0; /* reasonable sensor size in mm */
+        
+        return sqrt(36*36+24*24) / size;
+        
+}
+
 
 gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_valid)
 {
@@ -96,12 +148,47 @@
 		gchar *make = exif_get_data_as_text(exif, "Exif.Image.Make");
 		gchar *model = exif_get_data_as_text(exif, "Exif.Image.Model");
 		gchar *software = exif_get_data_as_text(exif, "Exif.Image.Software");
+		gchar *model2;
+		gchar *software2;
+		gint i;
+
+		if (make)
+			{
+			gchar *x;
+			
+			g_strstrip(make);
+#define REMOVE_SUFFIX(str,suff)         \
+do {                                    \
+	if (g_str_has_suffix(str,suff)) \
+		str[strlen(str)-(sizeof(suff)-1)] = 0;  \
+} while(0)
+			REMOVE_SUFFIX(make," Corporation"); /* Pentax */
+			REMOVE_SUFFIX(make," OPTICAL CO.,LTD"); /* OLYMPUS */
+		}
+		if (model)
+			g_strstrip(model);
+		if (software)
+			g_strstrip(software);
+		/* remove superfluous spaces (pentax K100D) */
+		for (i=0; software && software[i]; i++)
+			if (software[i] == ' ' && software[i+1] == ' ')
+				{
+				gint j;
+				
+				for (j=1; software[i+j]; j++)
+		      			if (software[i+j] != ' ')
+						break;
+		    		memmove(software+i+1, software+i+j, strlen(software+i+j)+1);
+		  		}
+
+		model2 = remove_common_prefix(make, model);
+		software2 = remove_common_prefix(model2, software);
 
 		text = g_strdup_printf("%s%s%s%s%s%s", (make) ? make : "", ((make) && (model)) ? " " : "",
-						       (model) ? model : "",
-						       (software) ? " (" : "",
-						       (software) ? software : "",
-						       (software) ? ")" : "");
+						       (model2) ? model2 : "",
+						       (software2) ? " (" : "",
+						       (software2) ? software2 : "",
+						       (software2) ? ")" : "");
 
 		g_free(make);
 		g_free(model);
@@ -179,7 +266,27 @@
 
 		n = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength");
 		if (n == 0.0) return NULL;
-		return g_strdup_printf("%.2f mm", n);
+		return g_strdup_printf("%.0f mm", n);
+		}
+	if (strcmp(key, "fFocalLength35mmFilm") == 0)
+		{
+		gint n;
+                double f, c;
+
+		if (exif_get_integer(exif, "Exif.Photo.FocalLengthIn35mmFilm", &n) && n != 0)
+		        {
+                        return g_strdup_printf("%d mm", n);
+                        }
+                        
+                f = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength");
+                c = get_crop_factor(exif);
+                
+                if (f != 0.0 && c != 0.0)
+                        {
+                        return g_strdup_printf("%.0f mm", f * c);
+                        }
+
+                return NULL;
 		}
 	if (strcmp(key, "fISOSpeedRating") == 0)
 		{
--- a/src/exif.c	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/exif.c	Wed Apr 02 20:44:40 2008 +0000
@@ -109,6 +109,36 @@
  * Data
  *-----------------------------------------------------------------------------
  */
+static ExifTextList ExifCompressionList[] = {
+	{ 1, "Uncompressed" },
+	{ 2, "CCITT 1D" },
+	{ 3, "T4/Group 3 Fax" },
+	{ 4, "T6/Group 4 Fax" },
+	{ 5, "LZW" },
+	{ 6, "JPEG (old style)" },
+	{ 7, "JPEG" },
+	{ 8, "Adobe Deflate" },
+	{ 9, "JBIG B&W" },
+	{ 10, "JBIG Color" },
+	{ 32766, "Next" },
+	{ 32771, "CCIRLEW" },
+	{ 32773, "PackBits" },
+	{ 32809, "ThunderScan" },
+	{ 32895, "IT8CTPAD" },
+	{ 32896, "IT8LW" },
+	{ 32897, "IT8MP" },
+	{ 32898, "IT8BL" },
+	{ 32908, "PixasFilm" },
+	{ 32909, "PixasLog" },
+	{ 32946, "Deflate" },
+	{ 32947, "DCS" },
+	{ 34661, "JBIG" },
+	{ 34676, "SGILog" },
+	{ 34677, "SGILog24" },
+	{ 34712, "JPEF 2000" },
+	{ 34713, "Nikon NEF Compressed" },
+	EXIF_TEXT_LIST_END
+};
 
 static ExifTextList ExifOrientationList[] = {
 	{ EXIF_ORIENTATION_UNKNOWN,	N_("unknown") },
@@ -287,31 +317,40 @@
 	EXIF_TEXT_LIST_END
 };
 
+/* 
+Tag names should match to exiv2 keys, http://www.exiv2.org/metadata.html 
+Tags that don't match are not supported by exiv2 and should not be used anywhere in the code
+*/
+
 ExifMarker ExifKnownMarkersList[] = {
+{ 0x0100, EXIF_FORMAT_LONG_UNSIGNED, 1,		"Exif.Image.ImageWidth",	N_("Image Width"), NULL },
+{ 0x0101, EXIF_FORMAT_LONG_UNSIGNED, 1,		"Exif.Image.ImageLength",	N_("Image Height"), NULL },
+{ 0x0102, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Image.BitsPerSample",	N_("Bits per Sample/Pixel"), NULL },
+{ 0x0103, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Image.Compression",	N_("Compression"), ExifCompressionList },
 { 0x010e, EXIF_FORMAT_STRING, -1,		"Exif.Image.ImageDescription",	N_("Image description"), NULL },
-{ 0x010f, EXIF_FORMAT_STRING, -1,		"Exif.Image.Make",			"Camera make", NULL },
+{ 0x010f, EXIF_FORMAT_STRING, -1,		"Exif.Image.Make",		"Camera make", NULL },
 { 0x0110, EXIF_FORMAT_STRING, -1,		"Exif.Image.Model",		"Camera model", NULL },
-{ 0x0112, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Image.Orientation",		N_("Orientation"), ExifOrientationList },
-{ 0x011a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Image.XResolution",		"X resolution", NULL },
-{ 0x011b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Image.YResolution",		"Y Resolution", NULL },
+{ 0x0112, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Image.Orientation",	N_("Orientation"), ExifOrientationList },
+{ 0x011a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Image.XResolution",	"X resolution", NULL },
+{ 0x011b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Image.YResolution",	"Y Resolution", NULL },
 { 0x0128, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Image.ResolutionUnit",	"Resolution units", ExifUnitList },
 { 0x0131, EXIF_FORMAT_STRING, -1, 		"Exif.Image.Software",		"Firmware", NULL },
 { 0x0132, EXIF_FORMAT_STRING, 20,		"Exif.Image.DateTime",		N_("Date"), NULL },
-{ 0x013e, EXIF_FORMAT_RATIONAL_UNSIGNED, 2,	"Exif.Image.WhitePoint",		"White point", NULL },
+{ 0x013e, EXIF_FORMAT_RATIONAL_UNSIGNED, 2,	"Exif.Image.WhitePoint",	"White point", NULL },
 { 0x013f, EXIF_FORMAT_RATIONAL_UNSIGNED, 6,	"Exif.Image.PrimaryChromaticities","Primary chromaticities", NULL },
 { 0x0211, EXIF_FORMAT_RATIONAL_UNSIGNED, 3,	"Exif.Image.YCbCrCoefficients",	"YCbCy coefficients", NULL },
 { 0x0213, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Image.YCbCrPositioning",	"YCbCr positioning", ExifYCbCrPosList },
-{ 0x0214, EXIF_FORMAT_RATIONAL_UNSIGNED, 6, 	"Exif.Image.ReferenceBlackWhite",	"Black white reference", NULL },
+{ 0x0214, EXIF_FORMAT_RATIONAL_UNSIGNED, 6, 	"Exif.Image.ReferenceBlackWhite","Black white reference", NULL },
 { 0x8298, EXIF_FORMAT_STRING, -1,		"Exif.Image.Copyright",		N_("Copyright"), NULL },
-{ 0x8769, EXIF_FORMAT_LONG_UNSIGNED, 1,		"ExifOffset",		"SubIFD Exif offset", NULL },
+{ 0x8769, EXIF_FORMAT_LONG_UNSIGNED, 1,		"Exif.Image.ExifTag",		"SubIFD Exif offset", NULL },
 	/* subIFD follows */
-{ 0x829a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.ExposureTime",		"Exposure time (seconds)", NULL },
+{ 0x829a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.ExposureTime",	"Exposure time (seconds)", NULL },
 { 0x829d, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.FNumber",		"FNumber", NULL },
 { 0x8822, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.ExposureProgram",	N_("Exposure program"), ExifExposureProgramList },
-{ 0x8824, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SpectralSensitivity",	"Spectral Sensitivity", NULL },
+{ 0x8824, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SpectralSensitivity","Spectral Sensitivity", NULL },
 { 0x8827, EXIF_FORMAT_SHORT_UNSIGNED, -1,	"Exif.Photo.ISOSpeedRatings",	N_("ISO sensitivity"), NULL },
-{ 0x8828, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Photo.OECF",			"Optoelectric conversion factor", NULL },
-{ 0x9000, EXIF_FORMAT_UNDEFINED, 4,		"Exif.Photo.ExifVersion",		"Exif version", NULL },
+{ 0x8828, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Photo.OECF",		"Optoelectric conversion factor", NULL },
+{ 0x9000, EXIF_FORMAT_UNDEFINED, 4,		"Exif.Photo.ExifVersion",	"Exif version", NULL },
 { 0x9003, EXIF_FORMAT_STRING, 20,		"Exif.Photo.DateTimeOriginal",	N_("Date original"), NULL },
 { 0x9004, EXIF_FORMAT_STRING, 20,		"Exif.Photo.DateTimeDigitized",	N_("Date digitized"), NULL },
 { 0x9101, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Photo.ComponentsConfiguration","Pixel format", NULL },
@@ -322,24 +361,24 @@
 { 0x9204, EXIF_FORMAT_RATIONAL, 1,		"Exif.Photo.ExposureBiasValue",	N_("Exposure bias"), NULL },
 { 0x9205, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.MaxApertureValue",	"Maximum aperture", NULL },
 { 0x9206, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.SubjectDistance",	N_("Subject distance"), NULL },
-{ 0x9207, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.MeteringMode",		N_("Metering mode"), ExifMeteringModeList },
-{ 0x9208, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.LightSource",		N_("Light source"), ExifLightSourceList },
+{ 0x9207, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.MeteringMode",	N_("Metering mode"), ExifMeteringModeList },
+{ 0x9208, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.LightSource",	N_("Light source"), ExifLightSourceList },
 { 0x9209, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.Flash",		N_("Flash"), ExifFlashList },
-{ 0x920a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, 	"Exif.Photo.FocalLength",		N_("Focal length"), NULL },
-{ 0x9214, EXIF_FORMAT_SHORT_UNSIGNED, -1,	"Exif.Photo.SubjectArea",		"Subject area", NULL },
+{ 0x920a, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, 	"Exif.Photo.FocalLength",	N_("Focal length"), NULL },
+{ 0x9214, EXIF_FORMAT_SHORT_UNSIGNED, -1,	"Exif.Photo.SubjectArea",	"Subject area", NULL },
 { 0x927c, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Photo.MakerNote",		"MakerNote", NULL },
-{ 0x9286, EXIF_FORMAT_UNDEFINED, -1, 		"Exif.Photo.UserComment",		"UserComment", NULL },
-{ 0x9290, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SubSecTime",		"Subsecond time", NULL },
-{ 0x9291, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SubSecTimeOriginal",	"Subsecond time original", NULL },
-{ 0x9292, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SubSecTimeDigitized",	"Subsecond time digitized", NULL },
-{ 0xa000, EXIF_FORMAT_UNDEFINED, 4,		"FlashPixVersion",	"FlashPix version", NULL },
-{ 0xa001, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.ColorSpace",		"Colorspace", ExifColorSpaceList },
+{ 0x9286, EXIF_FORMAT_UNDEFINED, -1, 		"Exif.Photo.UserComment",	"UserComment", NULL },
+{ 0x9290, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SubSecTime",	"Subsecond time", NULL },
+{ 0x9291, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SubSecTimeOriginal","Subsecond time original", NULL },
+{ 0x9292, EXIF_FORMAT_STRING, -1,		"Exif.Photo.SubSecTimeDigitized","Subsecond time digitized", NULL },
+{ 0xa000, EXIF_FORMAT_UNDEFINED, 4,		"Exif.Photo.FlashpixVersion",	"FlashPix version", NULL },
+{ 0xa001, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.ColorSpace",	"Colorspace", ExifColorSpaceList },
 	/* ExifImageWidth, ExifImageHeight can also be unsigned short */
-{ 0xa002, EXIF_FORMAT_LONG_UNSIGNED, 1,		"ExifImageWidth",	N_("Width"), NULL },
-{ 0xa003, EXIF_FORMAT_LONG_UNSIGNED, 1,		"ExifImageHeight",	N_("Height"), NULL },
+{ 0xa002, EXIF_FORMAT_LONG_UNSIGNED, 1,		"Exif.Photo.PixelXDimension",	N_("Width"), NULL },
+{ 0xa003, EXIF_FORMAT_LONG_UNSIGNED, 1,		"Exif.Photo.PixelYDimension",	N_("Height"), NULL },
 { 0xa004, EXIF_FORMAT_STRING, -1,		"Exif.Photo.RelatedSoundFile",	"Audio data", NULL },
-{ 0xa005, EXIF_FORMAT_LONG_UNSIGNED, 1,		"ExifInteroperabilityOffset", "ExifR98 extension", NULL },
-{ 0xa20b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.FlashEnergy",		"Flash strength", NULL },
+{ 0xa005, EXIF_FORMAT_LONG_UNSIGNED, 1,		"ExifInteroperabilityOffset",   "ExifR98 extension", NULL },
+{ 0xa20b, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.FlashEnergy",	"Flash strength", NULL },
 { 0xa20c, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.SpatialFrequencyResponse","Spatial frequency response", NULL },
 { 0xa20e, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.FocalPlaneXResolution", "X Pixel density", NULL },
 { 0xa20f, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.FocalPlaneYResolution", "Y Pixel density", NULL },
@@ -347,26 +386,26 @@
 { 0x0214, EXIF_FORMAT_SHORT_UNSIGNED, 2,	"Exif.Photo.SubjectLocation",	"Subject location", NULL },
 { 0xa215, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.ExposureIndex",	N_("ISO sensitivity"), NULL },
 { 0xa217, EXIF_FORMAT_SHORT_UNSIGNED, -1,	"Exif.Photo.SensingMethod",	"Sensor type", ExifSensorList },
-{ 0xa300, EXIF_FORMAT_UNDEFINED, 1,		"Exif.Photo.FileSource",		"Source type", ExifSourceList },
+{ 0xa300, EXIF_FORMAT_UNDEFINED, 1,		"Exif.Photo.FileSource",	"Source type", ExifSourceList },
 { 0xa301, EXIF_FORMAT_UNDEFINED, 1,		"Exif.Photo.SceneType",		"Scene type", ExifSceneList },
-{ 0xa302, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Image.CFAPattern",		"Color filter array pattern", NULL },
+{ 0xa302, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Image.CFAPattern",	"Color filter array pattern", NULL },
 	/* tags a4xx were added for Exif 2.2 (not just these - some above, as well) */
 { 0xa401, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.CustomRendered",	"Render process", ExifCustRenderList },
-{ 0xa402, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.ExposureMode",		"Exposure mode", ExifExposureModeList },
-{ 0xa403, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.WhiteBalance",		"White balance", ExifWhiteBalanceList },
+{ 0xa402, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.ExposureMode",	"Exposure mode", ExifExposureModeList },
+{ 0xa403, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.WhiteBalance",	"White balance", ExifWhiteBalanceList },
 { 0xa404, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Photo.DigitalZoomRatio",	"Digital zoom ratio", NULL },
-{ 0xa405, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"FocalLength35mmFilm",	"Focal length (35mm)", NULL },
-{ 0xa406, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"SceneCapturetype",	"Scene capture type", ExifSceneCaptureList },
-{ 0xa407, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.GainControl",		"Gain control", ExifGainControlList },
+{ 0xa405, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.FocalLengthIn35mmFilm","Focal length (35mm)", NULL },
+{ 0xa406, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.SceneCaptureType",	"Scene capture type", ExifSceneCaptureList },
+{ 0xa407, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.GainControl",	"Gain control", ExifGainControlList },
 { 0xa408, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.Contrast",		"Contrast", ExifContrastList },
-{ 0xa409, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.Saturation",		"Saturation", ExifSaturationList },
+{ 0xa409, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.Saturation",	"Saturation", ExifSaturationList },
 { 0xa40a, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.Sharpness",		"Sharpness", ExifSharpnessList },
 { 0xa40b, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Photo.DeviceSettingDescription","Device setting", NULL },
-{ 0xa40c, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.SubjectDistanceRange",	"Subject range", ExifSubjectRangeList },
+{ 0xa40c, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Exif.Photo.SubjectDistanceRange","Subject range", ExifSubjectRangeList },
 { 0xa420, EXIF_FORMAT_STRING, -1,		"Exif.Photo.ImageUniqueID",	"Image serial number", NULL },
 	/* place known, but undocumented or lesser used tags here */
 { 0x00fe, EXIF_FORMAT_LONG_UNSIGNED, 1,		"Exif.Image.NewSubfileType",	NULL, NULL },
-{ 0x00ff, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"SubfileType",		NULL, NULL },
+{ 0x00ff, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"SubfileType",			NULL, NULL },
 { 0x012d, EXIF_FORMAT_SHORT_UNSIGNED, 3,	"Exif.Image.TransferFunction",	NULL, NULL },
 { 0x013b, EXIF_FORMAT_STRING, -1,		"Exif.Image.Artist",		"Artist", NULL },
 { 0x013d, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Predictor",		NULL, NULL },
@@ -380,7 +419,7 @@
 { 0x828e, EXIF_FORMAT_BYTE_UNSIGNED, -1,	"Exif.Image.CFAPattern",		NULL, NULL },
 { 0x828f, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,	"Exif.Image.BatteryLevel",		NULL, NULL },
 { 0x83bb, EXIF_FORMAT_LONG_UNSIGNED, -1,	"IPTC/NAA",		NULL, NULL },
-{ 0x8773, EXIF_FORMAT_UNDEFINED, -1,		"ColorProfile",		NULL, NULL },
+{ 0x8773, EXIF_FORMAT_UNDEFINED, -1,		"Exif.Image.InterColorProfile",		NULL, NULL },
 { 0x8825, EXIF_FORMAT_LONG_UNSIGNED, 1,		"GPSInfo",		"SubIFD GPS offset", NULL },
 { 0x8829, EXIF_FORMAT_SHORT_UNSIGNED, 1,	"Interlace",		NULL, NULL },
 { 0x882a, EXIF_FORMAT_SHORT, 1,			"TimeZoneOffset",	NULL, NULL },
@@ -1013,7 +1052,7 @@
 	return FALSE;
 }
 
-static ExifMarker jpeg_color_marker = { 0x8773, EXIF_FORMAT_UNDEFINED, -1, "ColorProfile", NULL, NULL };
+static ExifMarker jpeg_color_marker = { 0x8773, EXIF_FORMAT_UNDEFINED, -1, "Exif.Image.InterColorProfile", NULL, NULL };
 
 static gint exif_jpeg_parse_color(ExifData *exif, unsigned char *data, guint size)
 {
@@ -1508,8 +1547,6 @@
 	return NULL;
 }
 
-
-
 const gchar *exif_get_tag_description_by_key(const gchar *key)
 {
 	gint i;
--- a/src/image.c	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/image.c	Wed Apr 02 20:44:40 2008 +0000
@@ -364,7 +364,7 @@
 
 	if (imd->color_profile_use_image && exif)
 		{
-		item = exif_get_item(exif, "ColorProfile");
+		item = exif_get_item(exif, "Exif.Image.InterColorProfile");
 		if (!item)
 			{
 			gint cs;
--- a/src/preferences.c	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/preferences.c	Wed Apr 02 20:44:40 2008 +0000
@@ -28,6 +28,8 @@
 #include "ui_misc.h"
 #include "ui_tabcomp.h"
 #include "ui_utildlg.h"
+#include "bar_exif.h"
+#include "exif.h"
 
 #include <math.h>
 
@@ -330,6 +332,11 @@
 	if (buf && strlen(buf) > 0) color_profile_screen_file = g_strdup(buf);
 #endif
 
+	for (i=0; ExifUIList[i].key; i++)
+		{
+		ExifUIList[i].current = ExifUIList[i].temp;
+		}
+
 	l_conf = layout_config_get(layout_widget, &new_style);
 
 	if (new_style != layout_style ||
@@ -396,6 +403,41 @@
  *-----------------------------------------------------------------------------
  */ 
 
+static void exif_item_cb(GtkWidget *combo, gpointer data)
+{
+	gint *option = data;
+	*option = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
+}
+
+static void exif_item(GtkWidget *table, gint column, gint row, 
+		      const gchar *text, gint option, gint *option_c)
+{
+	GtkWidget *combo;
+	gint current = 0;
+
+	*option_c = option;
+
+	pref_table_label(table, column, row, text, 0.0);
+
+	combo = gtk_combo_box_new_text();
+
+	/* note: the order is important, it must match the values of 
+	 * EXIF_UI_OFF, _IFSET, _ON */
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Never"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("If set"));
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _("Always"));
+
+	gtk_combo_box_set_active(GTK_COMBO_BOX(combo), option);
+
+	g_signal_connect(G_OBJECT(combo), "changed",
+			 G_CALLBACK(exif_item_cb), option_c);
+
+	gtk_table_attach(GTK_TABLE(table), combo, 
+			 column + 1, column + 2, row, row + 1,
+			 GTK_EXPAND | GTK_FILL, 0, 0, 0);
+	gtk_widget_show(combo);
+}
+
 static void quality_menu_cb(GtkWidget *combo, gpointer data)
 {
 	gint *option = data;
@@ -1217,6 +1259,40 @@
 	gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
 	gtk_widget_show(button);
 
+	/* exif tab */
+
+	scrolled = gtk_scrolled_window_new(NULL, NULL);
+	gtk_container_set_border_width(GTK_CONTAINER(scrolled), PREF_PAD_BORDER);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
+				       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+	label = gtk_label_new(_("Exif"));
+	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, label);
+	gtk_widget_show(scrolled);
+
+	viewport = gtk_viewport_new(NULL, NULL);
+	gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
+	gtk_container_add(GTK_CONTAINER(scrolled), viewport);
+	gtk_widget_show(viewport);
+
+	vbox = gtk_vbox_new(FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(viewport), vbox);
+	gtk_widget_show(vbox);
+
+	group = pref_group_new(vbox, FALSE, _("What to show in properties dialog:"), 
+			       GTK_ORIENTATION_VERTICAL);
+	table = pref_table_new(group, 2, 2, FALSE, FALSE);
+
+	for (i = 0; ExifUIList[i].key; i++)
+		{
+		static gint cc;
+		const gchar *title;
+	  
+	  	title = exif_get_description_by_key(ExifUIList[i].key);
+		exif_item(table, 0, i, title, ExifUIList[i].current,
+			  &ExifUIList[i].temp);
+		}
+
 	/* advanced entry tab */
 
 	scrolled = gtk_scrolled_window_new(NULL, NULL);
--- a/src/rcfile.c	Wed Apr 02 12:12:50 2008 +0000
+++ b/src/rcfile.c	Wed Apr 02 20:44:40 2008 +0000
@@ -16,6 +16,7 @@
 #include "filelist.h"
 #include "slideshow.h"
 #include "ui_fileops.h"
+#include "bar_exif.h"
 
 
 /*
@@ -437,6 +438,13 @@
 	write_int_option(f, "divider_position_h", window_hdivider_pos);
 	write_int_option(f, "divider_position_v", window_vdivider_pos);
 
+	fprintf(f,"\n##### Exif #####\n# 0: never\n# 1: if set\n# 2: always\n");
+	for (i = 0; ExifUIList[i].key; i++)
+		{
+		fprintf(f,"exif_");
+		write_int_option(f, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
+		}
+
 	fprintf(f,"######################################################################\n");
 	fprintf(f,"#                      end of Geeqie config file                     #\n");
 	fprintf(f,"######################################################################\n");
@@ -464,6 +472,9 @@
 	gchar value_all[1024];
 	gint c,l,i;
 
+	for (i = 0; ExifUIList[i].key; i++)
+		ExifUIList[i].current = ExifUIList[i].default_value;
+
 	rc_path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_FILE_NAME, NULL);
 
 	rc_pathl = path_from_utf8(rc_path);
@@ -753,6 +764,12 @@
 		window_vdivider_pos = read_int_option(f, option,
 			"divider_position_v", value, window_vdivider_pos);
 
+		if (0 == strncasecmp(option, "exif_", 5))
+			{
+			for (i = 0; ExifUIList[i].key; i++)
+				if (0 == strcasecmp(option+5, ExifUIList[i].key))
+					ExifUIList[i].current = strtol(value, NULL, 10);
+		  	}
 		}
 
 	fclose(f);