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



commit 76dc649b3f41d666f01b3b92d517e3ed9d220ab8
Author: Jacob Boerema <jgboerema gmail com>
Date:   Sat Sep 25 14:39:40 2021 -0400

    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.

 plug-ins/metadata/metadata-editor.c | 189 ++++++++++++++++++++++++++----------
 1 file changed, 137 insertions(+), 52 deletions(-)
---
diff --git a/plug-ins/metadata/metadata-editor.c b/plug-ins/metadata/metadata-editor.c
index efd678c74d..0236617129 100644
--- a/plug-ins/metadata/metadata-editor.c
+++ b/plug-ins/metadata/metadata-editor.c
@@ -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 (value)
+            {
+              gchar *value_utf8 = clean_xmp_string (value);
 
-              if (str)
+              g_free (value);
+
+              if (value_utf8 && value_utf8[0] != '\0')
+                {
+                  value = g_strdup (value_utf8);
+                }
+              else
                 {
-                  /* 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 = 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
+                    }
+
+                  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))
                         {
-                          g_string_prepend (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);
                         }
-                      g_string_prepend (str, value);
-                      g_free (value);
+                      value = g_string_free (str, FALSE);
                     }
-                  value = g_string_free (str, FALSE);
                 }
             }
         }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]