Issue #5863: No namespace info available for XMP prefix.

Adding 2 temporary patches for our builds:

- gexiv2-mr20.patch: to be applied over GExiv2 0.12.1. This patch is
  already contributed upstream so it won't be necessary once GExiv2
  0.12.2 is released.
- 0001-Issue-5863-do-not-raise-WARNINGs-on-Exiv2-unsupporte.patch: to be
  applied over GIMP master branch itself. It depends on GExiv2 0.12.2 so
  I cannot push it to master until we bump GExiv2 minimum requirement
  (which can only happen when v0.12.2 is out then available in Debian
  testing, as per our dependency rules).

For the time being, while waiting for upstream releases, all we can do
is wait and apply these patches on our own dev builds (because this bug
is annoying and was reported to us quite a few times already).
This commit is contained in:
Jehan 2020-12-14 21:03:43 +01:00
parent d90d622c92
commit 7ed68556c7
2 changed files with 814 additions and 0 deletions

View File

@ -0,0 +1,66 @@
From d164c9922801631631ba8f275b0b2ce91c71d6df Mon Sep 17 00:00:00 2001
From: Jehan <jehan@girinstud.io>
Date: Sun, 8 Nov 2020 18:54:53 +0100
Subject: [PATCH] Issue #5863: do not raise WARNINGs on Exiv2 unsupported tags
on loading.
WIP. Waiting for GExiv2 to merge a patch I submitted:
https://gitlab.gnome.org/GNOME/gexiv2/-/merge_requests/20
We will have to bump GExiv2 dependency as well (so master only fix).
---
libgimpbase/gimpmetadata.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/libgimpbase/gimpmetadata.c b/libgimpbase/gimpmetadata.c
index 2170d4a4f4..ef312be670 100644
--- a/libgimpbase/gimpmetadata.c
+++ b/libgimpbase/gimpmetadata.c
@@ -644,12 +644,20 @@ gimp_metadata_deserialize_text (GMarkupParseContext *context,
if (value)
{
GExiv2Metadata *g2_metadata = GEXIV2_METADATA (parse_data->metadata);
+ GError *error = NULL;
gchar **values;
- values = gexiv2_metadata_get_tag_multiple (g2_metadata,
- parse_data->name);
+ values = gexiv2_metadata_try_get_tag_multiple (g2_metadata,
+ parse_data->name,
+ &error);
- if (values)
+ if (error)
+ {
+ g_printerr ("%s: %s\n", G_STRFUNC, error->message);
+ g_clear_error (&error);
+ g_strfreev (values);
+ }
+ else if (values)
{
guint length = g_strv_length (values);
@@ -1597,9 +1605,18 @@ gimp_metadata_copy_tag (GExiv2Metadata *src,
GExiv2Metadata *dest,
const gchar *tag)
{
- gchar **values = gexiv2_metadata_get_tag_multiple (src, tag);
+ gchar **values;
+ GError *error = NULL;
+
+ values = gexiv2_metadata_try_get_tag_multiple (src, tag, &error);
- if (values)
+ if (error)
+ {
+ g_printerr ("%s: %s\n", G_STRFUNC, error->message);
+ g_clear_error (&error);
+ g_strfreev (values);
+ }
+ else if (values)
{
gexiv2_metadata_set_tag_multiple (dest, tag, (const gchar **) values);
g_strfreev (values);
--
2.29.2

View File

@ -0,0 +1,748 @@
From 45aef278795767012d2f44985f900569df3b8bd3 Mon Sep 17 00:00:00 2001
From: Jehan <jehan@girinstud.io>
Date: Sun, 8 Nov 2020 18:25:34 +0100
Subject: [PATCH 1/3] Issue #60: alt gexiv2_metadata_try_(g|s)et_tag_multiple()
with GError.
Raising GLib warning should not be done on tag errors because calling
applications may prefer handling these errors differently (and adding a
log handler for every dependency of a software is not flexible).
It is much better design to return errors as optional GError.
---
gexiv2/gexiv2-metadata-iptc.cpp | 10 +++--
gexiv2/gexiv2-metadata-private.h | 8 ++--
gexiv2/gexiv2-metadata-xmp.cpp | 10 +++--
gexiv2/gexiv2-metadata.cpp | 73 ++++++++++++++++++++++++--------
gexiv2/gexiv2-metadata.h | 34 +++++++++++++++
5 files changed, 105 insertions(+), 30 deletions(-)
diff --git a/gexiv2/gexiv2-metadata-iptc.cpp b/gexiv2/gexiv2-metadata-iptc.cpp
index 24de73b..efb5824 100644
--- a/gexiv2/gexiv2-metadata-iptc.cpp
+++ b/gexiv2/gexiv2-metadata-iptc.cpp
@@ -161,10 +161,11 @@ gboolean gexiv2_metadata_set_iptc_tag_string (GExiv2Metadata *self, const gchar*
return FALSE;
}
-gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag) {
+gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
g_return_val_if_fail(tag != NULL, NULL);
g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::IptcData &iptc_data = self->priv->image->iptcData();
@@ -191,7 +192,7 @@ gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar
return values;
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
g_slist_free_full (list, g_free);
@@ -200,11 +201,12 @@ gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar
}
gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag,
- const gchar** values) {
+ const gchar** values, GError **error) {
g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
g_return_val_if_fail(tag != NULL, FALSE);
g_return_val_if_fail(values != NULL, FALSE);
g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::IptcData& iptc_data = self->priv->image->iptcData();
@@ -232,7 +234,7 @@ gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gcha
return TRUE;
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return FALSE;
diff --git a/gexiv2/gexiv2-metadata-private.h b/gexiv2/gexiv2-metadata-private.h
index d31fa99..989af0b 100644
--- a/gexiv2/gexiv2-metadata-private.h
+++ b/gexiv2/gexiv2-metadata-private.h
@@ -62,8 +62,8 @@ G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_string (GExiv2Metadata *se
G_GNUC_INTERNAL gchar* gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL glong gexiv2_metadata_get_xmp_tag_long (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_long (GExiv2Metadata *self, const gchar* tag, glong value);
-G_GNUC_INTERNAL gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values);
+G_GNUC_INTERNAL gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values, GError **error);
G_GNUC_INTERNAL const gchar* gexiv2_metadata_get_xmp_tag_label (const gchar* tag);
G_GNUC_INTERNAL const gchar* gexiv2_metadata_get_xmp_tag_description (const gchar* tag);
@@ -78,8 +78,8 @@ G_GNUC_INTERNAL gboolean gexiv2_metadata_has_iptc_tag (GExiv2Metadata *self, c
G_GNUC_INTERNAL gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_set_iptc_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value);
G_GNUC_INTERNAL gchar* gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values);
+G_GNUC_INTERNAL gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values, GError **error);
G_GNUC_INTERNAL const gchar* gexiv2_metadata_get_iptc_tag_label (const gchar* tag);
G_GNUC_INTERNAL const gchar* gexiv2_metadata_get_iptc_tag_description (const gchar* tag);
diff --git a/gexiv2/gexiv2-metadata-xmp.cpp b/gexiv2/gexiv2-metadata-xmp.cpp
index 784ad86..4647d36 100644
--- a/gexiv2/gexiv2-metadata-xmp.cpp
+++ b/gexiv2/gexiv2-metadata-xmp.cpp
@@ -269,10 +269,11 @@ gboolean gexiv2_metadata_set_xmp_tag_long (GExiv2Metadata *self, const gchar* ta
return FALSE;
}
-gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag) {
+gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
g_return_val_if_fail(tag != NULL, NULL);
g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
@@ -294,7 +295,7 @@ gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar*
return array;
}
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
gchar **array = g_new (gchar*, 1);
@@ -304,11 +305,12 @@ gchar** gexiv2_metadata_get_xmp_tag_multiple (GExiv2Metadata *self, const gchar*
}
gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar* tag,
- const gchar** values) {
+ const gchar** values, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
g_return_val_if_fail(tag != NULL, FALSE);
g_return_val_if_fail(values != NULL, FALSE);
g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
@@ -330,7 +332,7 @@ gboolean gexiv2_metadata_set_xmp_tag_multiple (GExiv2Metadata *self, const gchar
return TRUE;
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return FALSE;
diff --git a/gexiv2/gexiv2-metadata.cpp b/gexiv2/gexiv2-metadata.cpp
index 5a2a2bb..3b04017 100644
--- a/gexiv2/gexiv2-metadata.cpp
+++ b/gexiv2/gexiv2-metadata.cpp
@@ -945,35 +945,72 @@ gchar* gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata *self, const g
return NULL;
}
-gchar** gexiv2_metadata_get_tag_multiple(GExiv2Metadata *self, const gchar* tag) {
- g_return_val_if_fail(GEXIV2_IS_METADATA(self), NULL);
- g_return_val_if_fail(tag != NULL, NULL);
- g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
-
+gchar** gexiv2_metadata_try_get_tag_multiple(GExiv2Metadata *self, const gchar* tag, GError **error) {
+ g_return_val_if_fail(GEXIV2_IS_METADATA(self), nullptr);
+ g_return_val_if_fail(tag != nullptr, nullptr);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
if (gexiv2_metadata_is_xmp_tag(tag))
- return gexiv2_metadata_get_xmp_tag_multiple(self, tag);
-
+ return gexiv2_metadata_get_xmp_tag_multiple(self, tag, error);
+
if (gexiv2_metadata_is_iptc_tag(tag))
- return gexiv2_metadata_get_iptc_tag_multiple(self, tag);
-
+ return gexiv2_metadata_get_iptc_tag_multiple(self, tag, error);
+
return NULL;
}
-gboolean gexiv2_metadata_set_tag_multiple(GExiv2Metadata *self, const gchar* tag, const gchar** values) {
+gboolean gexiv2_metadata_try_set_tag_multiple(GExiv2Metadata *self, const gchar* tag, const gchar** values, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
- g_return_val_if_fail(tag != NULL, FALSE);
- g_return_val_if_fail(values != NULL, FALSE);
- g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
-
+ g_return_val_if_fail(tag != nullptr, FALSE);
+ g_return_val_if_fail(values != nullptr, FALSE);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
if (gexiv2_metadata_is_xmp_tag(tag))
- return gexiv2_metadata_set_xmp_tag_multiple(self, tag, values);
-
+ return gexiv2_metadata_set_xmp_tag_multiple(self, tag, values, error);
+
if (gexiv2_metadata_is_iptc_tag(tag))
- return gexiv2_metadata_set_iptc_tag_multiple(self, tag, values);
-
+ return gexiv2_metadata_set_iptc_tag_multiple(self, tag, values, error);
+
return FALSE;
}
+gchar** gexiv2_metadata_get_tag_multiple(GExiv2Metadata *self, const gchar* tag) {
+ gchar **tags = nullptr;
+ GError *error = nullptr;
+
+ g_return_val_if_fail(GEXIV2_IS_METADATA(self), nullptr);
+ g_return_val_if_fail(tag != nullptr, nullptr);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+ tags = gexiv2_metadata_try_get_tag_multiple(self, tag, &error);
+
+ if (error) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ return tags;
+}
+
+gboolean gexiv2_metadata_set_tag_multiple(GExiv2Metadata *self, const gchar* tag, const gchar** values) {
+ GError *error = nullptr;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
+ g_return_val_if_fail(tag != nullptr, FALSE);
+ g_return_val_if_fail(values != nullptr, FALSE);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
+ success = gexiv2_metadata_try_set_tag_multiple(self, tag, values, &error);
+
+ if (error) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ return success;
+}
+
glong gexiv2_metadata_get_tag_long(GExiv2Metadata *self, const gchar* tag) {
g_return_val_if_fail(GEXIV2_IS_METADATA(self), 0);
g_return_val_if_fail(tag != NULL, 0);
diff --git a/gexiv2/gexiv2-metadata.h b/gexiv2/gexiv2-metadata.h
index f65db7e..89e1495 100644
--- a/gexiv2/gexiv2-metadata.h
+++ b/gexiv2/gexiv2-metadata.h
@@ -562,6 +562,32 @@ glong gexiv2_metadata_get_tag_long (GExiv2Metadata *self, const gchar* tag);
gboolean gexiv2_metadata_set_tag_long (GExiv2Metadata *self, const gchar* tag, glong value);
+/**
+ * gexiv2_metadata_try_get_tag_multiple:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
+ *
+ * Returns: (transfer full) (allow-none) (array zero-terminated=1): The multiple string values of
+ * the tag
+ */
+gchar** gexiv2_metadata_try_get_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error);
+
+/**
+ * gexiv2_metadata_try_set_tag_multiple:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @values: (array zero-terminated=1): An array of values to set or replace the existing value(s)
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
+ *
+ * Returns: Boolean success value
+ */
+gboolean gexiv2_metadata_try_set_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values, GError **error);
+
/**
* gexiv2_metadata_get_tag_multiple:
* @self: An instance of #GExiv2Metadata
@@ -569,6 +595,10 @@ gboolean gexiv2_metadata_set_tag_long (GExiv2Metadata *self, const gchar* tag,
*
* The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
*
+ * In case of error, a GLib warning will be logged. Use instead
+ * gexiv2_metadata_try_get_tag_multiple() if you want to avoid this and
+ * control if and how the error is outputted.
+ *
* Returns: (transfer full) (allow-none) (array zero-terminated=1): The multiple string values of
* the tag
*/
@@ -582,6 +612,10 @@ gchar** gexiv2_metadata_get_tag_multiple (GExiv2Metadata *self, const gchar* t
*
* The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
*
+ * In case of error, a GLib warning will be logged. Use instead
+ * gexiv2_metadata_try_set_tag_multiple() if you want to avoid this and
+ * control if and how the error is outputted.
+ *
* Returns: Boolean success value
*/
gboolean gexiv2_metadata_set_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values);
--
GitLab
From 52c3a2b1442b52d95abd561a5973862c46f740ea Mon Sep 17 00:00:00 2001
From: Jehan <jehan@girinstud.io>
Date: Sun, 8 Nov 2020 19:22:54 +0100
Subject: [PATCH 2/3] New gexiv2_metadata_try_(g|s)et_tag_string() variants
with GError.
Similarly to my previous commit, gexiv2_metadata_set_tag_string() and
gexiv2_metadata_get_tag_string() should have variants which just set a
GError appropriately on tag error, rather than raising a WARNING.
---
gexiv2/gexiv2-metadata-exif.cpp | 10 +++---
gexiv2/gexiv2-metadata-gps.cpp | 6 ++--
gexiv2/gexiv2-metadata-iptc.cpp | 10 +++---
gexiv2/gexiv2-metadata-private.h | 12 +++----
gexiv2/gexiv2-metadata-xmp.cpp | 10 +++---
gexiv2/gexiv2-metadata.cpp | 62 +++++++++++++++++++++++++-------
gexiv2/gexiv2-metadata.h | 33 +++++++++++++++++
7 files changed, 109 insertions(+), 34 deletions(-)
diff --git a/gexiv2/gexiv2-metadata-exif.cpp b/gexiv2/gexiv2-metadata-exif.cpp
index 15cf116..81e54b3 100644
--- a/gexiv2/gexiv2-metadata-exif.cpp
+++ b/gexiv2/gexiv2-metadata-exif.cpp
@@ -97,10 +97,11 @@ gchar** gexiv2_metadata_get_exif_tags (GExiv2Metadata *self) {
return data;
}
-gchar* gexiv2_metadata_get_exif_tag_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_get_exif_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
g_return_val_if_fail(tag != NULL, NULL);
g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::ExifData &exif_data = self->priv->image->exifData();
@@ -112,7 +113,7 @@ gchar* gexiv2_metadata_get_exif_tag_string (GExiv2Metadata *self, const gchar* t
if (it != exif_data.end())
return g_strdup (it->toString ().c_str ());
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return NULL;
@@ -143,18 +144,19 @@ gchar* gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata *self, co
return NULL;
}
-gboolean gexiv2_metadata_set_exif_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value) {
+gboolean gexiv2_metadata_set_exif_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
g_return_val_if_fail(tag != NULL, FALSE);
g_return_val_if_fail(value != NULL, FALSE);
g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
try {
self->priv->image->exifData()[tag] = value;
return TRUE;
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return FALSE;
diff --git a/gexiv2/gexiv2-metadata-gps.cpp b/gexiv2/gexiv2-metadata-gps.cpp
index deeb4ac..7d0d18a 100644
--- a/gexiv2/gexiv2-metadata-gps.cpp
+++ b/gexiv2/gexiv2-metadata-gps.cpp
@@ -56,7 +56,7 @@ gboolean gexiv2_metadata_get_gps_longitude (GExiv2Metadata *self, gdouble *longi
double min, sec;
*longitude = 0.0;
- gchar* longitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLongitudeRef");
+ gchar* longitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLongitudeRef", nullptr);
GPointer longitude_ref_guard(longitude_ref);
if (longitude_ref == NULL || longitude_ref[0] == '\0') {
@@ -105,7 +105,7 @@ gboolean gexiv2_metadata_get_gps_latitude (GExiv2Metadata *self, gdouble *latitu
double min, sec;
*latitude = 0.0;
- gchar* latitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLatitudeRef");
+ gchar* latitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSLatitudeRef", nullptr);
GPointer latitude_ref_guard(latitude_ref);
if (latitude_ref == NULL || latitude_ref[0] == '\0') {
@@ -153,7 +153,7 @@ gboolean gexiv2_metadata_get_gps_altitude (GExiv2Metadata *self, gdouble *altitu
try {
*altitude = 0.0;
- gchar* altitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSAltitudeRef");
+ gchar* altitude_ref = gexiv2_metadata_get_exif_tag_string (self, "Exif.GPSInfo.GPSAltitudeRef", nullptr);
GPointer altitude_ref_guard(altitude_ref);
if (altitude_ref == NULL || altitude_ref[0] == '\0') {
diff --git a/gexiv2/gexiv2-metadata-iptc.cpp b/gexiv2/gexiv2-metadata-iptc.cpp
index efb5824..8340d72 100644
--- a/gexiv2/gexiv2-metadata-iptc.cpp
+++ b/gexiv2/gexiv2-metadata-iptc.cpp
@@ -97,10 +97,11 @@ gchar** gexiv2_metadata_get_iptc_tags (GExiv2Metadata *self) {
return data;
}
-gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
g_return_val_if_fail(tag != NULL, NULL);
g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::IptcData& iptc_data = self->priv->image->iptcData();
@@ -112,7 +113,7 @@ gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* t
if (it != iptc_data.end())
return g_strdup (it->toString ().c_str ());
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return NULL;
@@ -144,18 +145,19 @@ gchar* gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata *self, co
}
gboolean gexiv2_metadata_set_iptc_tag_string (GExiv2Metadata *self, const gchar* tag,
- const gchar* value) {
+ const gchar* value, GError **error) {
g_return_val_if_fail (GEXIV2_IS_METADATA (self), FALSE);
g_return_val_if_fail(tag != NULL, FALSE);
g_return_val_if_fail(value != NULL, FALSE);
g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
try {
self->priv->image->iptcData()[tag] = value;
return TRUE;
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return FALSE;
diff --git a/gexiv2/gexiv2-metadata-private.h b/gexiv2/gexiv2-metadata-private.h
index 989af0b..30e3c13 100644
--- a/gexiv2/gexiv2-metadata-private.h
+++ b/gexiv2/gexiv2-metadata-private.h
@@ -42,8 +42,8 @@ struct _GExiv2MetadataPrivate
G_GNUC_INTERNAL gboolean gexiv2_metadata_has_exif_tag (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_clear_exif_tag (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gchar* gexiv2_metadata_get_exif_tag_string (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gboolean gexiv2_metadata_set_exif_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value);
+G_GNUC_INTERNAL gchar* gexiv2_metadata_get_exif_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean gexiv2_metadata_set_exif_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value, GError **error);
G_GNUC_INTERNAL gchar* gexiv2_metadata_get_exif_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL glong gexiv2_metadata_get_exif_tag_long (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_set_exif_tag_long (GExiv2Metadata *self, const gchar* tag, glong value);
@@ -57,8 +57,8 @@ G_GNUC_INTERNAL GBytes* gexiv2_metadata_get_exif_tag_raw (GExiv2Metadata *self
G_GNUC_INTERNAL gboolean gexiv2_metadata_clear_xmp_tag (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_has_xmp_tag (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gchar* gexiv2_metadata_get_xmp_tag_string (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value);
+G_GNUC_INTERNAL gchar* gexiv2_metadata_get_xmp_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value, GError **error);
G_GNUC_INTERNAL gchar* gexiv2_metadata_get_xmp_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL glong gexiv2_metadata_get_xmp_tag_long (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_set_xmp_tag_long (GExiv2Metadata *self, const gchar* tag, glong value);
@@ -75,8 +75,8 @@ G_GNUC_INTERNAL GBytes* gexiv2_metadata_get_xmp_tag_raw (GExiv2Metadata *self
G_GNUC_INTERNAL gboolean gexiv2_metadata_clear_iptc_tag (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gboolean gexiv2_metadata_has_iptc_tag (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* tag);
-G_GNUC_INTERNAL gboolean gexiv2_metadata_set_iptc_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value);
+G_GNUC_INTERNAL gchar* gexiv2_metadata_get_iptc_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error);
+G_GNUC_INTERNAL gboolean gexiv2_metadata_set_iptc_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value, GError **error);
G_GNUC_INTERNAL gchar* gexiv2_metadata_get_iptc_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag);
G_GNUC_INTERNAL gchar** gexiv2_metadata_get_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, GError **error);
G_GNUC_INTERNAL gboolean gexiv2_metadata_set_iptc_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values, GError **error);
diff --git a/gexiv2/gexiv2-metadata-xmp.cpp b/gexiv2/gexiv2-metadata-xmp.cpp
index 4647d36..87795a4 100644
--- a/gexiv2/gexiv2-metadata-xmp.cpp
+++ b/gexiv2/gexiv2-metadata-xmp.cpp
@@ -126,10 +126,11 @@ gchar** gexiv2_metadata_get_xmp_tags (GExiv2Metadata *self) {
return data;
}
-gchar* gexiv2_metadata_get_xmp_tag_string (GExiv2Metadata *self, const gchar* tag) {
+gchar* gexiv2_metadata_get_xmp_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
g_return_val_if_fail(tag != NULL, NULL);
g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
Exiv2::XmpData& xmp_data = self->priv->image->xmpData();
@@ -141,7 +142,7 @@ gchar* gexiv2_metadata_get_xmp_tag_string (GExiv2Metadata *self, const gchar* ta
if (it != xmp_data.end())
return g_strdup (it->toString ().c_str ());
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return NULL;
@@ -215,18 +216,19 @@ gboolean gexiv2_metadata_set_xmp_tag_struct (GExiv2Metadata *self, const gchar*
}
gboolean gexiv2_metadata_set_xmp_tag_string (GExiv2Metadata *self, const gchar* tag,
- const gchar* value) {
+ const gchar* value, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), FALSE);
g_return_val_if_fail(tag != NULL, FALSE);
g_return_val_if_fail(value != NULL, FALSE);
g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+ g_return_val_if_fail(error == nullptr || *error == nullptr, FALSE);
try {
self->priv->image->xmpData()[tag] = value;
return TRUE;
} catch (Exiv2::Error& e) {
- LOG_ERROR(e);
+ g_set_error_literal (error, g_quark_from_string ("GExiv2"), e.code (), e.what ());
}
return FALSE;
diff --git a/gexiv2/gexiv2-metadata.cpp b/gexiv2/gexiv2-metadata.cpp
index 3b04017..426a55d 100644
--- a/gexiv2/gexiv2-metadata.cpp
+++ b/gexiv2/gexiv2-metadata.cpp
@@ -894,40 +894,76 @@ gboolean gexiv2_metadata_is_iptc_tag(const gchar* tag) {
return g_ascii_strncasecmp("Iptc.", tag, 5) == 0;
}
-gchar* gexiv2_metadata_get_tag_string (GExiv2Metadata *self, const gchar* tag) {
- g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
- g_return_val_if_fail(tag != NULL, NULL);
- g_return_val_if_fail(self->priv->image.get() != NULL, NULL);
+gchar* gexiv2_metadata_try_get_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error) {
+ g_return_val_if_fail(GEXIV2_IS_METADATA (self), nullptr);
+ g_return_val_if_fail(tag != nullptr, nullptr);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
if (gexiv2_metadata_is_xmp_tag(tag))
- return gexiv2_metadata_get_xmp_tag_string (self, tag);
+ return gexiv2_metadata_get_xmp_tag_string (self, tag, error);
if (gexiv2_metadata_is_exif_tag(tag))
- return gexiv2_metadata_get_exif_tag_string (self, tag);
+ return gexiv2_metadata_get_exif_tag_string (self, tag, error);
if (gexiv2_metadata_is_iptc_tag(tag))
- return gexiv2_metadata_get_iptc_tag_string (self, tag);
+ return gexiv2_metadata_get_iptc_tag_string (self, tag, error);
return NULL;
}
-gboolean gexiv2_metadata_set_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value) {
+gboolean gexiv2_metadata_try_set_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value, GError **error) {
g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
- g_return_val_if_fail(tag != NULL, FALSE);
- g_return_val_if_fail(self->priv->image.get() != NULL, FALSE);
+ g_return_val_if_fail(tag != nullptr, FALSE);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
if (gexiv2_metadata_is_xmp_tag(tag))
- return gexiv2_metadata_set_xmp_tag_string(self, tag, value);
+ return gexiv2_metadata_set_xmp_tag_string(self, tag, value, error);
if (gexiv2_metadata_is_exif_tag(tag))
- return gexiv2_metadata_set_exif_tag_string(self, tag, value);
+ return gexiv2_metadata_set_exif_tag_string(self, tag, value, error);
if (gexiv2_metadata_is_iptc_tag(tag))
- return gexiv2_metadata_set_iptc_tag_string(self, tag, value);
+ return gexiv2_metadata_set_iptc_tag_string(self, tag, value, error);
return FALSE;
}
+gchar* gexiv2_metadata_get_tag_string (GExiv2Metadata *self, const gchar* tag) {
+ gchar *value;
+ GError *error = nullptr;
+
+ g_return_val_if_fail(GEXIV2_IS_METADATA (self), nullptr);
+ g_return_val_if_fail(tag != nullptr, nullptr);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, nullptr);
+
+ value = gexiv2_metadata_try_get_tag_string (self, tag, &error);
+
+ if (error) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ return value;
+}
+
+gboolean gexiv2_metadata_set_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value) {
+ gboolean success;
+ GError *error = nullptr;
+
+ g_return_val_if_fail(GEXIV2_IS_METADATA(self), FALSE);
+ g_return_val_if_fail(tag != nullptr, FALSE);
+ g_return_val_if_fail(self->priv->image.get() != nullptr, FALSE);
+
+ success = gexiv2_metadata_try_set_tag_string(self, tag, value, &error);
+
+ if (error) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ return success;
+}
+
gchar* gexiv2_metadata_get_tag_interpreted_string (GExiv2Metadata *self, const gchar* tag) {
g_return_val_if_fail(GEXIV2_IS_METADATA (self), NULL);
g_return_val_if_fail(tag != NULL, NULL);
diff --git a/gexiv2/gexiv2-metadata.h b/gexiv2/gexiv2-metadata.h
index 89e1495..3315d92 100644
--- a/gexiv2/gexiv2-metadata.h
+++ b/gexiv2/gexiv2-metadata.h
@@ -489,6 +489,31 @@ gint gexiv2_metadata_get_pixel_width (GExiv2Metadata *self);
*/
gint gexiv2_metadata_get_pixel_height (GExiv2Metadata *self);
+/**
+ * gexiv2_metadata_try_get_tag_string:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
+ *
+ * Returns: (transfer full) (allow-none): The tag's value as a string
+ */
+gchar* gexiv2_metadata_try_get_tag_string (GExiv2Metadata *self, const gchar* tag, GError **error);
+
+/**
+ * gexiv2_metadata_try_set_tag_string:
+ * @self: An instance of #GExiv2Metadata
+ * @tag: Exiv2 tag name
+ * @value: The value to set or replace the existing value
+ * @error: (allow-none): A return location for a #GError or %nullptr
+ *
+ * The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
+ *
+ * Returns: TRUE on success
+ */
+gboolean gexiv2_metadata_try_set_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value, GError **error);
+
/**
* gexiv2_metadata_get_tag_string:
* @self: An instance of #GExiv2Metadata
@@ -496,6 +521,10 @@ gint gexiv2_metadata_get_pixel_height (GExiv2Metadata *self);
*
* The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
*
+ * In case of error, a GLib warning will be logged. Use instead
+ * gexiv2_metadata_try_get_tag_string() if you want to avoid this and
+ * control if and how the error is outputted.
+ *
* Returns: (transfer full) (allow-none): The tag's value as a string
*/
gchar* gexiv2_metadata_get_tag_string (GExiv2Metadata *self, const gchar* tag);
@@ -508,6 +537,10 @@ gchar* gexiv2_metadata_get_tag_string (GExiv2Metadata *self, const gchar* tag
*
* The Exiv2 Tag Reference can be found at <ulink url="http://exiv2.org/metadata.html"></ulink>
*
+ * In case of error, a GLib warning will be logged. Use instead
+ * gexiv2_metadata_try_set_tag_string() if you want to avoid this and
+ * control if and how the error is outputted.
+ *
* Returns: TRUE on success
*/
gboolean gexiv2_metadata_set_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value);
--
GitLab
From 5377a0e2912d1a93dcdd38dfff9b1f68223cef53 Mon Sep 17 00:00:00 2001
From: Jehan <jehan@girinstud.io>
Date: Tue, 10 Nov 2020 20:11:06 +0100
Subject: [PATCH 3/3] gexiv2: properly deprecate functions in favor of
gexiv2_metadata_try*().
---
gexiv2/gexiv2-metadata.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gexiv2/gexiv2-metadata.h b/gexiv2/gexiv2-metadata.h
index 3315d92..f51d85f 100644
--- a/gexiv2/gexiv2-metadata.h
+++ b/gexiv2/gexiv2-metadata.h
@@ -526,7 +526,10 @@ gboolean gexiv2_metadata_try_set_tag_string (GExiv2Metadata *self, const gchar*
* control if and how the error is outputted.
*
* Returns: (transfer full) (allow-none): The tag's value as a string
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_string() instead.
*/
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_string)
gchar* gexiv2_metadata_get_tag_string (GExiv2Metadata *self, const gchar* tag);
/**
@@ -542,7 +545,10 @@ gchar* gexiv2_metadata_get_tag_string (GExiv2Metadata *self, const gchar* tag
* control if and how the error is outputted.
*
* Returns: TRUE on success
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_tag_string() instead.
*/
+G_DEPRECATED_FOR(gexiv2_metadata_try_set_tag_string)
gboolean gexiv2_metadata_set_tag_string (GExiv2Metadata *self, const gchar* tag, const gchar* value);
/**
@@ -634,7 +640,10 @@ gboolean gexiv2_metadata_try_set_tag_multiple (GExiv2Metadata *self, const gcha
*
* Returns: (transfer full) (allow-none) (array zero-terminated=1): The multiple string values of
* the tag
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_get_tag_multiple() instead.
*/
+G_DEPRECATED_FOR(gexiv2_metadata_try_get_tag_multiple)
gchar** gexiv2_metadata_get_tag_multiple (GExiv2Metadata *self, const gchar* tag);
/**
@@ -650,7 +659,10 @@ gchar** gexiv2_metadata_get_tag_multiple (GExiv2Metadata *self, const gchar* t
* control if and how the error is outputted.
*
* Returns: Boolean success value
+ *
+ * Deprecated: 0.12.2: Use gexiv2_metadata_try_set_tag_multiple:() instead.
*/
+G_DEPRECATED_FOR(gexiv2_metadata_try_set_tag_multiple)
gboolean gexiv2_metadata_set_tag_multiple (GExiv2Metadata *self, const gchar* tag, const gchar** values);
/**
--
GitLab