[gnome-photos/wip/rishi/edit-mode: 9/12] Add a basic image editing pipeline



commit 054f981be7fb1ac51e32daa04a436770fd16a86b
Author: Debarshi Ray <debarshir gnome org>
Date:   Thu Jan 29 15:55:48 2015 +0100

    Add a basic image editing pipeline

 src/Makefile.am        |    2 +
 src/photos-base-item.c |  105 ++++++++++++++++++++++++++++++++++++--
 src/photos-base-item.h |   11 ++++
 src/photos-pipeline.c  |  129 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/photos-pipeline.h  |   65 ++++++++++++++++++++++++
 5 files changed, 306 insertions(+), 6 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 3f34e56..5d6ec54 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -157,6 +157,8 @@ gnome_photos_SOURCES = \
        photos-organize-collection-view.h \
        photos-overview-searchbar.c \
        photos-overview-searchbar.h \
+       photos-pipeline.c \
+       photos-pipeline.h \
        photos-preview-model.c \
        photos-preview-model.h \
        photos-preview-nav-buttons.c \
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index 321cc2d..a5cdea8 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -42,6 +42,7 @@
 #include "photos-filterable.h"
 #include "photos-icons.h"
 #include "photos-local-item.h"
+#include "photos-pipeline.h"
 #include "photos-print-notification.h"
 #include "photos-print-operation.h"
 #include "photos-query.h"
@@ -56,13 +57,14 @@ struct _PhotosBaseItemPrivate
   cairo_surface_t *surface;
   GdkPixbuf *original_icon;
   GeglNode *graph;
-  GeglNode *node;
+  GeglNode *load;
   GeglRectangle bbox;
   GMutex mutex_download;
   GMutex mutex;
   GQuark equipment;
   GQuark flash;
   PhotosCollectionIconWatcher *watcher;
+  PhotosPipeline *pipeline;
   PhotosSelectionController *sel_cntrlr;
   TrackerSparqlCursor *cursor;
   gboolean collection;
