[gegl] Added syntactic sugar for graph construction for C



commit 7f00beed5a06c534738e09f68ce595b7a3a30c19
Author: �yvind Kolås <pippin gimp org>
Date:   Sun Nov 22 21:48:15 2009 +0000

    Added syntactic sugar for graph construction for C

 examples/csugar.c |   59 ++++++++++++++++++++
 gegl/Makefile.am  |    1 +
 gegl/gegl-c.c     |  158 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gegl/gegl.h       |   36 ++++++++++++
 4 files changed, 254 insertions(+), 0 deletions(-)
---
diff --git a/examples/csugar.c b/examples/csugar.c
new file mode 100644
index 0000000..a8e403f
--- /dev/null
+++ b/examples/csugar.c
@@ -0,0 +1,59 @@
+#include "config.h"
+#include <gegl.h>
+#include <gegl-plugin.h>
+#include <glib/gprintf.h>
+#include <gobject/gvaluecollector.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+/* Example file illustrating the syntactic sugar for graph
+ * construction in C
+ */
+
+gint
+main (gint argc,
+      gchar **argv)
+{
+  GeglNode *gegl, *sink;
+
+  if (argc != 4)
+    {
+      g_print ("Usage: %s <input image> \"string\" <output image>\n\n", argv[0]);
+      return -1;
+    }
+
+  g_thread_init (NULL);
+  gegl_init (&argc, &argv);
+
+  gegl =
+    gegl_graph (
+    sink = gegl_node ("gegl:png-save", "path", argv[3], NULL,
+    gegl_node   ("gegl:over", NULL,
+      gegl_node ("gegl:scale",
+                 "x", 0.4,
+                 "y", 0.4,
+                 NULL,
+      gegl_node ("gegl:invert",
+                 NULL,
+      gegl_node ("gegl:load",
+                 "path", argv[1],
+                 NULL
+    ))),
+      gegl_node ("gegl:translate",
+                 "x", 50.0,
+                 "y", 50.0,
+                 NULL,
+      gegl_node ("gegl:dropshadow", "opacity", 1.0, "radius", 3.0, "x", 3.0, "y", 3.0, NULL,
+        gegl_node ("gegl:text",
+                   "size", 40.0,
+                   "font", "sans bold",
+                   "string", argv[2],
+                   "color", gegl_color_new("green"),
+                   NULL
+    ))))));
+
+  gegl_node_process (sink);
+  g_object_unref (gegl);
+  gegl_exit ();
+  return 0;
+}
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index 200116e..72d9d55 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -41,6 +41,7 @@ GEGL_public_HEADERS =	\
     property-types/gegl-curve.h
 
 GEGL_sources = \
+	gegl-c.c			\
 	gegl-config.c			\
 	gegl-cpuaccel.c			\
 	gegl-dot.c			\
