plug-ins: improve loading of XMP BAG/SEQ tags in metadata-editor

XMP array tags of type BAG and SEQ can have multiple values, each of these
values needs to be on a separate line to be correctly recognized as a
different value in the tag array. We were incorrectly loading all values
on one line separated by a comma.
For those tags that have equivalent IPTC tags we were also comparing just
the one XMP value with the whole, possibly multiple lines, of the same
IPTC, which could cause a failure to recognize identical tags.

We changed this to now have each value in a tag array on a separate line
by adding \n between values.
Each IPTC equivalent tag value is now compared to each value in the XMP
tag array and only added when a different value is found.
This commit is contained in:
Jacob Boerema 2021-09-25 14:39:40 -04:00
parent baaa1380cf
commit 76dc649b3f
1 changed files with 139 additions and 54 deletions

View File

@ -2081,89 +2081,174 @@ metadata_dialog_editor_set_metadata (GExiv2Metadata *metadata,
continue;
}
value = gexiv2_metadata_get_tag_interpreted_string (metadata,
default_metadata_tags[i].tag);
if (value)
{
gchar *value_utf8 = clean_xmp_string (value);
g_free (value);
if (value_utf8 && value_utf8[0] != '\0')
{
value = g_strdup (value_utf8);
}
else
{
value = NULL;
}
g_free (value_utf8);
}
index = default_metadata_tags[i].other_tag_index;
if (index > -1)
if (default_metadata_tags[i].xmp_type == GIMP_XMP_BAG ||
default_metadata_tags[i].xmp_type == GIMP_XMP_SEQ)
{
gchar **values;
/* These are all IPTC tags some of which can appear multiple times so
* we will use get_tag_multiple. Also IPTC most commonly uses UTF-8
* not current locale so get_tag_interpreted was wrong anyway.
* FIXME For now lets interpret as UTF-8 and in the future read
* and interpret based on the CharacterSet tag.
*/
value = NULL;
values = gexiv2_metadata_get_tag_multiple (metadata,
equivalent_metadata_tags[index].tag);
default_metadata_tags[i].tag);
if (values)
{
gint i;
GString *str = NULL;
gint vi;
for (i = 0; values[i] != NULL; i++)
for (vi = 0; values[vi] != NULL; vi++)
{
if (values[i][0] != '\0')
gchar *value_clean;
value_clean = clean_xmp_string (values[vi]);
if (value_clean != NULL && value_clean[0] != '\0')
{
if (! str)
if (! value)
{
str = g_string_new (values[i]);
value = g_strdup (value_clean);
}
else
{
if (! strcmp ("multi", equivalent_metadata_tags[index].mode))
gchar *tmpvalue;
tmpvalue = value;
value = g_strconcat (value, "\n", value_clean, NULL);
g_free (tmpvalue);
}
}
g_free (value_clean);
}
}
if (index > -1)
{
gchar **equiv_values;
/* These are all IPTC tags some of which can appear multiple times so
* we will use get_tag_multiple. Also IPTC most commonly uses UTF-8
* not current locale so get_tag_interpreted was wrong anyway.
* FIXME For now lets interpret as UTF-8 and in the future read
* and interpret based on the CharacterSet tag.
*/
equiv_values = gexiv2_metadata_get_tag_multiple (metadata,
equivalent_metadata_tags[index].tag);
if (equiv_values)
{
gint evi;
for (evi = 0; equiv_values[evi] != NULL; evi++)
{
if (equiv_values[evi][0] != '\0')
{
if (! value)
{
g_string_append (str, "\n");
value = g_strdup (equiv_values[evi]);
}
else
{
g_string_append (str, ", ");
if (! g_strv_contains (values, equiv_values[evi]))
{
gchar *tmpvalue;
tmpvalue = value;
value = g_strconcat (value, "\n", equiv_values[evi], NULL);
g_free (tmpvalue);
}
}
g_string_append (str, values[i]);
}
}
}
}
g_strfreev (values);
}
else
{
value = gexiv2_metadata_get_tag_interpreted_string (metadata,
default_metadata_tags[i].tag);
if (str)
if (value)
{
gchar *value_utf8 = clean_xmp_string (value);
g_free (value);
if (value_utf8 && value_utf8[0] != '\0')
{
/* If we got values from both Xmp and Iptc then compare those
* values and if they are different concatenate them. Usually they
* should be the same in which case we won't duplicate the string.
*/
if (value && strcmp (value, str->str))
value = g_strdup (value_utf8);
}
else
{
value = NULL;
}
g_free (value_utf8);
}
if (index > -1)
{
gchar **values;
/* It's not very likely we will have an XMP tag that can only
* have a single value instead of an array, which corresponds to
* an IPTC tag that can have multiple values, but since we
* already have this code it can't hurt to keep testing for it.
* FIXME For now lets interpret as UTF-8 and in the future read
* and interpret based on the CharacterSet tag.
*/
values = gexiv2_metadata_get_tag_multiple (metadata,
equivalent_metadata_tags[index].tag);
if (values)
{
gint i;
GString *str = NULL;
for (i = 0; values[i] != NULL; i++)
{
if (! strcmp ("multi", equivalent_metadata_tags[index].mode))
if (values[i][0] != '\0')
{
g_string_prepend (str, "\n");
if (! str)
{
str = g_string_new (values[i]);
}
else
{
if (! strcmp ("multi", equivalent_metadata_tags[index].mode))
{
g_string_append (str, "\n");
}
else
{
g_string_append (str, ", ");
}
g_string_append (str, values[i]);
}
}
else
{
g_string_prepend (str, ", ");
}
g_string_prepend (str, value);
g_free (value);
}
value = g_string_free (str, FALSE);
if (str)
{
/* If we got values from both Xmp and Iptc then compare those
* values and if they are different concatenate them. Usually they
* should be the same in which case we won't duplicate the string.
*/
if (value && strcmp (value, str->str))
{
if (! strcmp ("multi", equivalent_metadata_tags[index].mode))
{
g_string_prepend (str, "\n");
}
else
{
g_string_prepend (str, ", ");
}
g_string_prepend (str, value);
g_free (value);
}
value = g_string_free (str, FALSE);
}
}
}
}