mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
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 Deserialization DMS Old code = 89.5686111111 DMS New code = 89.5688643 The new test tries to serialize a higher precision coordinate. The types of the coordinates are also guint32 instead of gint like previously. guint32 is the type of the fraction components in the exif. https://bugzilla.gnome.org/show_bug.cgi?id=767537
This commit is contained in:
parent
d423406e0a
commit
5dd720e064
2 changed files with 17 additions and 14 deletions
|
@ -2090,9 +2090,9 @@ serialize_geo_coordinate (GstExifWriter * writer, const GstTagList * taglist,
|
||||||
{
|
{
|
||||||
gboolean latitude;
|
gboolean latitude;
|
||||||
gdouble value;
|
gdouble value;
|
||||||
gint degrees;
|
guint32 degrees;
|
||||||
gint minutes;
|
guint32 minutes;
|
||||||
gint seconds;
|
guint32 seconds_numerator, seconds_denominator;
|
||||||
guint32 offset;
|
guint32 offset;
|
||||||
|
|
||||||
latitude = exiftag->exif_tag == EXIF_TAG_GPS_LATITUDE; /* exif tag for latitude */
|
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 */
|
/* now write the degrees stuff */
|
||||||
GST_LOG ("Converting geo location %lf to degrees", value);
|
GST_DEBUG ("Converting %lf degrees geo location to HMS", value);
|
||||||
degrees = (gint) value;
|
degrees = (guint32) value;
|
||||||
value -= degrees;
|
value -= degrees;
|
||||||
minutes = (gint) (value * 60);
|
minutes = (guint32) (value * 60);
|
||||||
value = (value * 60) - minutes;
|
value = (value * 60) - minutes;
|
||||||
seconds = (gint) (value * 60);
|
seconds_denominator = 10000000UL;
|
||||||
GST_LOG ("Converted geo location to %d.%d'%d'' degrees", degrees,
|
seconds_numerator = (guint32) (value * 60 * seconds_denominator);
|
||||||
minutes, seconds);
|
|
||||||
|
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);
|
offset = gst_byte_writer_get_size (&writer->datawriter);
|
||||||
gst_exif_writer_write_tag_header (writer, exiftag->exif_tag,
|
gst_exif_writer_write_tag_header (writer, exiftag->exif_tag,
|
||||||
EXIF_TYPE_RATIONAL, 3, offset, NULL);
|
EXIF_TYPE_RATIONAL, 3, offset, NULL);
|
||||||
gst_exif_writer_write_rational_data (writer, degrees, 1);
|
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, minutes, 1);
|
||||||
gst_exif_writer_write_rational_data (writer, seconds, 1);
|
gst_exif_writer_write_rational_data (writer, seconds_numerator,
|
||||||
|
seconds_denominator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
|
@ -2251,12 +2254,11 @@ deserialize_geo_coordinate (GstExifReader * exif_reader,
|
||||||
gst_util_fraction_to_double (degrees_n, degrees_d, °rees);
|
gst_util_fraction_to_double (degrees_n, degrees_d, °rees);
|
||||||
gst_util_fraction_to_double (minutes_n, minutes_d, &minutes);
|
gst_util_fraction_to_double (minutes_n, minutes_d, &minutes);
|
||||||
gst_util_fraction_to_double (seconds_n, seconds_d, &seconds);
|
gst_util_fraction_to_double (seconds_n, seconds_d, &seconds);
|
||||||
|
|
||||||
minutes += seconds / 60;
|
minutes += seconds / 60;
|
||||||
degrees += minutes / 60;
|
degrees += minutes / 60;
|
||||||
degrees *= multiplier;
|
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,
|
gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
|
||||||
exiftag->gst_tag, degrees, NULL);
|
exiftag->gst_tag, degrees, NULL);
|
||||||
|
|
||||||
|
|
|
@ -1676,10 +1676,11 @@ GST_START_TEST (test_exif_tags_serialization_deserialization)
|
||||||
g_value_unset (&value);
|
g_value_unset (&value);
|
||||||
|
|
||||||
g_value_init (&value, G_TYPE_DOUBLE);
|
g_value_init (&value, G_TYPE_DOUBLE);
|
||||||
g_value_set_double (&value, 30.5);
|
g_value_set_double (&value, 40.3456784);
|
||||||
do_simple_exif_tag_serialization_deserialization
|
do_simple_exif_tag_serialization_deserialization
|
||||||
(GST_TAG_GEO_LOCATION_LATITUDE, &value);
|
(GST_TAG_GEO_LOCATION_LATITUDE, &value);
|
||||||
g_value_set_double (&value, -12.125);
|
g_value_set_double (&value, -12.1250865);
|
||||||
|
|
||||||
do_simple_exif_tag_serialization_deserialization
|
do_simple_exif_tag_serialization_deserialization
|
||||||
(GST_TAG_GEO_LOCATION_LATITUDE, &value);
|
(GST_TAG_GEO_LOCATION_LATITUDE, &value);
|
||||||
g_value_set_double (&value, 0);
|
g_value_set_double (&value, 0);
|
||||||
|
|
Loading…
Reference in a new issue