Explode exif_get_formatted_by_key() in smaller functions prefixed "exif_build_f".
authorLaurent Monin <geeqie@norz.org>
Fri, 2 May 2008 21:34:26 +0000 (21:34 +0000)
committerLaurent Monin <geeqie@norz.org>
Fri, 2 May 2008 21:34:26 +0000 (21:34 +0000)
An helper macro was added to call them.

src/exif-common.c

index 621ba87..8fd6ce6 100644 (file)
@@ -149,305 +149,333 @@ static gint remove_suffix(gchar *str, const gchar *suffix, gint suffix_len)
        return TRUE;
 }
 
-gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_valid)
+static gchar *exif_build_fCamera(ExifData *exif)
 {
-       /* must begin with f, else not formatted */
-       if (key[0] != 'f')
+       gchar *text;
+       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;
+
+       if (make)
                {
-               if (key_valid) *key_valid = FALSE;
-               return NULL;
+               g_strstrip(make);
+
+               if (remove_suffix(make, " CORPORATION", 12)) { /* Nikon */ }
+               else if (remove_suffix(make, " Corporation", 12)) { /* Pentax */ }
+               else if (remove_suffix(make, " OPTICAL CO.,LTD", 16)) { /* OLYMPUS */ };
                }
 
-       if (key_valid) *key_valid = TRUE;
+       if (model)
+               g_strstrip(model);
 
-       if (strcmp(key, "fCamera") == 0)
+       if (software)
                {
-               gchar *text;
-               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;
-       
-               if (make)
-                       {
-                       g_strstrip(make);
+               gint i;
 
-                       if (remove_suffix(make, " CORPORATION", 12)) { /* Nikon */ }
-                       else if (remove_suffix(make, " Corporation", 12)) { /* Pentax */ }
-                       else if (remove_suffix(make, " OPTICAL CO.,LTD", 16)) { /* OLYMPUS */ };
-                       }
+               g_strstrip(software);
+               
+               /* remove superfluous spaces (pentax K100D) */
+               for (i = 0; software[i]; i++)
+                       if (software[i] == ' ' && software[i + 1] == ' ')
+                               {
+                               gint j;
+
+                               for (j = 1; software[i + j] == ' '; j++);
+                               memmove(software + i + 1, software + i + j, strlen(software + i + j) + 1);
+                               }
+               }
 
-               if (model)
-                       g_strstrip(model);
+       model2 = remove_common_prefix(make, model);
+       software2 = remove_common_prefix(model2, software);
 
-               if (software)
-                       {
-                       gint i;
-
-                       g_strstrip(software);
-                       
-                       /* remove superfluous spaces (pentax K100D) */
-                       for (i = 0; software[i]; i++)
-                               if (software[i] == ' ' && software[i + 1] == ' ')
-                                       {
-                                       gint j;
-
-                                       for (j = 1; software[i + j] == ' '; j++);
-                                       memmove(software + i + 1, software + i + j, strlen(software + i + j) + 1);
-                                       }
-                       }
+       text = g_strdup_printf("%s%s%s%s%s%s", (make) ? make : "", (make && model2) ? " " : "",
+                                              (model2) ? model2 : "",
+                                              (software2 && (make || model2)) ? " (" : "",
+                                              (software2) ? software2 : "",
+                                              (software2 && (make || model2)) ? ")" : "");
 
-               model2 = remove_common_prefix(make, model);
-               software2 = remove_common_prefix(model2, software);
+       g_free(make);
+       g_free(model);
+       g_free(software);
+       return text;
+}
 
-               text = g_strdup_printf("%s%s%s%s%s%s", (make) ? make : "", (make && model2) ? " " : "",
-                                                      (model2) ? model2 : "",
-                                                      (software2 && (make || model2)) ? " (" : "",
-                                                      (software2) ? software2 : "",
-                                                      (software2 && (make || model2)) ? ")" : "");
+static gchar *exif_build_fDateTime(ExifData *exif)
+{
+       gchar *text = exif_get_data_as_text(exif, "Exif.Photo.DateTimeOriginal");
+       gchar *subsec = NULL;
 
-               g_free(make);
-               g_free(model);
-               g_free(software);
-               return text;
-               }
-       if (strcmp(key, "fDateTime") == 0)
+       if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTimeOriginal");
+       if (!text)
                {
-               gchar *text = exif_get_data_as_text(exif, "Exif.Photo.DateTimeOriginal");
-               gchar *subsec = NULL;
-               if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTimeOriginal");
-               if (!text)
-                       {
-                       text = exif_get_data_as_text(exif, "Exif.Image.DateTime");
-                       if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTime");
-                       }
-               if (subsec)
-                       {
-                       gchar *tmp = text;
-                       text = g_strconcat(tmp, ".", subsec, NULL);
-                       g_free(tmp);
-                       g_free(subsec);
-                       }
-               return text;
+               text = exif_get_data_as_text(exif, "Exif.Image.DateTime");
+               if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTime");
                }
