Revision: 1147
http://geeqie.svn.sourceforge.net/geeqie/?rev=1147&view=rev
Author: nadvornik
Date: 2008-10-01 20:57:56 +0000 (Wed, 01 Oct 2008)
Log Message:
-----------
Add support for GPSInfo - patch by Klaus Ethgen
Modified Paths:
--------------
trunk/src/bar_exif.c
trunk/src/exif-common.c
trunk/src/exif.c
trunk/src/exif.h
trunk/src/exiv2.cc
Modified: trunk/src/bar_exif.c
===================================================================
--- trunk/src/bar_exif.c 2008-09-29 21:17:19 UTC (rev 1146)
+++ trunk/src/bar_exif.c 2008-10-01 20:57:56 UTC (rev 1147)
@@ -46,6 +46,8 @@
{ 0, 0, EXIF_UI_IFSET, "formatted.SubjectDistance"},
{ 0, 0, EXIF_UI_IFSET, "formatted.Resolution"},
{ 0, 0, EXIF_UI_IFSET, "Exif.Image.Orientation"},
+ { 0, 0, EXIF_UI_IFSET, "formatted.GPSPosition"},
+ { 0, 0, EXIF_UI_IFSET, "formatted.GPSAltitude"},
{ 0, 0, EXIF_UI_IFSET, "Exif.Image.ImageDescription"},
{ 0, 0, EXIF_UI_IFSET, "Exif.Image.Copyright"},
{ 0, 0, EXIF_UI_OFF, NULL}
Modified: trunk/src/exif-common.c
===================================================================
--- trunk/src/exif-common.c 2008-09-29 21:17:19 UTC (rev 1146)
+++ trunk/src/exif-common.c 2008-10-01 20:57:56 UTC (rev 1147)
@@ -429,7 +429,79 @@
return g_strdup_printf("%s (%s)", name, source);
}
+static gchar *exif_build_formatted_GPSPosition(ExifData *exif)
+{
+ GString *string;
+ gchar *text, *ref;
+ ExifRational *value;
+ ExifItem *item;
+ guint i;
+ gdouble p, p3;
+ gulong p1, p2;
+ string = g_string_new("");
+
+ item = exif_get_item(exif, "Exif.GPSInfo.GPSLatitude");
+ ref = exif_get_data_as_text(exif, "Exif.GPSInfo.GPSLatitudeRef");
+ if (item && ref)
+ {
+ p = 0;
+ for (i = 0; i < exif_item_get_elements(item); i++)
+ {
+ value = exif_item_get_rational(item, NULL, i);
+ if (value && value->num && value->den)
+ p += (gdouble)value->num / (gdouble)value->den
/ pow(60.0, (gdouble)i);
+ }
+ p1 = (gint)p;
+ p2 = (gint)((p - p1)*60);
+ p3 = ((p - p1)*60 - p2)*60;
+
+ g_string_append_printf(string, "%0d\xB0 %0d' %0.2f\" %.1s", p1,
p2, p3, ref);
+ } // if (item && ref)
+
+ item = exif_get_item(exif, "Exif.GPSInfo.GPSLongitude");
+ ref = exif_get_data_as_text(exif, "Exif.GPSInfo.GPSLongitudeRef");
+ if (item && ref)
+ {
+ p = 0;
+ for (i = 0; i < exif_item_get_elements(item); i++)
+ {
+ value = exif_item_get_rational(item, NULL, i);
+ if (value && value->num && value->den)
+ p += (gdouble)value->num / (gdouble)value->den /
pow(60.0, (gdouble)i);
+ }
+ p1 = (gint)p;
+ p2 = (gint)((p - p1)*60);
+ p3 = ((p - p1)*60 - p2)*60;
+
+ g_string_append_printf(string, ", %0d\xB0 %0d' %0.2f\" %.1s",
p1, p2, p3, ref);
+ } // if (item && ref)
+
+ text = string->str;
+ g_string_free(string, FALSE);
+
+ return text;
+} // static gchar *exif_build_forma...
+
+static gchar *exif_build_formatted_GPSAltitude(ExifData *exif)
+{
+ ExifRational *r;
+ ExifItem *item;
+ gdouble alt;
+ gint ref;
+
+ item = exif_get_item(exif, "Exif.GPSInfo.GPSAltitudeRef");
+ r = exif_get_rational(exif, "Exif.GPSInfo.GPSAltitude", NULL);
+
+ if (!r || !item) return NULL;
+
+ alt = exif_rational_to_double(r, 0);
+ exif_item_get_integer(item, &ref);
+
+ return g_strdup_printf("%0.f m %s", alt, (ref==0)?_("Above Sea
Level"):_("Below Sea Level"));
+}
+
+
/* List of custom formatted pseudo-exif tags */
#define EXIF_FORMATTED_TAG(name, label) { "formatted."#name, label,
exif_build_formatted##_##name }
@@ -446,6 +518,8 @@
EXIF_FORMATTED_TAG(Flash, N_("Flash")),
EXIF_FORMATTED_TAG(Resolution, N_("Resolution")),
EXIF_FORMATTED_TAG(ColorProfile, N_("Color profile")),
+ EXIF_FORMATTED_TAG(GPSPosition, N_("GPS position")),
+ EXIF_FORMATTED_TAG(GPSAltitude, N_("GPS altitude")),
{ NULL, NULL, NULL }
};
@@ -497,7 +571,7 @@
ExifItem *item;
item = exif_get_item(exif, key);
- return exif_item_get_rational(item, sign);
+ return exif_item_get_rational(item, sign, 0);
}
gchar *exif_get_data_as_text(ExifData *exif, const gchar *key)
Modified: trunk/src/exif.c
===================================================================
--- trunk/src/exif.c 2008-09-29 21:17:19 UTC (rev 1146)
+++ trunk/src/exif.c 2008-10-01 20:57:56 UTC (rev 1147)
@@ -28,12 +28,12 @@
* Unsupported at this time:
* IFD1 (thumbnail)
* MakerNote
- * GPSInfo
*
* TODO:
* Convert data to useable form in the ??_as_text function for:
* ComponentsConfiguration
* UserComment (convert this to UTF-8?)
+ * Add support for marker tag 0x0000
*
This program is free software; you can redistribute it and/or modify
@@ -103,6 +103,7 @@
/* tags that are special, or need special treatment */
#define TAG_EXIFOFFSET 0x8769
#define TAG_EXIFMAKERNOTE 0x927c
+#define TAG_GPSOFFSET 0x8825
/*
@@ -437,6 +438,44 @@
EXIF_MARKER_LIST_END
};
+ExifMarker ExifKnownGPSInfoMarkersList[] = {
+ /* The following do not work at the moment as the tag value 0x0000 has
a
+ * special meaning. */
+ /* { 0x0000, EXIF_FORMAT_BYTE, -1, "Exif.GPSInfo.GPSVersionID", NULL,
NULL }, */
+ { 0x0001, EXIF_FORMAT_STRING, 2, "Exif.GPSInfo.GPSLatitudeRef", NULL,
NULL },
+ { 0x0002, EXIF_FORMAT_RATIONAL_UNSIGNED, 3,
"Exif.GPSInfo.GPSLatitude", NULL, NULL },
+ { 0x0003, EXIF_FORMAT_STRING, 2, "Exif.GPSInfo.GPSLongitudeRef", NULL,
NULL },
+ { 0x0004, EXIF_FORMAT_RATIONAL_UNSIGNED, 3,
"Exif.GPSInfo.GPSLongitude", NULL, NULL },
+ { 0x0005, EXIF_FORMAT_BYTE_UNSIGNED, 1, "Exif.GPSInfo.GPSAltitudeRef",
NULL, NULL },
+ { 0x0006, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,
"Exif.GPSInfo.GPSAltitude", NULL, NULL },
+ { 0x0007, EXIF_FORMAT_RATIONAL_UNSIGNED, 3,
"Exif.GPSInfo.GPSTimeStamp", NULL, NULL },
+ { 0x0008, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSSatellites", NULL,
NULL },
+ { 0x0009, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSStatus", NULL, NULL
},
+ { 0x000a, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSMeasureMode", NULL,
NULL },
+ { 0x000b, EXIF_FORMAT_RATIONAL_UNSIGNED, -1, "Exif.GPSInfo.GPSDOP",
NULL, NULL },
+ { 0x000c, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSSpeedRef", NULL,
NULL },
+ { 0x000d, EXIF_FORMAT_RATIONAL_UNSIGNED, -1, "Exif.GPSInfo.GPSSpeed",
NULL, NULL },
+ { 0x000e, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSTrackRef", NULL,
NULL },
+ { 0x000f, EXIF_FORMAT_RATIONAL_UNSIGNED, -1, "Exif.GPSInfo.GPSTrack",
NULL, NULL },
+ { 0x0010, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSImgDirectionRef",
NULL, NULL },
+ { 0x0011, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,
"Exif.GPSInfo.GPSImgDirection", NULL, NULL },
+ { 0x0012, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSMapDatum", NULL,
NULL },
+ { 0x0013, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSDestLatitudeRef",
NULL, NULL },
+ { 0x0014, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,
"Exif.GPSInfo.GPSDestLatitude", NULL, NULL },
+ { 0x0015, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSDestLongitudeRef",
NULL, NULL },
+ { 0x0016, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,
"Exif.GPSInfo.GPSDestLongitude", NULL, NULL },
+ { 0x0017, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSDestBearingRef",
NULL, NULL },
+ { 0x0018, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,
"Exif.GPSInfo.GPSDestBearing", NULL, NULL },
+ { 0x0019, EXIF_FORMAT_STRING, -1, "Exif.GPSInfo.GPSDestDistanceRef",
NULL, NULL },
+ { 0x001a, EXIF_FORMAT_RATIONAL_UNSIGNED, -1,
"Exif.GPSInfo.GPSDestDistance", NULL, NULL },
+ { 0x001b, EXIF_FORMAT_UNDEFINED, -1,
"Exif.GPSInfo.GPSProcessingMethod", NULL, NULL },
+ { 0x001c, EXIF_FORMAT_UNDEFINED, -1,
"Exif.GPSInfo.GPSAreaInformation", NULL, NULL },
+ { 0x001d, EXIF_FORMAT_RATIONAL_UNSIGNED, 3,
"Exif.GPSInfo.GPSDateStamp", NULL, NULL },
+ { 0x001e, EXIF_FORMAT_SHORT, -1, "Exif.GPSInfo.GPSDifferential", NULL,
NULL },
+
+ EXIF_MARKER_LIST_END
+};
+
ExifMarker ExifUnknownMarkersList[] = {
{ 0x0000, EXIF_FORMAT_UNKNOWN, 0, "unknown", NULL, NULL },
{ 0x0000, EXIF_FORMAT_BYTE_UNSIGNED, -1, "unknown", NULL, NULL },
@@ -911,6 +950,9 @@
case TAG_EXIFOFFSET:
exif_parse_IFD_table(exif, tiff, data_val,
size, bo, level + 1, list);
break;
+ case TAG_GPSOFFSET:
+ exif_parse_IFD_table(exif, tiff, data_val,
size, bo, level + 1, ExifKnownGPSInfoMarkersList);
+ break;
case TAG_EXIFMAKERNOTE:
format_exif_makernote_parse(exif, tiff,
data_val, size, bo);
break;
@@ -1436,15 +1478,16 @@
}
-ExifRational *exif_item_get_rational(ExifItem *item, gint *sign)
+ExifRational *exif_item_get_rational(ExifItem *item, gint *sign, gint n)
{
if (!item) return NULL;
+ if (n >= (gint)item->elements) return NULL;
if (item->format == EXIF_FORMAT_RATIONAL ||
item->format == EXIF_FORMAT_RATIONAL_UNSIGNED)
{
if (sign) *sign = (item->format == EXIF_FORMAT_RATIONAL);
- return &((ExifRational *)(item->data))[0];
+ return &((ExifRational *)(item->data))[n];
}
return NULL;
@@ -1463,6 +1506,13 @@
i++;
}
+ i = 0;
+ while (ExifKnownGPSInfoMarkersList[i].tag > 0)
+ {
+ if (strcmp(key, ExifKnownGPSInfoMarkersList[i].key) == 0) return
_(ExifKnownGPSInfoMarkersList[i].description);
+ i++;
+ }
+
return NULL;
}
Modified: trunk/src/exif.h
===================================================================
--- trunk/src/exif.h 2008-09-29 21:17:19 UTC (rev 1146)
+++ trunk/src/exif.h 2008-10-01 20:57:56 UTC (rev 1147)
@@ -133,7 +133,7 @@
const gchar *exif_item_get_format_name(ExifItem *item, gint brief);
gchar *exif_item_get_data_as_text(ExifItem *item);
gint exif_item_get_integer(ExifItem *item, gint *value);
-ExifRational *exif_item_get_rational(ExifItem *item, gint *sign);
+ExifRational *exif_item_get_rational(ExifItem *item, gint *sign, gint n);
gchar *exif_item_get_string(ExifItem *item, gint idx);
Modified: trunk/src/exiv2.cc
===================================================================
--- trunk/src/exiv2.cc 2008-09-29 21:17:19 UTC (rev 1146)
+++ trunk/src/exiv2.cc 2008-10-01 20:57:56 UTC (rev 1147)
@@ -512,11 +512,12 @@
}
}
-ExifRational *exif_item_get_rational(ExifItem *item, gint *sign)
+ExifRational *exif_item_get_rational(ExifItem *item, gint *sign, gint n)
{
try {
if (!item) return NULL;
- Exiv2::Rational v = ((Exiv2::Metadatum *)item)->toRational();
+ if (n >= exif_item_get_elements(item)) return NULL;
+ Exiv2::Rational v = ((Exiv2::Metadatum *)item)->toRational(n);
static ExifRational ret;
ret.num = v.first;
ret.den = v.second;
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn