[gimp] Bug 769112 - The metadata windows takes a lot of CPU.



commit 8c2ca36ac76fc5fc9aa7aa9055d2c6e4772f93b7
Author: Ell <ell_se yahoo com>
Date:   Sat Jul 8 08:48:47 2017 -0400

    Bug 769112 - The metadata windows takes a lot of CPU.
    
    The new metadata viewer is based on a version of the old metadata
    plugin that still contained this bug, and a few other bugs that've
    been fixed since then.  Reapply those fixes to the new plugin.
    
    This is essentially an adaptation of commits
    f8e291bf3110098ed03e858d13b22296ec1068a4,
    ce9e7feabde9b31d5847f6e533feeb0cac23f325,
    38c79600f15402fd126aa572eafd444b775f56c1,
    and 801bd8fb3f4ac3494b571df6a260fe0f31df38f2.

 plug-ins/metadata/metadata-viewer.c |  234 +++++++++++++++++++++++++----------
 1 files changed, 169 insertions(+), 65 deletions(-)
---
diff --git a/plug-ins/metadata/metadata-viewer.c b/plug-ins/metadata/metadata-viewer.c
index c0be370..76b016a 100644
--- a/plug-ins/metadata/metadata-viewer.c
+++ b/plug-ins/metadata/metadata-viewer.c
@@ -39,6 +39,15 @@
 #define IPTC_PREFIX "Iptc."
 #define XMP_PREFIX  "Xmp."
 
