[gimp] Bug 769112 - The metadata windows takes a lot of CPU.
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 769112 - The metadata windows takes a lot of CPU.
- Date: Fri, 30 Dec 2016 03:15:55 +0000 (UTC)
commit f8e291bf3110098ed03e858d13b22296ec1068a4
Author: Ell <ell_se yahoo com>
Date: Thu Dec 29 21:45:55 2016 -0500
Bug 769112 - The metadata windows takes a lot of CPU.
Exif tags may have long values, which can choke GTK if we display
them in their entirety. Truncate tag values (based on type, and
with proper indication) to avoid that.
This commit also hides private tags, and fixes some memory leaks.
plug-ins/common/metadata.c | 212 ++++++++++++++++++++++++++++++++++----------
1 files changed, 163 insertions(+), 49 deletions(-)
---
diff --git a/plug-ins/common/metadata.c b/plug-ins/common/metadata.c
index 1472d45..e2d3048 100644
--- a/plug-ins/common/metadata.c
+++ b/plug-ins/common/metadata.c
@@ -38,6 +38,14 @@
#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,
@@ -62,21 +70,30 @@ typedef struct
/* 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 void query (void);
+static void run (const gchar *name,
+ gint nparams,
+ const GimpParam *param,
+ gint *nreturn_vals,
+ GimpParam **return_vals);
+
+static gboolean metadata_dialog (gint32 image_id,
+ GExiv2Metadata *metadata);
+
+static void metadata_dialog_set_metadata (GExiv2Metadata *metadata,
+ GtkBuilder *builder);
-static gboolean metadata_dialog (gint32 image_id,
- GExiv2Metadata *metadata);
+static void metadata_dialog_append_tags (GExiv2Metadata *metadata,
+ gchar **tags,
+ GtkListStore *store,
+ gint tag_column,
+ gint value_column);
-static void metadata_dialog_set_metadata (GExiv2Metadata *metadata,
- GtkBuilder *builder);
+static gchar * metadata_dialog_format_tag_value (GExiv2Metadata *metadata,
+ const gchar *tag);
-static void metadata_dialog_iptc_callback (GtkWidget *dialog,
- GtkBuilder *builder);
+static void metadata_dialog_iptc_callback (GtkWidget *dialog,
+ GtkBuilder *builder);
/* local variables */
@@ -270,47 +287,24 @@ metadata_dialog_set_metadata (GExiv2Metadata *metadata,
GtkListStore *exif_store;
GtkListStore *xmp_store;
gchar **exif_data;
- gchar **iptc_data;
gchar **xmp_data;
+ gchar **iptc_data;
gchar *value;
- gchar *value_utf;
- GtkTreeIter iter;
gint i;
+ exif_data = gexiv2_metadata_get_exif_tags (metadata);
exif_store = GTK_LIST_STORE (gtk_builder_get_object (builder,
"exif-liststore"));
- xmp_store = GTK_LIST_STORE (gtk_builder_get_object (builder,
- "xmp-liststore"));
- exif_data = gexiv2_metadata_get_exif_tags (metadata);
+ metadata_dialog_append_tags (metadata, exif_data,
+ exif_store, C_EXIF_TAG, C_EXIF_VALUE);
- for (i = 0; exif_data[i] != NULL; i++)
- {
- 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,
- -1);
- }
-
- xmp_data = gexiv2_metadata_get_xmp_tags (metadata);
+ xmp_data = gexiv2_metadata_get_xmp_tags (metadata);
+ xmp_store = GTK_LIST_STORE (gtk_builder_get_object (builder,
+ "xmp-liststore"));
- for (i = 0; xmp_data[i] != NULL; i++)
- {
- 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);
- }
+ metadata_dialog_append_tags (metadata, xmp_data,
+ xmp_store, C_XMP_TAG, C_XMP_VALUE);
iptc_data = gexiv2_metadata_get_iptc_tags (metadata);
@@ -319,15 +313,14 @@ metadata_dialog_set_metadata (GExiv2Metadata *metadata,
GtkWidget *widget;
widget = GTK_WIDGET (gtk_builder_get_object (builder, iptc_data[i]));
- value = gexiv2_metadata_get_tag_interpreted_string (metadata,
- iptc_data[i]);
- value_utf = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
+
+ value = metadata_dialog_format_tag_value (metadata, iptc_data[i]);
if (GTK_IS_ENTRY (widget))
{
GtkEntry *entry_widget = GTK_ENTRY (widget);
- gtk_entry_set_text (entry_widget, value_utf);
+ gtk_entry_set_text (entry_widget, value);
}
else if (GTK_IS_TEXT_VIEW (widget))
{
@@ -335,12 +328,133 @@ metadata_dialog_set_metadata (GExiv2Metadata *metadata,
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (text_view);
- gtk_text_buffer_set_text (buffer, value_utf, -1);
+ gtk_text_buffer_set_text (buffer, value, -1);
}
+
+ g_free (value);
}
}
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++))
+ {
+ 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);
+
+ 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)
+{
+ const gchar *tag_type;
+ gchar *result;
+
+ tag_type = gexiv2_metadata_get_tag_type (tag);
+
+ if (g_strcmp0 (tag_type, "Byte") != 0 &&
+ g_strcmp0 (tag_type, "Undefined") != 0 &&
+ g_strcmp0 (tag_type, NULL) != 0)
+ {
+ 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 (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);
+
+ g_string_append (str, "... ");
+ g_string_append_printf (str,
+ _("(%lu more character(s))"),
+ size - TAG_VALUE_MAX_SIZE);
+
+ result = g_string_free (str, FALSE);
+ }
+ }
+ else
+ {
+ 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);
+
+ 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;
+}
+
+static void
metadata_dialog_iptc_callback (GtkWidget *dialog,
GtkBuilder *builder)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]