[gegl] add an API to directly invoke commands on buffers



commit 4a7a011322337e0b6efd7a6e6d134bb1bfe774ac
Author: Ãyvind KolÃs <pippin gimp org>
Date:   Fri Mar 16 22:52:19 2012 +0000

    add an API to directly invoke commands on buffers
    
    For use directly inside ops or in stand-alone code where a graph is overkill.
    (Note that this API uses short temporary graphs of it's own...)

 gegl/Makefile.am  |    1 +
 gegl/gegl-apply.c |  298 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gegl/gegl.h       |   33 ++++++
 perf/Makefile     |    2 +-
 4 files changed, 333 insertions(+), 1 deletions(-)
---
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index 02a540e..6a70100 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -62,6 +62,7 @@ GEGL_public_HEADERS = \
 
 GEGL_introspectable_sources = \
 	gegl-c.c			\
+	gegl-apply.c  \
 	gegl-config.c			\
 	gegl-cpuaccel.c			\
 	gegl-dot.c			\
diff --git a/gegl/gegl-apply.c b/gegl/gegl-apply.c
new file mode 100644
index 0000000..0235faa
--- /dev/null
+++ b/gegl/gegl-apply.c
@@ -0,0 +1,298 @@
+/* This file is part of GEGL
+ *
+ * GEGL 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.
+ *
+ * GEGL 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 GEGL; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2003 Calvin Williamson
+ *           2006 Ãyvind KolÃs
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
+#include "gegl-types-internal.h"
+
+#include "gegl.h"
+#include "gegl-apply.h"
+
+#include "graph/gegl-node.h"
+
+#include "operation/gegl-operation.h"
+#include "operation/gegl-operations.h"
+#include "operation/gegl-operation-meta.h"
+#include "operation/gegl-operation-point-filter.h"
+
+#include "process/gegl-eval-mgr.h"
+#include "process/gegl-have-visitor.h"
+#include "process/gegl-prepare-visitor.h"
+#include "process/gegl-finish-visitor.h"
+#include "process/gegl-processor.h"
+
+
+static void
+gegl_node_set_props (GeglNode *node,
+                     va_list   var_args)
+{
+  const char *property_name;
+
+  g_object_freeze_notify (G_OBJECT (node));
+
+  property_name = va_arg (var_args, gchar *);
+  while (property_name)
+    {
+      GValue      value = { 0, };
+      GParamSpec *pspec = NULL;
+      gchar      *error = NULL;
+
+      if (!strcmp (property_name, "name"))
+        {
+          pspec = g_object_class_find_property (
+            G_OBJECT_GET_CLASS (G_OBJECT (node)), property_name);
+
+          g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+          G_VALUE_COLLECT (&value, var_args, 0, &error);
+          if (error)
+            {
+              g_warning ("%s: %s", G_STRFUNC, error);
+              g_free (error);
+              g_value_unset (&value);
+              break;
+            }
+          g_object_set_property (G_OBJECT (node), property_name, &value);
+          g_value_unset (&value);
+        }
+      else
+        {
+          if (node->operation)
+            {
+              pspec = g_object_class_find_property (
+                G_OBJECT_GET_CLASS (G_OBJECT (node->operation)), property_name);
+            }
+          if (!pspec)
+            {
+              g_warning ("%s:%s has no property named: '%s'",
+                         G_STRFUNC,
+                         gegl_node_get_debug_name (node), property_name);
+              break;
+            }
+          if (!(pspec->flags & G_PARAM_WRITABLE))
+            {
+              g_warning ("%s: property (%s of operation class '%s' is not writable",
+                         G_STRFUNC,
+                         pspec->name,
+                         G_OBJECT_TYPE_NAME (node->operation));
+              break;
+            }
+
+          g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+          G_VALUE_COLLECT (&value, var_args, 0, &error);
+          if (error)
+            {
+              g_warning ("%s: %s", G_STRFUNC, error);
+              g_free (error);
+              g_value_unset (&value);
+              break;
+            }
+          g_object_set_property (G_OBJECT (node->operation), property_name, &value);
+          g_value_unset (&value);
+        }
+      property_name = va_arg (var_args, gchar *);
+    }
+  g_object_thaw_notify (G_OBJECT (node));
+}
+
+
+void
+gegl_apply_op (GeglBuffer *buffer,
+               const gchar *first_property_name,
+               ...)
+{
+  va_list var_args;
+
+  g_return_if_fail (GEGL_IS_BUFFER (buffer));
+
+  va_start (var_args, first_property_name);
+  gegl_apply_op_valist (buffer, first_property_name, var_args);
+  va_end (var_args);
+}
+
+void
+gegl_apply_op_valist (GeglBuffer  *buffer,
+                      const gchar *first_property_name,
+                      va_list      var_args)
+{
+  GeglBuffer  *tempbuf = NULL;
+  GeglNode    *node;
+  GeglNode    *source;
+  GeglNode    *sink;
+
+  g_return_if_fail (GEGL_IS_BUFFER (buffer));
+
+  g_object_ref (buffer);
+
+  source  = gegl_node_new_child (NULL, "operation", "gegl:buffer-source",
+                                    "buffer", buffer,
+                                    NULL);
+  node   = gegl_node_new_child (NULL, "operation", first_property_name, NULL);
+
+  if (!GEGL_IS_OPERATION_POINT_FILTER (node->operation))
+    {
+      tempbuf = gegl_buffer_new (gegl_buffer_get_extent (buffer), gegl_buffer_get_format (buffer));
+
+      sink = gegl_node_new_child (NULL, "operation", "gegl:write-buffer",
+                                        "buffer", tempbuf,
+                                        NULL);
+    }
+  else
+    {
+      sink = gegl_node_new_child (NULL, "operation", "gegl:write-buffer",
+                                        "buffer", buffer,
+                                        NULL);
+    }
+
+  gegl_node_link_many (source, node, sink, NULL);
+
+  gegl_node_set_props (node, var_args);
+
+  gegl_node_process (sink);
+
+  g_object_unref (source);
+  g_object_unref (node);
+  g_object_unref (sink);
+
+  if (tempbuf)
+    {
+      gegl_buffer_copy (tempbuf, NULL, buffer, NULL);
+      g_object_unref (tempbuf);
+    }
+  g_object_unref (buffer);
+}
+
+GeglBuffer *gegl_filter_op_valist (GeglBuffer    *buffer,
+                                   const gchar   *first_property_name,
+                                   va_list        var_args)
+{
+  GeglBuffer  *tempbuf = NULL;
+  GeglNode    *node;
+  GeglNode    *source;
+  GeglNode    *sink;
+
+  //g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
+
+  if (buffer)
+    {
+      g_object_ref (buffer);
+      source  = gegl_node_new_child (NULL, "operation", "gegl:buffer-source",
+                                        "buffer", buffer,
+                                        NULL);
+    }
+  node   = gegl_node_new_child (NULL, "operation", first_property_name, NULL);
+
+  sink = gegl_node_new_child (NULL, "operation", "gegl:buffer-sink",
+                                    "buffer", &tempbuf,
+                                    NULL);
+
+  if (buffer)
+    gegl_node_link_many (source, node, sink, NULL);
+  else
+    gegl_node_link_many (node, sink, NULL);
+
+  gegl_node_set_props (node, var_args);
+
+  gegl_node_process (sink);
+
+  if (buffer)
+    {
+      g_object_unref (source);
+      g_object_unref (buffer);
+    }
+  g_object_unref (node);
+  g_object_unref (sink);
+
+  return tempbuf;
+}
+
+GeglBuffer *gegl_filter_op     (GeglBuffer    *buffer,
+                                const gchar   *first_property_name,
+                                ...)
+{
+  GeglBuffer *ret;
+  va_list var_args;
+
+  //g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
+
+  va_start (var_args, first_property_name);
+  ret = gegl_filter_op_valist (buffer, first_property_name, var_args);
+  va_end (var_args);
+  return ret;
+}
+
+
+
+void
+gegl_render_op (GeglBuffer *source_buffer,
+                GeglBuffer *target_buffer,
+                const gchar *first_property_name,
+                ...)
+{
+  va_list var_args;
+
+  g_return_if_fail (GEGL_IS_BUFFER (source_buffer));
+  g_return_if_fail (GEGL_IS_BUFFER (target_buffer));
+
+  va_start (var_args, first_property_name);
+  gegl_render_op_valist (source_buffer, target_buffer,
+                         first_property_name, var_args);
+  va_end (var_args);
+}
+
+void
+gegl_render_op_valist (GeglBuffer  *source_buffer,
+                       GeglBuffer  *target_buffer,
+                       const gchar *first_property_name,
+                       va_list      var_args)
+{
+  GeglNode    *node;
+  GeglNode    *source;
+  GeglNode    *sink;
+
+  g_return_if_fail (GEGL_IS_BUFFER (source_buffer));
+  g_return_if_fail (GEGL_IS_BUFFER (target_buffer));
+
+  g_object_ref (source_buffer);
+  g_object_ref (target_buffer);
+
+  source  = gegl_node_new_child (NULL, "operation", "gegl:buffer-source",
+                                       "buffer", source_buffer,
+                                       NULL);
+  node   = gegl_node_new_child (NULL, "operation", first_property_name, NULL);
+
+  sink   = gegl_node_new_child (NULL, "operation", "gegl:write-buffer",
+                                      "buffer", target_buffer,
+                                      NULL);
+
+  gegl_node_link_many (source, node, sink, NULL);
+  gegl_node_set_props (node, var_args);
+  gegl_node_process (sink);
+
+  g_object_unref (source);
+  g_object_unref (node);
+  g_object_unref (sink);
+
+  g_object_unref (source_buffer);
+  g_object_unref (target_buffer);
+}
diff --git a/gegl/gegl.h b/gegl/gegl.h
index 0d4195b..61e9daa 100644
--- a/gegl/gegl.h
+++ b/gegl/gegl.h
@@ -838,6 +838,39 @@ void           gegl_processor_destroy       (GeglProcessor *processor);
 GeglConfig      * gegl_config (void);
 
 
+
+void        gegl_apply_op  (GeglBuffer    *buffer,
+                            const gchar   *operation_name,
+                            ...) G_GNUC_NULL_TERMINATED;
+
+GeglBuffer *gegl_filter_op (GeglBuffer    *source_buffer,
+                            const gchar   *operation_name,
+                            ...) G_GNUC_NULL_TERMINATED;
+
+void        gegl_render_op (GeglBuffer    *source_buffer,
+                            GeglBuffer    *target_buffer,
+                            const gchar   *operation_name,
+                            ...) G_GNUC_NULL_TERMINATED;
+
+/* the following only exist to make gegl_apply nad gegl_filter bindable */
+void        gegl_apply_op_valist (GeglBuffer    *buffer,
+                                  const gchar   *operation_name,
+                                  va_list        var_args);
+
+GeglBuffer *gegl_filter_op_valist (GeglBuffer   *source_buffer,
+                                   const gchar  *operation_name,
+                                   va_list       var_args);
+
+void        gegl_render_op_valist (GeglBuffer   *source_buffer,
+                                   GeglBuffer   *target_buffer,
+                                   const gchar  *operation_name,
+                                   va_list       var_args);
+
+
+
+
+
+
 /**
  * gegl_node: (skip)
  * @op_type:  the type of operation to create
diff --git a/perf/Makefile b/perf/Makefile
index 6d9dff7..18d00dc 100644
--- a/perf/Makefile
+++ b/perf/Makefile
@@ -2,7 +2,7 @@
 # revision to start at
 START_REV = master
 # number of revisions to create
-REVISIONS = 100
+REVISIONS = 20
 
 MAKE_FLAGS = -j3 -k
 CC = "ccache gcc"   # if you do not have ccache replace with just gcc



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