+/* The length at which to truncate tag values, in characters. */
+#define TAG_VALUE_MAX_SIZE 1024
+
+/* The length at which to truncate raw data (i.e., tag values
+ * of type "Byte" or "Undefined"), in bytes.
+ */
+#define RAW_DATA_MAX_SIZE 16
+
+
 enum
 {
   C_XMP_TAG = 0,
@@ -63,18 +72,25 @@ enum
 
 /*  local function prototypes  */
 
-static void       query                         (void);
-static void       run                           (const gchar      *name,
-                                                 gint              nparams,
-                                                 const GimpParam  *param,
-                                                 gint             *nreturn_vals,
-                                                 GimpParam       **return_vals);
-
-static gboolean   metadata_viewer_dialog        (gint32          image_id,
-                                                 GExiv2Metadata *metadata);
-static void       metadata_dialog_set_metadata  (GExiv2Metadata *metadata,
-                                                 GtkBuilder     *builder);
-
+static void       query                            (void);
+static void       run                              (const gchar      *name,
+                                                    gint              nparams,
+                                                    const GimpParam  *param,
+                                                    gint             *nreturn_vals,
+                                                    GimpParam       **return_vals);
+
+static gboolean   metadata_viewer_dialog           (gint32          image_id,
+                                                    GExiv2Metadata *metadata);
+static void       metadata_dialog_set_metadata     (GExiv2Metadata *metadata,
+                                                    GtkBuilder     *builder);
+static void       metadata_dialog_append_tags      (GExiv2Metadata  *metadata,
+                                                    gchar          **tags,
+                                                    GtkListStore    *store,
+                                                    gint             tag_column,
+                                                    gint             value_column);
+static gchar    * metadata_dialog_format_tag_value (GExiv2Metadata  *metadata,
+                                                    const gchar     *tag,
+                                                    gboolean         truncate);
 
 
 /* local variables */
@@ -205,7 +221,7 @@ metadata_viewer_dialog (gint32          image_id,
                             "gimp-metadata-viewer-dialog",
                             NULL, 0,
                             gimp_standard_help_func, PLUG_IN_PROC,
-                            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+                            _("_Close"), GTK_RESPONSE_CLOSE,
                             NULL);
 
   gtk_widget_set_size_request(dialog, 460, 340);
@@ -237,66 +253,154 @@ static void
 metadata_dialog_set_metadata (GExiv2Metadata *metadata,
                               GtkBuilder     *builder)
 {
-  GtkListStore  *exif_store;
-  GtkListStore  *xmp_store;
-  GtkListStore  *iptc_store;
-  gchar        **exif_data;
-  gchar        **iptc_data;
-  gchar        **xmp_data;
-  gchar         *value;
-  gchar         *value_utf;
-  GtkTreeIter    iter;
-  gint           i;
-
-  exif_store = GTK_LIST_STORE (gtk_builder_get_object  (builder,
-                                                        "exif-liststore"));
-  xmp_store  = GTK_LIST_STORE (gtk_builder_get_object  (builder,
-                                                        "xmp-liststore"));
-  iptc_store  = GTK_LIST_STORE (gtk_builder_get_object (builder,
-                                                        "iptc-liststore"));
-
-  exif_data = gexiv2_metadata_get_exif_tags (metadata);
-
-  for (i = 0; exif_data[i] != NULL; i++)
+  gchar        **tags;
+  GtkListStore  *store;
+
+  /* load exif tags */
+  tags  = gexiv2_metadata_get_exif_tags (metadata);
+  store = GTK_LIST_STORE (gtk_builder_get_object (builder, "exif-liststore"));
+
+  metadata_dialog_append_tags (metadata, tags, store, C_EXIF_TAG, C_EXIF_VALUE);
+
+  g_strfreev (tags);
+
+  /* load xmp tags */
+  tags  = gexiv2_metadata_get_xmp_tags (metadata);
+  store = GTK_LIST_STORE (gtk_builder_get_object (builder, "xmp-liststore"));
+
+  metadata_dialog_append_tags (metadata, tags, store, C_XMP_TAG, C_XMP_VALUE);
+
+  g_strfreev (tags);
+
+  /* load iptc tags */
+  tags  = gexiv2_metadata_get_iptc_tags (metadata);
+  store = GTK_LIST_STORE (gtk_builder_get_object (builder, "iptc-liststore"));
+
+  metadata_dialog_append_tags (metadata, tags, store, C_IPTC_TAG, C_IPTC_VALUE);
+
+  g_strfreev (tags);
+}
+
+static void
+metadata_dialog_append_tags (GExiv2Metadata  *metadata,
+                             gchar          **tags,
+                             GtkListStore    *store,
+                             gint             tag_column,
+                             gint             value_column)
+{
+  GtkTreeIter  iter;
+  const gchar *tag;
+
+  while ((tag = *tags++))
     {
-      gtk_list_store_append (exif_store, &iter);
-      value = gexiv2_metadata_get_tag_interpreted_string (metadata,
-                                                          exif_data[i]);
-      value_utf = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
-
-      gtk_list_store_set (exif_store, &iter,
-                          C_EXIF_TAG,   exif_data[i],
-                          C_EXIF_VALUE, value_utf,
+      const gchar *tag_label;
+      gchar       *value;
+
+      tag_label = gexiv2_metadata_get_tag_label (tag);
+
+      /* skip private tags */
+      if (g_strcmp0 (tag_label, "") == 0 || g_strcmp0 (tag_label, NULL) == 0)
+        continue;
+
+      gtk_list_store_append (store, &iter);
+
+      value = metadata_dialog_format_tag_value (metadata, tag,
+                                                /* truncate = */ TRUE);
+
+      gtk_list_store_set (store, &iter,
+                          tag_column,   tag,
+                          value_column, value,
                           -1);
+
+      g_free (value);
     }
+}
+
+static gchar *
+metadata_dialog_format_tag_value (GExiv2Metadata *metadata,
+                                  const gchar    *tag,
+                                  gboolean        truncate)
+{
+  const gchar *tag_type;
+  gchar       *result;
 
-  xmp_data = gexiv2_metadata_get_xmp_tags (metadata);
+  tag_type = gexiv2_metadata_get_tag_type (tag);
 
-  for (i = 0; xmp_data[i] != NULL; i++)
+  if (g_strcmp0 (tag_type, "Byte")      != 0 &&
+      g_strcmp0 (tag_type, "Undefined") != 0 &&
+      g_strcmp0 (tag_type, NULL)        != 0)
     {
-      gtk_list_store_append (xmp_store, &iter);
-      value = gexiv2_metadata_get_tag_interpreted_string (metadata,
-                                                          xmp_data[i]);
-      value_utf = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
-
-      gtk_list_store_set (xmp_store, &iter,
-                          C_XMP_TAG,   xmp_data[i],
-                          C_XMP_VALUE, value_utf,
-                          -1);
-    }
+      gchar *value;
+      gchar *value_utf8;
+      glong  size;
+
+      value      = gexiv2_metadata_get_tag_interpreted_string (metadata, tag);
+      value_utf8 = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
+
+      g_free (value);
+
+      size = g_utf8_strlen (value_utf8, -1);
+
+      if (! truncate || size <= TAG_VALUE_MAX_SIZE)
+        {
+          result = value_utf8;
+        }
+      else
+        {
+          gchar   *value_utf8_trunc;
+          GString *str;
+
+          value_utf8_trunc = g_utf8_substring (value_utf8,
+                                               0, TAG_VALUE_MAX_SIZE);
+
+          g_free (value_utf8);
+
+          str = g_string_new (value_utf8_trunc);
+
+          g_free (value_utf8_trunc);
 
-  iptc_data = gexiv2_metadata_get_iptc_tags (metadata);
+          g_string_append (str, "... ");
+          g_string_append_printf (str,
+                                  _("(%lu more character(s))"),
+                                  size - TAG_VALUE_MAX_SIZE);
 
-  for (i = 0; iptc_data[i] != NULL; i++)
+          result = g_string_free (str, FALSE);
+        }
+    }
+  else
     {
-      gtk_list_store_append (iptc_store, &iter);
-      value = gexiv2_metadata_get_tag_interpreted_string (metadata,
-                                                          iptc_data[i]);
-      value_utf = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
-
-      gtk_list_store_set (iptc_store, &iter,
-                          C_IPTC_TAG,   iptc_data[i],
-                          C_IPTC_VALUE, value_utf,
-                          -1);
+      GBytes       *bytes;
+      const guchar *data;
+      gsize         size;
+      gsize         display_size;
+      GString      *str;
+      gint          i;
+
+      bytes = gexiv2_metadata_get_tag_raw (metadata, tag);
+      data  = g_bytes_get_data (bytes, &size);
+
+      if (! truncate)
+        display_size = size;
+      else
+        display_size = MIN (size, RAW_DATA_MAX_SIZE);
+
+      str = g_string_sized_new (3 * display_size);
+
+      for (i = 0; i < display_size; i++)
+        g_string_append_printf (str, i == 0 ? "%02x" : " %02x", data[i]);
+
+      if (display_size < size)
+        {
+          g_string_append (str, " ... ");
+          g_string_append_printf (str,
+                                  _("(%llu more byte(s))"),
+                                  (unsigned long long) (size - display_size));
+        }
+
+      result = g_string_free (str, FALSE);
+
+      g_bytes_unref (bytes);
     }
+
+  return result;
 }


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