various exif improvements based on patch by Uwe Ohse
authorVladimir Nadvornik <nadvornik@suse.cz>
Wed, 2 Apr 2008 20:44:40 +0000 (20:44 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Wed, 2 Apr 2008 20:44:40 +0000 (20:44 +0000)
try to compute 35mm focal length

src/bar_exif.c
src/bar_exif.h
src/exif-common.c
src/exif.c
src/image.c
src/preferences.c
src/rcfile.c

index 38b2c51..7a0b2a6 100644 (file)
@@ -36,6 +36,7 @@ static const gchar *bar_exif_key_list_real[] = {
        "fExposureBias",
        "fISOSpeedRating",
        "fFocalLength",
+       "fFocalLength35mmFilm",
        "fSubjectDistance",
        "Exif.Photo.MeteringMode",
        "fFlash",
@@ -49,6 +50,27 @@ static const gchar *bar_exif_key_list_real[] = {
 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 void table_add_line_custom(GtkWidget *table, gint x, gint y,
 }
 
 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 @@ static GtkWidget *table_add_line(GtkWidget *table, gint x, gint y,
        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 @@ struct _ExifBar
        GtkWidget *table;
        GtkWidget *advanced_scrolled;
        GtkWidget *listview;
+       GtkWidget **keys;
        GtkWidget **labels;
 
        GtkWidget *custom_sep;
@@ -185,12 +210,27 @@ static void bar_exif_update(ExifBar *eb)
        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_update(ExifBar *eb)
 
 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 @@ static void bar_exif_destroy(GtkWidget *widget, gpointer data)
 {
        ExifBar *eb = data;
 
+       g_free(eb->keys);
        g_free(eb->labels);
        file_data_unref(eb->fd);
        g_free(eb);
@@ -533,10 +572,15 @@ GtkWidget *bar_exif_new(gint show_title, FileData *fd, gint advanced, GtkWidget
        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 @@ GtkWidget *bar_exif_new(gint show_title, FileData *fd, gint advanced, GtkWidget
                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]);
                }
 
index 0f67374..3214dc9 100644 (file)
 #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);
index eb827b2..73cc075 100644 (file)
@@ -38,6 +38,7 @@ ExifFormattedText ExifFormattedList[] = {
        { "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 @@ static ExifTextList ExifFlashList[] = {
        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 @@ static GString *append_comma_text(GString *string, const gchar *text)
        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 *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_val
                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 @@ gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_val
 
                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)
                {
index 768d5bd..bf5b177 100644 (file)
@@ -109,6 +109,36 @@ ExifFormatAttrib ExifFormatList[] = {
  * 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 @@ static ExifTextList ExifSubjectRangeList[] = {
        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 @@ ExifMarker ExifKnownMarkersList[] = {
 { 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 @@ ExifMarker ExifKnownMarkersList[] = {
 { 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 @@ ExifMarker ExifKnownMarkersList[] = {
 { 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 @@ static gint exif_jpeg_segment_find(unsigned char *data, guint size,
        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 @@ ExifRational *exif_item_get_rational(ExifItem *item, gint *sign)
        return NULL;
 }
 
-
-
 const gchar *exif_get_tag_description_by_key(const gchar *key)
 {
        gint i;
index 5f6a1be..a80ef1a 100644 (file)
@@ -364,7 +364,7 @@ static gint image_post_process_color(ImageWindow *imd, gint start_row, ExifData
 
        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;
index 186e852..ac40207 100644 (file)
@@ -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 @@ static void config_window_apply(void)
        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 config_window_apply_cb(GtkWidget *widget, gpointer data)
  *-----------------------------------------------------------------------------
  */ 
 
+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 @@ static void config_window_create(void)
        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);
index 159d199..19d75e4 100644 (file)
@@ -16,6 +16,7 @@
 #include "filelist.h"
 #include "slideshow.h"
 #include "ui_fileops.h"
+#include "bar_exif.h"
 
 
 /*
@@ -437,6 +438,13 @@ void save_options(void)
        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 @@ void load_options(void)
        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 @@ void load_options(void)
                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);