diff --git a/gegl/gegl-c.c b/gegl/gegl-c.c
new file mode 100644
index 0000000..e7a70c1
--- /dev/null
+++ b/gegl/gegl-c.c
@@ -0,0 +1,158 @@
+/* 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 2009 �yvind Kolås
+ */
+
+#include "config.h"
+#include <gegl.h>
+#include <gegl-plugin.h>
+#include <glib/gprintf.h>
+#include <gobject/gvaluecollector.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "graph/gegl-node.h"
+#include "graph/gegl-pad.h"
+
+static void
+gegl_graph_adopt (GeglNode *graph, GeglNode *node)
+{
+  GeglNode *input, *aux;
+
+  gegl_node_add_child (graph, node);
+  g_object_unref (node);
+
+  if ((input = gegl_node_get_producer (node, "input", NULL)))
+    gegl_graph_adopt (graph, input);
+  if ((aux = gegl_node_get_producer (node, "aux", NULL)))
+    gegl_graph_adopt (graph, aux);
+}
+
+GeglNode *
+gegl_graph (GeglNode *node)
+{
+  GeglNode *graph;
+
+  graph = g_object_new (GEGL_TYPE_NODE, NULL);
+  if (gegl_node_get_pad (node, "output"))
+    {
+      GeglNode *outproxynop = gegl_node_get_output_proxy (graph, "output");
+      gegl_node_connect_to (node, "output", outproxynop, "input"); 
+    }
+  gegl_graph_adopt (graph, node);
+  return graph;
+}
+
+GeglNode *
+gegl_node (const gchar *type,
+           const gchar *firstname,
+           ...)
+{
+  GeglNode      *node;
+  GeglOperation *operation;
+  va_list        var_args;
+  const gchar   *property_name;
+
+  node = g_object_new (GEGL_TYPE_NODE, "operation", type, NULL);
+  g_object_get (G_OBJECT (node), "gegl-operation", &operation, NULL);
+
+  g_object_freeze_notify (G_OBJECT (node));
+  va_start (var_args, firstname);
+  property_name = firstname;
+  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 (operation)
+            {
+              pspec = g_object_class_find_property (
+                G_OBJECT_GET_CLASS (G_OBJECT (operation)), property_name);
+            }
+          if (!pspec)
+            {
+              g_warning ("%s:%s has no property named: '%s'",
+                         G_STRFUNC,
+                         G_OBJECT_TYPE_NAME (operation), 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 (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 (operation), property_name, &value);
+          g_value_unset (&value);
+        }
+
+      property_name = va_arg (var_args, gchar *);
+    }
+  g_object_thaw_notify (G_OBJECT (node));
+
+  /* The input pads checked for are hard-coded, if no output is connected
+   * pass NULL to indicate no connected node.
+   */
+  if (gegl_node_get_pad (node, "input"))
+    {
+      GeglNode *input = va_arg (var_args, GeglNode*);
+
+      if (input)
+        gegl_node_connect_from (node, "input", input, "output");
+    }
+
+  if (gegl_node_get_pad (node, "aux"))
+    {
+      GeglNode *aux = va_arg (var_args, GeglNode*);
+
+      if (aux)
+        gegl_node_connect_from (node, "aux", aux, "output");
+    }
+  va_end (var_args);
+  return node;
+}
diff --git a/gegl/gegl.h b/gegl/gegl.h
index 3e9fa9a..4ef71e9 100644
--- a/gegl/gegl.h
+++ b/gegl/gegl.h
@@ -845,6 +845,42 @@ void           gegl_processor_destroy       (GeglProcessor *processor);
 GeglConfig      * gegl_config (void);
 
 
+/**
+ * gegl_node:
+ * @op_type:  the type of operation to create
+ * @first_property_name: 
+ * @...:
+ *
+ * Construct a GEGL node, connecting it to needed input nodes. The
+ * returned node does not have a parent but a single reference it
+ * is meant to be passed to gegl_graph () for gegl_graph () to assume
+ * its ownership. This is syntactic sugar for use from C, similar
+ * conveniences can easily be built externally in other languages.
+ *
+ * gegl_node(op_type, [key, value, [...]], NULL, [input, [aux]])
+ *
+ * Returns a new Gegl node.
+ */
+GeglNode *gegl_node (const gchar *op_type,
+                     const gchar *first_property_name,
+                     ...);
+
+
+/**
+ * gegl_graph:
+ * @node: the end result of a composition created with gegl_node()
+ *
+ * Creates a GeglNode containing a free floating graph constructed
+ * using gegl_node(). The GeglGraph adopts all the passed in nodes
+ * making it sufficient to unref the resulting graph.
+ *
+ * gegl_graph (gegl_node ("gegl:over", NULL,
+ *                        gegl_node (..), gegl_node (..)));
+ *
+ * Returns a GeglNode graph.
+ */
+GeglNode *gegl_graph (GeglNode *node);
+
 
 G_END_DECLS
 #endif  /* __GEGL_H__ */



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