[gegl] add an API to directly invoke commands on buffers
- From: Ãyvind KolÃs <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] add an API to directly invoke commands on buffers
- Date: Sat, 17 Mar 2012 14:46:10 +0000 (UTC)
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]