Issue #1437 - 2.10 Image Metadata "keywords" corrupt

We were not taking into account tags that can appear multiple times,
such as "keyword", they are handled by gexiv2 with the
get_tag_multiple() and set_tag_multiple() functions.

gimp_metadata_deserialize_text(): when deserializing our XML format,
check if a tag is already set on the metadata as "multiple" and if yes
retrieve it, append the new value and set it again.

gimp_image_metadata_save_finish(): take care of "multiple" values when
copying tags to new metadata created for saving.

This should preserve all values across an "import, edit, export".

Thing will still break when using the metadata editor, it doesn't
handle multiple values at all, but that code is very hard to
understand.
This commit is contained in:
Michael Natterer
2019-01-06 17:46:31 +01:00
parent 889e2e26ee
commit d708ac0b21
2 changed files with 70 additions and 27 deletions

View File

@ -380,6 +380,30 @@ gimp_image_metadata_save_prepare (gint32 image_ID,
}
static void
gimp_image_metadata_copy_tag (GExiv2Metadata *src,
GExiv2Metadata *dest,
const gchar *tag)
{
gchar **values = gexiv2_metadata_get_tag_multiple (src, tag);
if (values)
{
gexiv2_metadata_set_tag_multiple (dest, tag, (const gchar **) values);
g_strfreev (values);
}
else
{
gchar *value = gexiv2_metadata_get_tag_string (src, tag);
if (value)
{
gexiv2_metadata_set_tag_string (dest, tag, value);
g_free (value);
}
}
}
/**
* gimp_image_metadata_save_finish:
* @image_ID: The image
@ -410,7 +434,6 @@ gimp_image_metadata_save_finish (gint32 image_ID,
gboolean support_exif;
gboolean support_xmp;
gboolean support_iptc;
gchar *value;
gboolean success = FALSE;
gint i;
@ -446,11 +469,9 @@ gimp_image_metadata_save_finish (gint32 image_ID,
if (! gexiv2_metadata_has_tag (new_g2metadata, exif_data[i]) &&
gimp_metadata_is_tag_supported (exif_data[i], mime_type))
{
value = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata),
gimp_image_metadata_copy_tag (GEXIV2_METADATA (metadata),
new_g2metadata,
exif_data[i]);
gexiv2_metadata_set_tag_string (new_g2metadata, exif_data[i],
value);
g_free (value);
}
}
@ -530,11 +551,9 @@ gimp_image_metadata_save_finish (gint32 image_ID,
if (! gexiv2_metadata_has_tag (new_g2metadata, xmp_data[i]) &&
gimp_metadata_is_tag_supported (xmp_data[i], mime_type))
{
value = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata),
gimp_image_metadata_copy_tag (GEXIV2_METADATA (metadata),
new_g2metadata,
xmp_data[i]);
gexiv2_metadata_set_tag_string (new_g2metadata, xmp_data[i],
value);
g_free (value);
}
}
@ -550,11 +569,9 @@ gimp_image_metadata_save_finish (gint32 image_ID,
if (! gexiv2_metadata_has_tag (new_g2metadata, iptc_data[i]) &&
gimp_metadata_is_tag_supported (iptc_data[i], mime_type))
{
value = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata),
gimp_image_metadata_copy_tag (GEXIV2_METADATA (metadata),
new_g2metadata,
iptc_data[i]);
gexiv2_metadata_set_tag_string (new_g2metadata, iptc_data[i],
value);
g_free (value);
}
}

View File

@ -616,22 +616,48 @@ gimp_metadata_deserialize_text (GMarkupParseContext *context,
decoded = g_base64_decode (value, &len);
if (decoded[len - 1] == '\0')
gexiv2_metadata_set_tag_string (GEXIV2_METADATA (parse_data->metadata),
parse_data->name,
(const gchar *) decoded);
{
g_free (value);
value = (gchar *) decoded;
}
else
{
g_clear_pointer (&value, g_free);
g_clear_pointer (&decoded, g_free);
}
}
g_free (decoded);
if (value)
{
GExiv2Metadata *g2_metadata = GEXIV2_METADATA (parse_data->metadata);
gchar **values;
values = gexiv2_metadata_get_tag_multiple (g2_metadata,
parse_data->name);
if (values)
{
guint length = g_strv_length (values);
values = g_renew (gchar *, values, length + 2);
values[length] = value;
values[length + 1] = NULL;
gexiv2_metadata_set_tag_multiple (g2_metadata,
parse_data->name,
(const gchar **) values);
g_strfreev (values);
}
else
{
gexiv2_metadata_set_tag_string (GEXIV2_METADATA (parse_data->metadata),
parse_data->name,
value);
}
g_free (value);
}
}
}
}
static void
gimp_metadata_deserialize_error (GMarkupParseContext *context,