-       if (strcmp(key, "fShutterSpeed") == 0)
+       if (subsec)
                {
-               ExifRational *r;
-
-               r = exif_get_rational(exif, "Exif.Photo.ExposureTime", NULL);
-               if (r && r->num && r->den)
-                       {
-                       double n = (double)r->den / (double)r->num;
-                       return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "",
-                                                         n > 1.0 ? n : 1.0 / n);
-                       }
-               r = exif_get_rational(exif, "Exif.Photo.ShutterSpeedValue", NULL);
-               if (r && r->num  && r->den)
-                       {
-                       double n = pow(2.0, exif_rational_to_double(r, TRUE));
+               gchar *tmp = text;
+               text = g_strconcat(tmp, ".", subsec, NULL);
+               g_free(tmp);
+               g_free(subsec);
+               }
+       return text;
+}
 
-                       /* Correct exposure time to avoid values like 1/91s (seen on Minolta DImage 7) */
-                       if (n > 1.0 && (int)n - ((int)(n/10))*10 == 1) n--;
+static gchar *exif_build_fShutterSpeed(ExifData *exif)
+{
+       ExifRational *r;
 
-                       return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "",
-                                                         n > 1.0 ? floor(n) : 1.0 / n);
-                       }
-               return NULL;
+       r = exif_get_rational(exif, "Exif.Photo.ExposureTime", NULL);
+       if (r && r->num && r->den)
+               {
+               double n = (double)r->den / (double)r->num;
+               return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "",
+                                                 n > 1.0 ? n : 1.0 / n);
                }
-       if (strcmp(key, "fAperture") == 0)
+       r = exif_get_rational(exif, "Exif.Photo.ShutterSpeedValue", NULL);
+       if (r && r->num  && r->den)
                {
-               double n;
+               double n = pow(2.0, exif_rational_to_double(r, TRUE));
 
-               n = exif_get_rational_as_double(exif, "Exif.Photo.FNumber");
-               if (n == 0.0) n = exif_get_rational_as_double(exif, "Exif.Photo.ApertureValue");
-               if (n == 0.0) return NULL;
+               /* Correct exposure time to avoid values like 1/91s (seen on Minolta DImage 7) */
+               if (n > 1.0 && (int)n - ((int)(n/10))*10 == 1) n--;
 
-               return g_strdup_printf("f/%.1f", n);
+               return g_strdup_printf("%s%.0fs", n > 1.0 ? "1/" : "",
+                                                 n > 1.0 ? floor(n) : 1.0 / n);
                }
-       if (strcmp(key, "fExposureBias") == 0)
-               {
-               ExifRational *r;
-               gint sign;
-               double n;
+       return NULL;
+}
 
-               r = exif_get_rational(exif, "Exif.Photo.ExposureBiasValue", &sign);
-               if (!r) return NULL;
+static gchar *exif_build_fAperture(ExifData *exif)
+{
+       double n;
 
-               n = exif_rational_to_double(r, sign);
-               return g_strdup_printf("%+.1f", n);
-               }
-       if (strcmp(key, "fFocalLength") == 0)
-               {
-               double n;
+       n = exif_get_rational_as_double(exif, "Exif.Photo.FNumber");
+       if (n == 0.0) n = exif_get_rational_as_double(exif, "Exif.Photo.ApertureValue");
+       if (n == 0.0) return NULL;
 
-               n = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength");
-               if (n == 0.0) return NULL;
-               return g_strdup_printf("%.0f mm", n);
-               }
-       if (strcmp(key, "fFocalLength35mmFilm") == 0)
-               {
-               gint n;
-               double f, c;
+       return g_strdup_printf("f/%.1f", n);
+}
 
-               if (exif_get_integer(exif, "Exif.Photo.FocalLengthIn35mmFilm", &n) && n != 0)
-                       {
-                       return g_strdup_printf("%d mm", n);
-                       }
+static gchar *exif_build_fExposureBias(ExifData *exif)
+{
+       ExifRational *r;
+       gint sign;
+       double n;
 
-               f = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength");
-               c = get_crop_factor(exif);
+       r = exif_get_rational(exif, "Exif.Photo.ExposureBiasValue", &sign);
+       if (!r) return NULL;
 
-               if (f != 0.0 && c != 0.0)
-                       {
-                       return g_strdup_printf("%.0f mm", f * c);
-                       }
+       n = exif_rational_to_double(r, sign);
+       return g_strdup_printf("%+.1f", n);
+}
 
-               return NULL;
-               }
-       if (strcmp(key, "fISOSpeedRating") == 0)
-               {
-               gchar *text;
+static gchar *exif_build_fFocalLength(ExifData *exif)
+{
+       double n;
+
+       n = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength");
+       if (n == 0.0) return NULL;
+       return g_strdup_printf("%.0f mm", n);
+}
 
-               text = exif_get_data_as_text(exif, "Exif.Photo.ISOSpeedRatings");
-               /* kodak may set this instead */
-               if (!text) text = exif_get_data_as_text(exif, "Exif.Photo.ExposureIndex");
-               return text;
+static gchar *exif_build_fFocalLength35mmFilm(ExifData *exif)
+{
+       gint n;
+       double f, c;
+
+       if (exif_get_integer(exif, "Exif.Photo.FocalLengthIn35mmFilm", &n) && n != 0)
+               {
+               return g_strdup_printf("%d mm", n);
                }
-       if (strcmp(key, "fSubjectDistance") == 0)
+
+       f = exif_get_rational_as_double(exif, "Exif.Photo.FocalLength");
+       c = get_crop_factor(exif);
+
+       if (f != 0.0 && c != 0.0)
                {
-               ExifRational *r;
-               gint sign;
-               double n;
+               return g_strdup_printf("%.0f mm", f * c);
+               }
 
-               r = exif_get_rational(exif, "Exif.Photo.SubjectDistance", &sign);
-               if (!r) return NULL;
+       return NULL;
+}
 
-               if ((long)r->num == 0xffffffff) return g_strdup(_("infinity"));
-               if ((long)r->num == 0) return g_strdup(_("unknown"));
+static gchar *exif_build_fISOSpeedRating(ExifData *exif)
+{
+       gchar *text;
 
-               n = exif_rational_to_double(r, sign);
-               if (n == 0.0) return _("unknown");
-               return g_strdup_printf("%.3f m", n);
-               }
-       if (strcmp(key, "fFlash") == 0)
-               {
-               /* grr, flash is a bitmask... */
-               GString *string;
-               gchar *text;
-               gint n;
-               gint v;
+       text = exif_get_data_as_text(exif, "Exif.Photo.ISOSpeedRatings");
+       /* kodak may set this instead */
+       if (!text) text = exif_get_data_as_text(exif, "Exif.Photo.ExposureIndex");
+       return text;
+}
 
-               if (!exif_get_integer(exif, "Exif.Photo.Flash", &n)) return NULL;
+static gchar *exif_build_fSubjectDistance(ExifData *exif)
+{
+       ExifRational *r;
+       gint sign;
+       double n;
 
-               /* Exif 2.1 only defines first 3 bits */
-               if (n <= 0x07) return exif_get_data_as_text(exif, "Exif.Photo.Flash");
+       r = exif_get_rational(exif, "Exif.Photo.SubjectDistance", &sign);
+       if (!r) return NULL;
 
-               /* must be Exif 2.2 */
-               string = g_string_new("");
+       if ((long)r->num == 0xffffffff) return g_strdup(_("infinity"));
+       if ((long)r->num == 0) return g_strdup(_("unknown"));
 
-               /* flash fired (bit 0) */
-               string = g_string_append(string, (n & 0x01) ? _("yes") : _("no"));
+       n = exif_rational_to_double(r, sign);
+       if (n == 0.0) return _("unknown");
+       return g_strdup_printf("%.3f m", n);
+}
 
-               /* flash mode (bits 3, 4) */
-               v = (n >> 3) & 0x03;
-               if (v) string = append_comma_text(string, _("mode:"));
-               switch (v)
-                       {
-                       case 1:
-                               string = g_string_append(string, _("on"));
-                               break;
-                       case 2:
-                               string = g_string_append(string, _("off"));
-                               break;
-                       case 3:
-                               string = g_string_append(string, _("auto"));
-                               break;
-                       }
+static gchar *exif_build_fFlash(ExifData *exif)
+{
+       /* grr, flash is a bitmask... */
+       GString *string;
+       gchar *text;
+       gint n;
+       gint v;
 
-               /* return light (bits 1, 2) */
-               v = (n >> 1) & 0x03;
-               if (v == 2) string = append_comma_text(string, _("not detected by strobe"));
-               if (v == 3) string = append_comma_text(string, _("detected by strobe"));
+       if (!exif_get_integer(exif, "Exif.Photo.Flash", &n)) return NULL;
 
-               /* we ignore flash function (bit 5) */
+       /* Exif 2.1 only defines first 3 bits */
+       if (n <= 0x07) return exif_get_data_as_text(exif, "Exif.Photo.Flash");
 
-               /* red-eye (bit 6) */
-               if ((n >> 5) & 0x01) string = append_comma_text(string, _("red-eye reduction"));
+       /* must be Exif 2.2 */
+       string = g_string_new("");
 
-               text = string->str;
-               g_string_free(string, FALSE);
-               return text;
-               }
-       if (strcmp(key, "fResolution") == 0)
+       /* flash fired (bit 0) */
+       string = g_string_append(string, (n & 0x01) ? _("yes") : _("no"));
+
+       /* flash mode (bits 3, 4) */
+       v = (n >> 3) & 0x03;
+       if (v) string = append_comma_text(string, _("mode:"));
+       switch (v)
                {
-               ExifRational *rx, *ry;
-               gchar *units;
-               gchar *text;
+               case 1:
+                       string = g_string_append(string, _("on"));
+                       break;
+               case 2:
+                       string = g_string_append(string, _("off"));
+                       break;
+               case 3:
+                       string = g_string_append(string, _("auto"));
+                       break;
+               }
 
-               rx = exif_get_rational(exif, "Exif.Image.XResolution", NULL);
-               ry = exif_get_rational(exif, "Exif.Image.YResolution", NULL);
-               if (!rx || !ry) return NULL;
+       /* return light (bits 1, 2) */
+       v = (n >> 1) & 0x03;
+       if (v == 2) string = append_comma_text(string, _("not detected by strobe"));
+       if (v == 3) string = append_comma_text(string, _("detected by strobe"));
 
-               units = exif_get_data_as_text(exif, "Exif.Image.ResolutionUnit");
-               text = g_strdup_printf("%0.f x %0.f (%s/%s)", rx->den ? (double)rx->num / rx->den : 1.0,
-                                                             ry->den ? (double)ry->num / ry->den : 1.0,
-                                                             _("dot"), (units) ? units : _("unknown"));
+       /* we ignore flash function (bit 5) */
 
-               g_free(units);
-               return text;
-               }
-       if (strcmp(key, "fColorProfile") == 0)
-               {
-               const gchar *name = "";
-               const gchar *source = "";
-               unsigned char *profile_data;
-               guint profile_len;
-               profile_data = exif_get_color_profile(exif, &profile_len);
-               if (!profile_data)
-                       {
-                       gint cs;
-                       gchar *interop_index;
+       /* red-eye (bit 6) */
+       if ((n >> 5) & 0x01) string = append_comma_text(string, _("red-eye reduction"));
 
-                       /* ColorSpace == 1 specifies sRGB per EXIF 2.2 */
-                       if (!exif_get_integer(exif, "Exif.Photo.ColorSpace", &cs)) cs = 0;
-                       interop_index = exif_get_data_as_text(exif, "Exif.Iop.InteroperabilityIndex");
+       text = string->str;
+       g_string_free(string, FALSE);
+       return text;
+}
 
-                       if (cs == 1)
-                               {
-                               name = _("sRGB");
-                               source = "ColorSpace";
-                               }
-                       else if (cs == 2 || (interop_index && !strcmp(interop_index, "R03")))
-                               {
-                               name = _("AdobeRGB");
-                               source = (cs == 2) ? "ColorSpace" : "Iop";
-                               }
+static gchar *exif_build_fResolution(ExifData *exif)
+{
+       ExifRational *rx, *ry;
+       gchar *units;
+       gchar *text;
+
+       rx = exif_get_rational(exif, "Exif.Image.XResolution", NULL);
+       ry = exif_get_rational(exif, "Exif.Image.YResolution", NULL);
+       if (!rx || !ry) return NULL;
+
+       units = exif_get_data_as_text(exif, "Exif.Image.ResolutionUnit");
+       text = g_strdup_printf("%0.f x %0.f (%s/%s)", rx->den ? (double)rx->num / rx->den : 1.0,
+                                                     ry->den ? (double)ry->num / ry->den : 1.0,
+                                                     _("dot"), (units) ? units : _("unknown"));
+
+       g_free(units);
+       return text;
+}
+
+static gchar *exif_build_fColorProfile(ExifData *exif)
+{
+       const gchar *name = "";
+       const gchar *source = "";
+       unsigned char *profile_data;
+       guint profile_len;
+
+       profile_data = exif_get_color_profile(exif, &profile_len);
+       if (!profile_data)
+               {
+               gint cs;
+               gchar *interop_index;
+
+               /* ColorSpace == 1 specifies sRGB per EXIF 2.2 */
+               if (!exif_get_integer(exif, "Exif.Photo.ColorSpace", &cs)) cs = 0;
+               interop_index = exif_get_data_as_text(exif, "Exif.Iop.InteroperabilityIndex");
 
-                       g_free(interop_index);
+               if (cs == 1)
+                       {
+                       name = _("sRGB");
+                       source = "ColorSpace";
                        }
-               else
+               else if (cs == 2 || (interop_index && !strcmp(interop_index, "R03")))
                        {
-                       source = _("embedded");
+                       name = _("AdobeRGB");
+                       source = (cs == 2) ? "ColorSpace" : "Iop";
+                       }
+
+               g_free(interop_index);
+               }
+       else
+               {
+               source = _("embedded");
 #ifdef HAVE_LCMS
 
+                       {
+                       cmsHPROFILE profile;
+
+                       profile = cmsOpenProfileFromMem(profile_data, profile_len);
+                       if (profile)
                                {
-                               cmsHPROFILE profile;
-
-                               profile = cmsOpenProfileFromMem(profile_data, profile_len);
-                               if (profile)
-                                       {
-                                       name = cmsTakeProductName(profile);
-                                       cmsCloseProfile(profile);
-                                       }
-                               g_free(profile_data);
+                               name = cmsTakeProductName(profile);
+                               cmsCloseProfile(profile);
                                }
-#endif
+                       g_free(profile_data);
                        }
-               if (name[0] == 0 && source[0] == 0) return NULL;
-               return g_strdup_printf("%s (%s)", name, source);
+#endif
+               }
+       if (name[0] == 0 && source[0] == 0) return NULL;
+       return g_strdup_printf("%s (%s)", name, source);
+}
+
+gchar *exif_get_formatted_by_key(ExifData *exif, const gchar *key, gint *key_valid)
+{
+       /* must begin with f, else not formatted */
+       if (key[0] != 'f')
+               {
+               if (key_valid) *key_valid = FALSE;
+               return NULL;
                }
 
+       if (key_valid) *key_valid = TRUE;
+
+#define EXIF_BUILD_FORMATTED_TAG(x) do { if (strcmp(key, #x) == 0) return exif_build##_##x(exif); } while (0)
+
+       EXIF_BUILD_FORMATTED_TAG(fCamera);
+       EXIF_BUILD_FORMATTED_TAG(fDateTime);
+       EXIF_BUILD_FORMATTED_TAG(fShutterSpeed);
+       EXIF_BUILD_FORMATTED_TAG(fAperture);
+       EXIF_BUILD_FORMATTED_TAG(fExposureBias);
+       EXIF_BUILD_FORMATTED_TAG(fFocalLength);
+       EXIF_BUILD_FORMATTED_TAG(fFocalLength35mmFilm);
+       EXIF_BUILD_FORMATTED_TAG(fISOSpeedRating);
+       EXIF_BUILD_FORMATTED_TAG(fSubjectDistance);
+       EXIF_BUILD_FORMATTED_TAG(fFlash);
+       EXIF_BUILD_FORMATTED_TAG(fResolution);
+       EXIF_BUILD_FORMATTED_TAG(fColorProfile);
+
        if (key_valid) *key_valid = FALSE;
        return NULL;
 }