@@ -730,6 +732,7 @@ static GeglNode *
 photos_base_item_load (PhotosBaseItem *self, GCancellable *cancellable, GError **error)
 {
   PhotosBaseItemPrivate *priv = self->priv;
+  GeglNode *output;
   GeglNode *ret_val = NULL;
   gchar *path = NULL;
 
@@ -739,13 +742,15 @@ photos_base_item_load (PhotosBaseItem *self, GCancellable *cancellable, GError *
       if (path == NULL)
         goto out;
 
-      gegl_node_set (priv->node, "path", path, NULL);
+      gegl_node_set (priv->load, "path", path, NULL);
       priv->loaded_once = TRUE;
     }
 
-  gegl_node_process (priv->node);
-  priv->bbox = gegl_node_get_bounding_box (priv->node);
-  ret_val = g_object_ref (priv->node);
+  output = photos_pipeline_get_output (priv->pipeline);
+  gegl_node_process (output);
+  priv->bbox = gegl_node_get_bounding_box (output);
+
+  ret_val = g_object_ref (output);
 
  out:
   g_free (path);
@@ -781,6 +786,47 @@ photos_base_item_load_in_thread_func (GTask *task,
 
 
 static void
+photos_base_item_process (PhotosBaseItem *self, GCancellable *cancellable, GError **error)
+{
+  PhotosBaseItemPrivate *priv = self->priv;
+  GeglNode *output;
+
+  if (!priv->loaded_once)
+    return;
+
+  output = photos_pipeline_get_output (priv->pipeline);
+  gegl_node_process (output);
+  priv->bbox = gegl_node_get_bounding_box (output);
+}
+
+
+static void
+photos_base_item_process_in_thread_func (GTask *task,
+                                         gpointer source_object,
+                                         gpointer task_data,
+                                         GCancellable *cancellable)
+{
+  PhotosBaseItem *self = PHOTOS_BASE_ITEM (source_object);
+  PhotosBaseItemPrivate *priv = self->priv;
+  GError *error = NULL;
+
+  g_mutex_lock (&priv->mutex);
+
+  photos_base_item_process (self, cancellable, &error);
+  if (error != NULL)
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  g_task_return_pointer (task, NULL, NULL);
+
+ out:
+  g_mutex_unlock (&priv->mutex);
+}
+
+
+static void
 photos_base_item_set_thumbnailing_icon (PhotosBaseItem *self)
 {
   if (thumbnailing_icon == NULL)
@@ -973,6 +1019,7 @@ photos_base_item_dispose (GObject *object)
   g_clear_object (&priv->graph);
   g_clear_object (&priv->original_icon);
   g_clear_object (&priv->watcher);
+  g_clear_object (&priv->pipeline);
   g_clear_object (&priv->sel_cntrlr);
   g_clear_object (&priv->cursor);
 
@@ -1129,6 +1176,13 @@ photos_base_item_filterable_iface_init (PhotosFilterableInterface *iface)
 }
 
 
+void
+photos_base_item_add_operation (PhotosBaseItem *self, const gchar *operation)
+{
+  photos_pipeline_add (self->priv->pipeline, operation);
+}
+
+
 gboolean
 photos_base_item_can_trash (PhotosBaseItem *self)
 {
@@ -1398,8 +1452,15 @@ photos_base_item_load_async (PhotosBaseItem *self,
 
   if (priv->graph == NULL)
     {
+      GeglNode *input;
+
       priv->graph = gegl_node_new ();
-      priv->node = gegl_node_new_child (priv->graph, "operation", "gegl:load", NULL);
+      priv->load = gegl_node_new_child (priv->graph, "operation", "gegl:load", NULL);
+
+      priv->pipeline = photos_pipeline_new ();
+      input = photos_pipeline_get_input (priv->pipeline);
+
+      gegl_node_link_many (priv->load, input, NULL);
     }
 
   task = g_task_new (self, cancellable, callback, user_data);
@@ -1439,6 +1500,38 @@ photos_base_item_print (PhotosBaseItem *self, GtkWidget *toplevel)
 
 
 void
+photos_base_item_process_async (PhotosBaseItem *self,
+                                GCancellable *cancellable,
+                                GAsyncReadyCallback callback,
+                                gpointer user_data)
+{
+  GTask *task;
+
+  g_return_if_fail (PHOTOS_IS_BASE_ITEM (self));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_check_cancellable (task, TRUE);
+  g_task_set_source_tag (task, photos_base_item_process_async);
+
+  g_task_run_in_thread (task, photos_base_item_process_in_thread_func);
+  g_object_unref (task);
+}
+
+
+void
+photos_base_item_process_finish (PhotosBaseItem *self, GAsyncResult *res, GError **error)
+{
+  GTask *task = G_TASK (res);
+
+  g_return_val_if_fail (g_task_is_valid (res, self), NULL);
+  g_return_val_if_fail (g_task_get_source_tag (task) == photos_base_item_process_async, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  g_task_propagate_pointer (task, error);
+}
+
+
+void
 photos_base_item_refresh (PhotosBaseItem *self)
 {
   GApplication *app;
diff --git a/src/photos-base-item.h b/src/photos-base-item.h
index 8313b8b..67c1646 100644
--- a/src/photos-base-item.h
+++ b/src/photos-base-item.h
@@ -88,6 +88,8 @@ struct _PhotosBaseItemClass
 
 GType               photos_base_item_get_type                (void) G_GNUC_CONST;
 
+void                photos_base_item_add_operation           (PhotosBaseItem *self, const gchar *operation);
+
 gboolean            photos_base_item_can_trash               (PhotosBaseItem *self);
 
 void                photos_base_item_destroy                 (PhotosBaseItem *self);
@@ -174,6 +176,15 @@ void                photos_base_item_open                    (PhotosBaseItem *se
 
 void                photos_base_item_print                   (PhotosBaseItem *self, GtkWidget *toplevel);
 
+void                photos_base_item_process_async           (PhotosBaseItem *self,
+                                                              GCancellable *cancellable,
+                                                              GAsyncReadyCallback callback,
+                                                              gpointer user_data);
+
+void                photos_base_item_process_finish          (PhotosBaseItem *self,
+                                                              GAsyncResult *res,
+                                                              GError **error);
+
 void                photos_base_item_refresh                 (PhotosBaseItem *self);
 
 void                photos_base_item_set_default_app_name    (PhotosBaseItem *self, const gchar 
*default_app_name);
diff --git a/src/photos-pipeline.c b/src/photos-pipeline.c
new file mode 100644
index 0000000..2efe5cb
--- /dev/null
+++ b/src/photos-pipeline.c
@@ -0,0 +1,129 @@
+/*
+ * Photos - access, organize and share your photos on GNOME
+ * Copyright © 2015 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "photos-pipeline.h"
+
+
+struct _PhotosPipeline
+{
+  GObject parent_instance;
+  GeglNode *graph;
+  GeglNode *nop;
+};
+
+struct _PhotosPipelineClass
+{
+  GObjectClass parent_class;
+};
+
+
+G_DEFINE_TYPE (PhotosPipeline, photos_pipeline, G_TYPE_OBJECT);
+
+
+static void
+photos_pipeline_dispose (GObject *object)
+{
+  PhotosPipeline *self = PHOTOS_PIPELINE (object);
+
+  g_clear_object (&self->graph);
+
+  G_OBJECT_CLASS (photos_pipeline_parent_class)->dispose (object);
+}
+
+
+static void
+photos_pipeline_finalize (GObject *object)
+{
+  PhotosPipeline *self = PHOTOS_PIPELINE (object);
+
+  G_OBJECT_CLASS (photos_pipeline_parent_class)->finalize (object);
+}
+
+
+static void
+photos_pipeline_init (PhotosPipeline *self)
+{
+  GeglNode *input;
+  GeglNode *output;
+
+  self->graph = gegl_node_new ();
+  input = gegl_node_get_input_proxy (self->graph, "input");
+  output = gegl_node_get_output_proxy (self->graph, "output");
+
+  self->nop = gegl_node_new_child (self->graph, "operation", "gegl:nop", NULL);
+  gegl_node_link_many (input, self->nop, output, NULL);
+}
+
+
+static void
+photos_pipeline_class_init (PhotosPipelineClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->dispose = photos_pipeline_dispose;
+  object_class->finalize = photos_pipeline_finalize;
+}
+
+
+PhotosPipeline *
+photos_pipeline_new (void)
+{
+  return g_object_new (PHOTOS_TYPE_PIPELINE, NULL);
+}
+
+
+void
+photos_pipeline_add (PhotosPipeline *self, const gchar *operation)
+{
+  GeglNode *last;
+  GeglNode *node;
+  GeglNode *output;
+
+  node = gegl_node_new_child (self->graph, "operation", operation, NULL);
+  output = gegl_node_get_output_proxy (self->graph, "output");
+  last = gegl_node_get_producer (output, "input", NULL);
+  gegl_node_disconnect (output, "input");
+  gegl_node_link_many (last, node, output, NULL);
+}
+
+
+GeglNode *
+photos_pipeline_get_input (PhotosPipeline *self)
+{
+  GeglNode *input;
+
+  input = gegl_node_get_input_proxy (self->graph, "input");
+  return input;
+}
+
+
+GeglNode *
+photos_pipeline_get_output (PhotosPipeline *self)
+{
+  GeglNode *output;
+
+  output = gegl_node_get_output_proxy (self->graph, "output");
+  return output;
+}
diff --git a/src/photos-pipeline.h b/src/photos-pipeline.h
new file mode 100644
index 0000000..3f1af1a
--- /dev/null
+++ b/src/photos-pipeline.h
@@ -0,0 +1,65 @@
+/*
+ * Photos - access, organize and share your photos on GNOME
+ * Copyright © 2015 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef PHOTOS_PIPELINE_H
+#define PHOTOS_PIPELINE_H
+
+#include <gegl.h>
+
+G_BEGIN_DECLS
+
+#define PHOTOS_TYPE_PIPELINE (photos_pipeline_get_type ())
+
+#define PHOTOS_PIPELINE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+   PHOTOS_TYPE_PIPELINE, PhotosPipeline))
+
+#define PHOTOS_PIPELINE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), \
+   PHOTOS_TYPE_PIPELINE, PhotosPipelineClass))
+
+#define PHOTOS_IS_PIPELINE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+   PHOTOS_TYPE_PIPELINE))
+
+#define PHOTOS_IS_PIPELINE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+   PHOTOS_TYPE_PIPELINE))
+
+#define PHOTOS_PIPELINE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+   PHOTOS_TYPE_PIPELINE, PhotosPipelineClass))
+
+typedef struct _PhotosPipeline      PhotosPipeline;
+typedef struct _PhotosPipelineClass PhotosPipelineClass;
+
+GType                  photos_pipeline_get_type          (void) G_GNUC_CONST;
+
+PhotosPipeline        *photos_pipeline_new               (void);
+
+void                   photos_pipeline_add               (PhotosPipeline *self, const gchar *operation);
+
+GeglNode              *photos_pipeline_get_input         (PhotosPipeline *self);
+
+GeglNode              *photos_pipeline_get_output        (PhotosPipeline *self);
+
+G_END_DECLS
+
+#endif /* PHOTOS_PIPELINE_H */


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