Commit 5dd720e0 authored by Paulo Neves's avatar Paulo Neves Committed by Sebastian Dröge
Browse files

exiftag: Increase serialized geo precision

The serialization of double typed geographical
coordinates to DMS system supported by the exif
standards was previously truncated without need.

The previous code truncated the seconds part of
the coordinate to a fraction with denominator
equal to 1 causing a bug on the deserialization
when the test for the coordinate to be serialized
was more precise.

This patch applies a 10E6 multiplier to the numerator
equal to the denominator of the rational number.

Eg. Latitude = 89.5688643 Serialization

DMS Old code = 89/1 deg, 34/1 min, 7/1 sec
DMS New code = 89/1 deg, 34/1 min, 79114800UL/10000000UL


DMS Old code = 89.5686111111
DMS New code = 89.5688643

The new test tries to serialize a higher precision

The types of the coordinates are also guint32 instead
of gint like previously. guint32 is the type of the
fraction components in the exif.
parent d423406e
......@@ -2090,9 +2090,9 @@ serialize_geo_coordinate (GstExifWriter * writer, const GstTagList * taglist,
gboolean latitude;
gdouble value;
gint degrees;
gint minutes;
gint seconds;
guint32 degrees;
guint32 minutes;
guint32 seconds_numerator, seconds_denominator;
guint32 offset;
latitude = exiftag->exif_tag == EXIF_TAG_GPS_LATITUDE; /* exif tag for latitude */
......@@ -2120,21 +2120,24 @@ serialize_geo_coordinate (GstExifWriter * writer, const GstTagList * taglist,
/* now write the degrees stuff */
GST_LOG ("Converting geo location %lf to degrees", value);
degrees = (gint) value;
GST_DEBUG ("Converting %lf degrees geo location to HMS", value);
degrees = (guint32) value;
value -= degrees;
minutes = (gint) (value * 60);
minutes = (guint32) (value * 60);
value = (value * 60) - minutes;
seconds = (gint) (value * 60);
GST_LOG ("Converted geo location to %d.%d'%d'' degrees", degrees,
minutes, seconds);
seconds_denominator = 10000000UL;
seconds_numerator = (guint32) (value * 60 * seconds_denominator);
GST_DEBUG ("Converted rational geo location to %u/%u %u/%u %u/%u degrees ",
degrees, 1U, minutes, 1U, seconds_numerator, seconds_denominator);
offset = gst_byte_writer_get_size (&writer->datawriter);
gst_exif_writer_write_tag_header (writer, exiftag->exif_tag,
gst_exif_writer_write_rational_data (writer, degrees, 1);
gst_exif_writer_write_rational_data (writer, minutes, 1);
gst_exif_writer_write_rational_data (writer, seconds, 1);
gst_exif_writer_write_rational_data (writer, seconds_numerator,
static gint
......@@ -2251,12 +2254,11 @@ deserialize_geo_coordinate (GstExifReader * exif_reader,
gst_util_fraction_to_double (degrees_n, degrees_d, &degrees);
gst_util_fraction_to_double (minutes_n, minutes_d, &minutes);
gst_util_fraction_to_double (seconds_n, seconds_d, &seconds);
minutes += seconds / 60;
degrees += minutes / 60;
degrees *= multiplier;
GST_DEBUG ("Adding %s tag: %lf", exiftag->gst_tag, degrees);
GST_DEBUG ("Adding %s tag: %lf degrees", exiftag->gst_tag, degrees);
gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
exiftag->gst_tag, degrees, NULL);
......@@ -1676,10 +1676,11 @@ GST_START_TEST (test_exif_tags_serialization_deserialization)
g_value_unset (&value);
g_value_init (&value, G_TYPE_DOUBLE);
g_value_set_double (&value, 30.5);
g_value_set_double (&value, 40.3456784);
g_value_set_double (&value, -12.125);
g_value_set_double (&value, -12.1250865);
g_value_set_double (&value, 0);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment