Mercurial > geeqie.yaz
changeset 546:f852eb277913
Explode exif_get_formatted_by_key() in smaller functions prefixed "exif_build_f".
An helper macro was added to call them.
author | zas_ |
---|---|
date | Fri, 02 May 2008 21:34:26 +0000 |
parents | e421326e8b43 |
children | 95e0449d8f29 |
files | src/exif-common.c |
diffstat | 1 files changed, 314 insertions(+), 286 deletions(-) [+] |
line wrap: on
line diff
--- a/src/exif-common.c Fri May 02 20:56:59 2008 +0000 +++ b/src/exif-common.c Fri May 02 21:34:26 2008 +0000 @@ -149,6 +149,307 @@ return TRUE; } +static gchar *exif_build_fCamera(ExifData *exif) +{ + 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); + + 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 (model) + g_strstrip(model); + + 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); + } + } + + 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 && model2) ? " " : "", + (model2) ? model2 : "", + (software2 && (make || model2)) ? " (" : "", + (software2) ? software2 : "", + (software2 && (make || model2)) ? ")" : ""); + + g_free(make); + g_free(model); + g_free(software); + return text; +} + +static gchar *exif_build_fDateTime(ExifData *exif) +{ + 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; +} + +static gchar *exif_build_fShutterSpeed(ExifData *exif) +{ + 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)); + + /* 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("%s%.0fs", n > 1.0 ? "1/" : "", + n > 1.0 ? floor(n) : 1.0 / n); + } + return NULL; +} + +static gchar *exif_build_fAperture(ExifData *exif) +{ + 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; + + return g_strdup_printf("f/%.1f", n); +} + +static gchar *exif_build_fExposureBias(ExifData *exif) +{ + ExifRational *r; + gint sign; + double n; + + r = exif_get_rational(exif, "Exif.Photo.ExposureBiasValue", &sign); + if (!r) return NULL; + + n = exif_rational_to_double(r, sign); + return g_strdup_printf("%+.1f", n); +} + +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); +} + +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); + } + + 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; +} + +static gchar *exif_build_fISOSpeedRating(ExifData *exif) +{ + gchar *text; + + 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_fSubjectDistance(ExifData *exif) +{ + ExifRational *r; + gint sign; + double n; + + r = exif_get_rational(exif, "Exif.Photo.SubjectDistance", &sign); + if (!r) return NULL; + + if ((long)r->num == 0xffffffff) return g_strdup(_("infinity")); + if ((long)r->num == 0) return g_strdup(_("unknown")); + + n = exif_rational_to_double(r, sign); + if (n == 0.0) return _("unknown"); + return g_strdup_printf("%.3f m", n); +} + +static gchar *exif_build_fFlash(ExifData *exif) +{ + /* grr, flash is a bitmask... */ + GString *string; + gchar *text; + gint n; + gint v; + + if (!exif_get_integer(exif, "Exif.Photo.Flash", &n)) return NULL; + + /* Exif 2.1 only defines first 3 bits */ + if (n <= 0x07) return exif_get_data_as_text(exif, "Exif.Photo.Flash"); + + /* must be Exif 2.2 */ + string = g_string_new(""); + + /* 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) + { + 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; + } + + /* 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")); + + /* we ignore flash function (bit 5) */ + + /* red-eye (bit 6) */ + if ((n >> 5) & 0x01) string = append_comma_text(string, _("red-eye reduction")); + + text = string->str; + g_string_free(string, FALSE); + return text; +} + +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"); + + if (cs == 1) + { + name = _("sRGB"); + source = "ColorSpace"; + } + else if (cs == 2 || (interop_index && !strcmp(interop_index, "R03"))) + { + 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) + { + name = cmsTakeProductName(profile); + cmsCloseProfile(profile); + } + g_free(profile_data); + } +#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 */ @@ -160,293 +461,20 @@ if (key_valid) *key_valid = TRUE; - if (strcmp(key, "fCamera") == 0) - { - 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); - - 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 (model) - g_strstrip(model); - - 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); - } - } - - 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 && model2) ? " " : "", - (model2) ? model2 : "", - (software2 && (make || model2)) ? " (" : "", - (software2) ? software2 : "", - (software2 && (make || model2)) ? ")" : ""); - - g_free(make); - g_free(model); - g_free(software); - return text; - } - if (strcmp(key, "fDateTime") == 0) - { - 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; - } - if (strcmp(key, "fShutterSpeed") == 0) - { - 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)); - - /* 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("%s%.0fs", n > 1.0 ? "1/" : "", - n > 1.0 ? floor(n) : 1.0 / n); - } - return NULL; - } - if (strcmp(key, "fAperture") == 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; - - return g_strdup_printf("f/%.1f", n); - } - if (strcmp(key, "fExposureBias") == 0) - { - ExifRational *r; - gint sign; - double n; - - r = exif_get_rational(exif, "Exif.Photo.ExposureBiasValue", &sign); - if (!r) return NULL; - - 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.FocalLength"); - if (n == 0.0) return NULL; - 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); - } +#define EXIF_BUILD_FORMATTED_TAG(x) do { if (strcmp(key, #x) == 0) return exif_build##_##x(exif); } while (0) - return NULL; - } - if (strcmp(key, "fISOSpeedRating") == 0) - { - gchar *text; - - 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 (strcmp(key, "fSubjectDistance") == 0) - { - ExifRational *r; - gint sign; - double n; - - r = exif_get_rational(exif, "Exif.Photo.SubjectDistance", &sign); - if (!r) return NULL; - - if ((long)r->num == 0xffffffff) return g_strdup(_("infinity")); - if ((long)r->num == 0) return g_strdup(_("unknown")); - - 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; - - if (!exif_get_integer(exif, "Exif.Photo.Flash", &n)) return NULL; - - /* Exif 2.1 only defines first 3 bits */ - if (n <= 0x07) return exif_get_data_as_text(exif, "Exif.Photo.Flash"); - - /* must be Exif 2.2 */ - string = g_string_new(""); - - /* 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) - { - 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; - } - - /* 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")); - - /* we ignore flash function (bit 5) */ - - /* red-eye (bit 6) */ - if ((n >> 5) & 0x01) string = append_comma_text(string, _("red-eye reduction")); - - text = string->str; - g_string_free(string, FALSE); - return text; - } - if (strcmp(key, "fResolution") == 0) - { - 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; - } - 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; - - /* 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"); - - if (cs == 1) - { - name = _("sRGB"); - source = "ColorSpace"; - } - else if (cs == 2 || (interop_index && !strcmp(interop_index, "R03"))) - { - 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) - { - name = cmsTakeProductName(profile); - cmsCloseProfile(profile); - } - g_free(profile_data); - } -#endif - } - if (name[0] == 0 && source[0] == 0) return NULL; - return g_strdup_printf("%s (%s)", name, source); - } + 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;