[gimp] libgimp: better organization of gimp_image_metadata_*() API.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] libgimp: better organization of gimp_image_metadata_*() API.
- Date: Sun, 13 Sep 2020 11:43:11 +0000 (UTC)
commit 1b4834126f96a9327d45b28789d3609bea560a5f
Author: Jehan <jehan girinstud io>
Date: Sun Sep 13 13:09:59 2020 +0200
libgimp: better organization of gimp_image_metadata_*() API.
gimpimagemetadata.[ch] was built into libgimpui because GTK+ was used
for dialog query for rotation metadata. gimpimagemetadata-save.c only
was built into libgimp, which made no sense as the declaration for its
public function was inside gimpimagemetadata.h!
That was a weird situation and somehow only made visible in the build
system because GIR build was complaining about missing annotations to
gimp_image_metadata_save_prepare() (the annotation was actually present
but in the implementation which was not in the same library as the
header, how weird!):
> Warning: GimpUi: gimp_image_metadata_save_prepare: return value: Missing (transfer) annotation
Moreover it means that only plug-ins linking libgimpui had access to the
gimp_image_metadata*() API, which is obviously not cool (that should be
a core API).
Instead I moved everything into libgimp and replaced
gimp_image_metadata_load_finish() with
gimp_image_metadata_load_finish_batch(), which is essentially the same
function except that it's not interactive (it will proceed to rotate the
image without user confirmation, provided the right flag is present).
Then I add gimpimagemetadata-interactive.[ch] which contains only
gimp_image_metadata_load_finish() and is the alternative interactive
version of gimp_image_metadata_load_finish_batch(). Most plug-ins won't
even have to be changed (at least none in core GIMP) and would still
work as before, whereas now a non-interactive version exists, which
doesn't mandate to link GTK+.
libgimp/Makefile.gi | 6 +-
libgimp/gimp.h | 1 +
libgimp/gimpimagemetadata-interactive.c | 351 ++++++++++++++++++++++++++++++++
libgimp/gimpimagemetadata-interactive.h | 36 ++++
libgimp/gimpimagemetadata.c | 306 +++-------------------------
libgimp/gimpimagemetadata.h | 14 +-
libgimp/gimpui.h | 2 +-
libgimp/meson.build | 6 +-
8 files changed, 428 insertions(+), 294 deletions(-)
---
diff --git a/libgimp/Makefile.gi b/libgimp/Makefile.gi
index eb6875c516..4ad1e3eefc 100644
--- a/libgimp/Makefile.gi
+++ b/libgimp/Makefile.gi
@@ -119,6 +119,7 @@ libgimp_introspectable_headers = \
../libgimp/gimpgradientselect.h \
../libgimp/gimpimage.h \
../libgimp/gimpimagecolorprofile.h \
+ ../libgimp/gimpimagemetadata.h \
../libgimp/gimpimageprocedure.h \
../libgimp/gimpitem.h \
../libgimp/gimplayer.h \
@@ -152,6 +153,7 @@ libgimp_introspectable = \
../libgimp/gimpgradientselect.c \
../libgimp/gimpimage.c \
../libgimp/gimpimagecolorprofile.c \
+ ../libgimp/gimpimagemetadata.c \
../libgimp/gimpimagemetadata-save.c \
../libgimp/gimpimageprocedure.c \
../libgimp/gimpitem.c \
@@ -181,7 +183,7 @@ libgimpui_introspectable_headers = \
../libgimp/gimpfontselectbutton.h \
../libgimp/gimpgradientselectbutton.h \
../libgimp/gimpimagecombobox.h \
- ../libgimp/gimpimagemetadata.h \
+ ../libgimp/gimpimagemetadata-interactive.h \
../libgimp/gimpitemcombobox.h \
../libgimp/gimppaletteselectbutton.h \
../libgimp/gimppatternselectbutton.h \
@@ -202,7 +204,7 @@ libgimpui_introspectable = \
../libgimp/gimpfontselectbutton.c \
../libgimp/gimpgradientselectbutton.c \
../libgimp/gimpimagecombobox.c \
- ../libgimp/gimpimagemetadata.c \
+ ../libgimp/gimpimagemetadata-interactive.c \
../libgimp/gimpitemcombobox.c \
../libgimp/gimppaletteselectbutton.c \
../libgimp/gimppatternselectbutton.c \
diff --git a/libgimp/gimp.h b/libgimp/gimp.h
index 0578715da1..71649bd026 100644
--- a/libgimp/gimp.h
+++ b/libgimp/gimp.h
@@ -45,6 +45,7 @@
#include <libgimp/gimpgradientselect.h>
#include <libgimp/gimpimage.h>
#include <libgimp/gimpimagecolorprofile.h>
+#include <libgimp/gimpimagemetadata.h>
#include <libgimp/gimpimageprocedure.h>
#include <libgimp/gimpitem.h>
#include <libgimp/gimplayer.h>
diff --git a/libgimp/gimpimagemetadata-interactive.c b/libgimp/gimpimagemetadata-interactive.c
new file mode 100644
index 0000000000..bff4667610
--- /dev/null
+++ b/libgimp/gimpimagemetadata-interactive.c
@@ -0,0 +1,351 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimpimagemetadata-interactive.c
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <sys/time.h>
+
+#include <gtk/gtk.h>
+#include <gexiv2/gexiv2.h>
+
+#include "gimp.h"
+#include "gimpui.h"
+#include "gimpimagemetadata.h"
+
+#include "libgimp-intl.h"
+
+
+static gboolean gimp_image_metadata_rotate_query (GimpImage *image,
+ const gchar *mime_type,
+ GimpMetadata *metadata);
+static gboolean gimp_image_metadata_rotate_dialog (GimpImage *image,
+ GExiv2Orientation orientation,
+ const gchar *parasite_name);
+static GdkPixbuf * gimp_image_metadata_rotate_pixbuf (GdkPixbuf *pixbuf,
+ GExiv2Orientation orientation);
+
+
+/* public functions */
+
+/**
+ * gimp_image_metadata_load_finish:
+ * @image: The image
+ * @mime_type: The loaded file's mime-type
+ * @metadata: The metadata to set on the image
+ * @flags: Flags to specify what of the metadata to apply to the image
+ * @interactive: Whether this function is allowed to query info with dialogs
+ *
+ * Applies the @metadata previously loaded with
+ * gimp_image_metadata_load_prepare() to the image, taking into account
+ * the passed @flags.
+ *
+ * This function is the interactive alternative to
+ * gimp_image_metadata_load_finish_batch() which is allowed to query
+ * info with dialogs. For instance, if GIMP_METADATA_LOAD_ORIENTATION
+ * flag is set, it will popup a dialog asking whether one wants to
+ * rotate the image according to the orientation set in the metadata
+ * (displaying small previews of both versions).
+ * If @interactive is %FALSE, this behaves exactly the same as
+ * gimp_image_metadata_load_finish_batch().
+ *
+ * Since: 2.10
+ */
+void
+gimp_image_metadata_load_finish (GimpImage *image,
+ const gchar *mime_type,
+ GimpMetadata *metadata,
+ GimpMetadataLoadFlags flags,
+ gboolean interactive)
+{
+ g_return_if_fail (GIMP_IS_IMAGE (image));
+ g_return_if_fail (mime_type != NULL);
+ g_return_if_fail (GEXIV2_IS_METADATA (metadata));
+
+ if (interactive)
+ {
+ if (flags & GIMP_METADATA_LOAD_ORIENTATION)
+ {
+ if (! gimp_image_metadata_rotate_query (image, mime_type,
+ metadata))
+ flags &= ~GIMP_METADATA_LOAD_ORIENTATION;
+ }
+ }
+
+ gimp_image_metadata_load_finish_batch (image, mime_type, metadata, flags);
+}
+
+
+/* private functions */
+
+static gboolean
+gimp_image_metadata_rotate_query (GimpImage *image,
+ const gchar *mime_type,
+ GimpMetadata *metadata)
+{
+ GimpParasite *parasite;
+ gchar *parasite_name;
+ GExiv2Orientation orientation;
+ gboolean query = TRUE;
+
+ orientation = gexiv2_metadata_get_orientation (GEXIV2_METADATA (metadata));
+
+ if (orientation <= GEXIV2_ORIENTATION_NORMAL ||
+ orientation > GEXIV2_ORIENTATION_MAX)
+ return FALSE;
+
+ parasite_name = g_strdup_printf ("gimp-metadata-exif-rotate(%s)", mime_type);
+
+ parasite = gimp_get_parasite (parasite_name);
+
+ if (parasite)
+ {
+ if (strncmp (gimp_parasite_data (parasite), "yes",
+ gimp_parasite_data_size (parasite)) == 0)
+ {
+ query = FALSE;
+ }
+ else if (strncmp (gimp_parasite_data (parasite), "no",
+ gimp_parasite_data_size (parasite)) == 0)
+ {
+ gimp_parasite_free (parasite);
+ g_free (parasite_name);
+ return FALSE;
+ }
+
+ gimp_parasite_free (parasite);
+ }
+
+ if (query && ! gimp_image_metadata_rotate_dialog (image,
+ orientation,
+ parasite_name))
+ {
+ g_free (parasite_name);
+ return FALSE;
+ }
+
+ g_free (parasite_name);
+ return TRUE;
+}
+
+static gboolean
+gimp_image_metadata_rotate_dialog (GimpImage *image,
+ GExiv2Orientation orientation,
+ const gchar *parasite_name)
+{
+ GtkWidget *dialog;
+ GtkWidget *main_vbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *toggle;
+ GdkPixbuf *pixbuf;
+ gchar *name;
+ gchar *title;
+ gint response;
+
+ name = gimp_image_get_name (image);
+ title = g_strdup_printf (_("Rotate %s?"), name);
+ g_free (name);
+
+ dialog = gimp_dialog_new (title, "gimp-metadata-rotate-dialog",
+ NULL, 0, NULL, NULL,
+
+ _("_Keep Original"), GTK_RESPONSE_CANCEL,
+ _("_Rotate"), GTK_RESPONSE_OK,
+
+ NULL);
+
+ g_free (title);
+
+ gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK,
+ GTK_RESPONSE_CANCEL,
+ -1);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+ gimp_window_set_transient (GTK_WINDOW (dialog));
+
+ main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+ main_vbox, FALSE, FALSE, 0);
+ gtk_widget_show (main_vbox);
+
+#define THUMBNAIL_SIZE 128
+
+ pixbuf = gimp_image_get_thumbnail (image,
+ THUMBNAIL_SIZE, THUMBNAIL_SIZE,
+ GIMP_PIXBUF_SMALL_CHECKS);
+
+ if (pixbuf)
+ {
+ GdkPixbuf *rotated;
+ GtkWidget *hbox;
+ GtkWidget *image;
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
+ gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ label = gtk_label_new (_("Original"));
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
+ gimp_label_set_attributes (GTK_LABEL (label),
+ PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
+ -1);
+ gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ label = gtk_label_new (_("Rotated"));
+ gimp_label_set_attributes (GTK_LABEL (label),
+ PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
+ -1);
+ gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ rotated = gimp_image_metadata_rotate_pixbuf (pixbuf, orientation);
+ g_object_unref (pixbuf);
+
+ image = gtk_image_new_from_pixbuf (rotated);
+ g_object_unref (rotated);
+
+ gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
+ }
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", _("This image contains Exif orientation "
+ "metadata."),
+ "wrap", TRUE,
+ "justify", GTK_JUSTIFY_LEFT,
+ "xalign", 0.0,
+ "yalign", 0.5,
+ NULL);
+ gimp_label_set_attributes (GTK_LABEL (label),
+ PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
+ PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
+ -1);
+ /* eek */
+ gtk_widget_set_size_request (GTK_WIDGET (label),
+ 2 * THUMBNAIL_SIZE + 12, -1);
+ gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", _("Would you like to rotate the image?"),
+ "wrap", TRUE,
+ "justify", GTK_JUSTIFY_LEFT,
+ "xalign", 0.0,
+ "yalign", 0.5,
+ NULL);
+ /* eek */
+ gtk_widget_set_size_request (GTK_WIDGET (label),
+ 2 * THUMBNAIL_SIZE + 12, -1);
+ gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again"));
+ gtk_box_pack_end (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
+ gtk_widget_show (toggle);
+
+ response = gimp_dialog_run (GIMP_DIALOG (dialog));
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
+ {
+ GimpParasite *parasite;
+ const gchar *str = (response == GTK_RESPONSE_OK) ? "yes" : "no";
+
+ parasite = gimp_parasite_new (parasite_name,
+ GIMP_PARASITE_PERSISTENT,
+ strlen (str), str);
+ gimp_attach_parasite (parasite);
+ gimp_parasite_free (parasite);
+ }
+
+ gtk_widget_destroy (dialog);
+
+ return (response == GTK_RESPONSE_OK);
+}
+
+static GdkPixbuf *
+gimp_image_metadata_rotate_pixbuf (GdkPixbuf *pixbuf,
+ GExiv2Orientation orientation)
+{
+ GdkPixbuf *rotated = NULL;
+ GdkPixbuf *temp;
+
+ switch (orientation)
+ {
+ case GEXIV2_ORIENTATION_UNSPECIFIED:
+ case GEXIV2_ORIENTATION_NORMAL: /* standard orientation, do nothing */
+ rotated = g_object_ref (pixbuf);
+ break;
+
+ case GEXIV2_ORIENTATION_HFLIP:
+ rotated = gdk_pixbuf_flip (pixbuf, TRUE);
+ break;
+
+ case GEXIV2_ORIENTATION_ROT_180:
+ rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
+ break;
+
+ case GEXIV2_ORIENTATION_VFLIP:
+ rotated = gdk_pixbuf_flip (pixbuf, FALSE);
+ break;
+
+ case GEXIV2_ORIENTATION_ROT_90_HFLIP: /* flipped diagonally around '\' */
+ temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+ rotated = gdk_pixbuf_flip (temp, TRUE);
+ g_object_unref (temp);
+ break;
+
+ case GEXIV2_ORIENTATION_ROT_90: /* 90 CW */
+ rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+ break;
+
+ case GEXIV2_ORIENTATION_ROT_90_VFLIP: /* flipped diagonally around '/' */
+ temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+ rotated = gdk_pixbuf_flip (temp, FALSE);
+ g_object_unref (temp);
+ break;
+
+ case GEXIV2_ORIENTATION_ROT_270: /* 90 CCW */
+ rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
+ break;
+
+ default: /* shouldn't happen */
+ break;
+ }
+
+ return rotated;
+}
diff --git a/libgimp/gimpimagemetadata-interactive.h b/libgimp/gimpimagemetadata-interactive.h
new file mode 100644
index 0000000000..6c972b062d
--- /dev/null
+++ b/libgimp/gimpimagemetadata-interactive.h
@@ -0,0 +1,36 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimpimagemetadata-interactive.h
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
+#error "Only <libgimp/gimpui.h> can be included directly."
+#endif
+
+#ifndef __GIMP_IMAGE_METADATA_INTERACTIVE_H__
+#define __GIMP_IMAGE_METADATA_INTERACTIVE_H__
+
+
+void gimp_image_metadata_load_finish (GimpImage *image,
+ const gchar *mime_type,
+ GimpMetadata *metadata,
+ GimpMetadataLoadFlags flags,
+ gboolean interactive);
+
+
+#endif /* __GIMP_IMAGE_METADATA_INTERACTIVE_H__ */
diff --git a/libgimp/gimpimagemetadata.c b/libgimp/gimpimagemetadata.c
index 9e999e2781..be19ad0898 100644
--- a/libgimp/gimpimagemetadata.c
+++ b/libgimp/gimpimagemetadata.c
@@ -23,11 +23,9 @@
#include <string.h>
#include <sys/time.h>
-#include <gtk/gtk.h>
#include <gexiv2/gexiv2.h>
#include "gimp.h"
-#include "gimpui.h"
#include "gimpimagemetadata.h"
#include "libgimp-intl.h"
@@ -42,16 +40,6 @@ typedef struct
static void gimp_image_metadata_rotate (GimpImage *image,
GExiv2Orientation orientation);
-static GdkPixbuf * gimp_image_metadata_rotate_pixbuf (GdkPixbuf *pixbuf,
- GExiv2Orientation orientation);
-static void gimp_image_metadata_rotate_query (GimpImage *image,
- const gchar *mime_type,
- GimpMetadata *metadata,
- gboolean interactive);
-static gboolean gimp_image_metadata_rotate_dialog (GimpImage *image,
- GExiv2Orientation orientation,
- const gchar *parasite_name);
-
/* public functions */
@@ -63,7 +51,8 @@ static gboolean gimp_image_metadata_rotate_dialog (GimpImage *image,
* @error: Return location for error
*
* Loads and returns metadata from @file to be passed into
- * gimp_image_metadata_load_finish().
+ * gimp_image_metadata_load_finish() or
+ * gimp_image_metadata_load_finish_batch().
*
* Returns: (transfer full): The file's metadata.
*
@@ -93,25 +82,34 @@ gimp_image_metadata_load_prepare (GimpImage *image,
}
/**
- * gimp_image_metadata_load_finish:
+ * gimp_image_metadata_load_finish_batch:
* @image: The image
* @mime_type: The loaded file's mime-type
* @metadata: The metadata to set on the image
* @flags: Flags to specify what of the metadata to apply to the image
- * @interactive: Whether this function is allowed to query info with dialogs
*
* Applies the @metadata previously loaded with
* gimp_image_metadata_load_prepare() to the image, taking into account
* the passed @flags.
*
- * Since: 2.10
+ * Some metadata may involve some image changes and are better asked for
+ * confirmation. For instance the orientation metadata may be wrong at
+ * times (because it depends usually on camera sensors and the rotated
+ * image may not be what one expects). If the related flag is set (i.e.
+ * GIMP_METADATA_LOAD_ORIENTATION for orientation), then the change will
+ * be automatically executed (i.e. the image will be rotated) without
+ * any human interaction.
+ *
+ * If you wish such edit to be queried interactively with dialogs, use
+ * gimp_image_metadata_load_finish() instead, from libgimpui.
+ *
+ * Since: 3.0
*/
void
-gimp_image_metadata_load_finish (GimpImage *image,
- const gchar *mime_type,
- GimpMetadata *metadata,
- GimpMetadataLoadFlags flags,
- gboolean interactive)
+gimp_image_metadata_load_finish_batch (GimpImage *image,
+ const gchar *mime_type,
+ GimpMetadata *metadata,
+ GimpMetadataLoadFlags flags)
{
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (mime_type != NULL);
@@ -157,8 +155,11 @@ gimp_image_metadata_load_finish (GimpImage *image,
if (flags & GIMP_METADATA_LOAD_ORIENTATION)
{
- gimp_image_metadata_rotate_query (image, mime_type,
- metadata, interactive);
+ gimp_image_metadata_rotate (image,
+ gexiv2_metadata_get_orientation (GEXIV2_METADATA (metadata)));
+
+ gexiv2_metadata_set_orientation (GEXIV2_METADATA (metadata),
+ GEXIV2_ORIENTATION_NORMAL);
}
if (flags & GIMP_METADATA_LOAD_COLORSPACE)
@@ -315,262 +316,3 @@ gimp_image_metadata_rotate (GimpImage *image,
break;
}
}
-
-static GdkPixbuf *
-gimp_image_metadata_rotate_pixbuf (GdkPixbuf *pixbuf,
- GExiv2Orientation orientation)
-{
- GdkPixbuf *rotated = NULL;
- GdkPixbuf *temp;
-
- switch (orientation)
- {
- case GEXIV2_ORIENTATION_UNSPECIFIED:
- case GEXIV2_ORIENTATION_NORMAL: /* standard orientation, do nothing */
- rotated = g_object_ref (pixbuf);
- break;
-
- case GEXIV2_ORIENTATION_HFLIP:
- rotated = gdk_pixbuf_flip (pixbuf, TRUE);
- break;
-
- case GEXIV2_ORIENTATION_ROT_180:
- rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
- break;
-
- case GEXIV2_ORIENTATION_VFLIP:
- rotated = gdk_pixbuf_flip (pixbuf, FALSE);
- break;
-
- case GEXIV2_ORIENTATION_ROT_90_HFLIP: /* flipped diagonally around '\' */
- temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
- rotated = gdk_pixbuf_flip (temp, TRUE);
- g_object_unref (temp);
- break;
-
- case GEXIV2_ORIENTATION_ROT_90: /* 90 CW */
- rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
- break;
-
- case GEXIV2_ORIENTATION_ROT_90_VFLIP: /* flipped diagonally around '/' */
- temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
- rotated = gdk_pixbuf_flip (temp, FALSE);
- g_object_unref (temp);
- break;
-
- case GEXIV2_ORIENTATION_ROT_270: /* 90 CCW */
- rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
- break;
-
- default: /* shouldn't happen */
- break;
- }
-
- return rotated;
-}
-
-static void
-gimp_image_metadata_rotate_query (GimpImage *image,
- const gchar *mime_type,
- GimpMetadata *metadata,
- gboolean interactive)
-{
- GimpParasite *parasite;
- gchar *parasite_name;
- GExiv2Orientation orientation;
- gboolean query = interactive;
-
- orientation = gexiv2_metadata_get_orientation (GEXIV2_METADATA (metadata));
-
- if (orientation <= GEXIV2_ORIENTATION_NORMAL ||
- orientation > GEXIV2_ORIENTATION_MAX)
- return;
-
- parasite_name = g_strdup_printf ("gimp-metadata-exif-rotate(%s)", mime_type);
-
- parasite = gimp_get_parasite (parasite_name);
-
- if (parasite)
- {
- if (strncmp (gimp_parasite_data (parasite), "yes",
- gimp_parasite_data_size (parasite)) == 0)
- {
- query = FALSE;
- }
- else if (strncmp (gimp_parasite_data (parasite), "no",
- gimp_parasite_data_size (parasite)) == 0)
- {
- gimp_parasite_free (parasite);
- g_free (parasite_name);
- return;
- }
-
- gimp_parasite_free (parasite);
- }
-
- if (query && ! gimp_image_metadata_rotate_dialog (image,
- orientation,
- parasite_name))
- {
- g_free (parasite_name);
- return;
- }
-
- g_free (parasite_name);
-
- gimp_image_metadata_rotate (image, orientation);
- gexiv2_metadata_set_orientation (GEXIV2_METADATA (metadata),
- GEXIV2_ORIENTATION_NORMAL);
-}
-
-static gboolean
-gimp_image_metadata_rotate_dialog (GimpImage *image,
- GExiv2Orientation orientation,
- const gchar *parasite_name)
-{
- GtkWidget *dialog;
- GtkWidget *main_vbox;
- GtkWidget *vbox;
- GtkWidget *label;
- GtkWidget *toggle;
- GdkPixbuf *pixbuf;
- gchar *name;
- gchar *title;
- gint response;
-
- name = gimp_image_get_name (image);
- title = g_strdup_printf (_("Rotate %s?"), name);
- g_free (name);
-
- dialog = gimp_dialog_new (title, "gimp-metadata-rotate-dialog",
- NULL, 0, NULL, NULL,
-
- _("_Keep Original"), GTK_RESPONSE_CANCEL,
- _("_Rotate"), GTK_RESPONSE_OK,
-
- NULL);
-
- g_free (title);
-
- gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK,
- GTK_RESPONSE_CANCEL,
- -1);
-
- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
- gimp_window_set_transient (GTK_WINDOW (dialog));
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
- main_vbox, FALSE, FALSE, 0);
- gtk_widget_show (main_vbox);
-
-#define THUMBNAIL_SIZE 128
-
- pixbuf = gimp_image_get_thumbnail (image,
- THUMBNAIL_SIZE, THUMBNAIL_SIZE,
- GIMP_PIXBUF_SMALL_CHECKS);
-
- if (pixbuf)
- {
- GdkPixbuf *rotated;
- GtkWidget *hbox;
- GtkWidget *image;
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- label = gtk_label_new (_("Original"));
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
- gimp_label_set_attributes (GTK_LABEL (label),
- PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
- -1);
- gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- image = gtk_image_new_from_pixbuf (pixbuf);
- gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
- gtk_widget_show (image);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- label = gtk_label_new (_("Rotated"));
- gimp_label_set_attributes (GTK_LABEL (label),
- PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
- -1);
- gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- rotated = gimp_image_metadata_rotate_pixbuf (pixbuf, orientation);
- g_object_unref (pixbuf);
-
- image = gtk_image_new_from_pixbuf (rotated);
- g_object_unref (rotated);
-
- gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
- gtk_widget_show (image);
- }
-
- label = g_object_new (GTK_TYPE_LABEL,
- "label", _("This image contains Exif orientation "
- "metadata."),
- "wrap", TRUE,
- "justify", GTK_JUSTIFY_LEFT,
- "xalign", 0.0,
- "yalign", 0.5,
- NULL);
- gimp_label_set_attributes (GTK_LABEL (label),
- PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
- PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
- -1);
- /* eek */
- gtk_widget_set_size_request (GTK_WIDGET (label),
- 2 * THUMBNAIL_SIZE + 12, -1);
- gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- label = g_object_new (GTK_TYPE_LABEL,
- "label", _("Would you like to rotate the image?"),
- "wrap", TRUE,
- "justify", GTK_JUSTIFY_LEFT,
- "xalign", 0.0,
- "yalign", 0.5,
- NULL);
- /* eek */
- gtk_widget_set_size_request (GTK_WIDGET (label),
- 2 * THUMBNAIL_SIZE + 12, -1);
- gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again"));
- gtk_box_pack_end (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 0);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
- gtk_widget_show (toggle);
-
- response = gimp_dialog_run (GIMP_DIALOG (dialog));
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
- {
- GimpParasite *parasite;
- const gchar *str = (response == GTK_RESPONSE_OK) ? "yes" : "no";
-
- parasite = gimp_parasite_new (parasite_name,
- GIMP_PARASITE_PERSISTENT,
- strlen (str), str);
- gimp_attach_parasite (parasite);
- gimp_parasite_free (parasite);
- }
-
- gtk_widget_destroy (dialog);
-
- return (response == GTK_RESPONSE_OK);
-}
diff --git a/libgimp/gimpimagemetadata.h b/libgimp/gimpimagemetadata.h
index 2f1cec6ddb..8aac8f372b 100644
--- a/libgimp/gimpimagemetadata.h
+++ b/libgimp/gimpimagemetadata.h
@@ -18,10 +18,11 @@
* <https://www.gnu.org/licenses/>.
*/
-#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
-#error "Only <libgimp/gimpui.h> can be included directly."
+#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
+#error "Only <libgimp/gimp.h> can be included directly."
#endif
+
#ifndef __GIMP_IMAGE_METADATA_H__
#define __GIMP_IMAGE_METADATA_H__
@@ -34,11 +35,10 @@ GimpMetadata * gimp_image_metadata_load_prepare (GimpImage *image,
const gchar *mime_type,
GFile *file,
GError **error);
-void gimp_image_metadata_load_finish (GimpImage *image,
- const gchar *mime_type,
- GimpMetadata *metadata,
- GimpMetadataLoadFlags flags,
- gboolean interactive);
+void gimp_image_metadata_load_finish_batch (GimpImage *image,
+ const gchar *mime_type,
+ GimpMetadata *metadata,
+ GimpMetadataLoadFlags flags);
GimpMetadata * gimp_image_metadata_save_prepare (GimpImage *image,
const gchar *mime_type,
diff --git a/libgimp/gimpui.h b/libgimp/gimpui.h
index 2d3db085e4..a4ac9e53aa 100644
--- a/libgimp/gimpui.h
+++ b/libgimp/gimpui.h
@@ -36,7 +36,7 @@
#include <libgimp/gimpfontselectbutton.h>
#include <libgimp/gimpgradientselectbutton.h>
#include <libgimp/gimpimagecombobox.h>
-#include <libgimp/gimpimagemetadata.h>
+#include <libgimp/gimpimagemetadata-interactive.h>
#include <libgimp/gimpitemcombobox.h>
#include <libgimp/gimppaletteselectbutton.h>
#include <libgimp/gimppatternselectbutton.h>
diff --git a/libgimp/meson.build b/libgimp/meson.build
index 3ac6a6b2c8..3245c44ba1 100644
--- a/libgimp/meson.build
+++ b/libgimp/meson.build
@@ -146,6 +146,7 @@ libgimp_sources_introspectable = [
'gimpgradientselect.c',
'gimpimage.c',
'gimpimagecolorprofile.c',
+ 'gimpimagemetadata.c',
'gimpimagemetadata-save.c',
'gimpimageprocedure.c',
'gimpitem.c',
@@ -200,6 +201,7 @@ libgimp_headers_introspectable = [
'gimpgradientselect.h',
'gimpimage.h',
'gimpimagecolorprofile.h',
+ 'gimpimagemetadata.h',
'gimpimageprocedure.h',
'gimpitem.h',
'gimplayer.h',
@@ -233,7 +235,7 @@ libgimpui_sources_introspectable = [
'gimpfontselectbutton.c',
'gimpgradientselectbutton.c',
'gimpimagecombobox.c',
- 'gimpimagemetadata.c',
+ 'gimpimagemetadata-interactive.c',
'gimpitemcombobox.c',
'gimppaletteselectbutton.c',
'gimppatternselectbutton.c',
@@ -264,7 +266,7 @@ libgimpui_headers_introspectable = [
'gimpfontselectbutton.h',
'gimpgradientselectbutton.h',
'gimpimagecombobox.h',
- 'gimpimagemetadata.h',
+ 'gimpimagemetadata-interactive.h',
'gimpitemcombobox.h',
'gimppaletteselectbutton.h',
'gimppatternselectbutton.h',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]