[gegl] gegl_create_chain: move into library
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gegl_create_chain: move into library
- Date: Fri, 25 Mar 2016 00:31:10 +0000 (UTC)
commit 6cff9393aa741001e5b2140f94af106ab7024141
Author: Øyvind Kolås <pippin gimp org>
Date: Sat Mar 12 20:58:01 2016 +0100
gegl_create_chain: move into library
bin/gegl-options.c | 8 ++
bin/gegl-options.h | 2 +
bin/gegl.c | 189 ++--------------------------
bin/ui.c | 4 +-
gegl/Makefile.am | 1 +
gegl/gegl-serialize.c | 333 +++++++++++++++++++++++++++++++++++++++++++++++++
gegl/gegl-utils.h | 6 +
7 files changed, 361 insertions(+), 182 deletions(-)
---
diff --git a/bin/gegl-options.c b/bin/gegl-options.c
index 7b295bf..e12c1ba 100644
--- a/bin/gegl-options.c
+++ b/bin/gegl-options.c
@@ -293,6 +293,14 @@ parse_args (int argc,
o->fatal_warnings=1;
}
+ else if (match ("--serialize")){
+ o->serialize=TRUE;
+ }
+
+ else if (match ("-S")){
+ o->serialize=TRUE;
+ }
+
else if (match ("-p")){
o->play=TRUE;
}
diff --git a/bin/gegl-options.h b/bin/gegl-options.h
index 3b4d121..8b9861d 100644
--- a/bin/gegl-options.h
+++ b/bin/gegl-options.h
@@ -49,6 +49,8 @@ struct _GeglOptions
gboolean play;
gdouble scale;
+
+ gboolean serialize;
};
GeglOptions *gegl_options_parse (gint argc,
diff --git a/bin/gegl.c b/bin/gegl.c
index 9a84558..9638385 100644
--- a/bin/gegl.c
+++ b/bin/gegl.c
@@ -76,8 +76,6 @@ static gboolean file_is_gegl_xml (const gchar *path)
return FALSE;
}
-void gegl_create_chain (char **ops, GeglNode *iter, GeglNode *proxy);
-
int mrg_ui_main (int argc, char **argv, char **ops);
gint
@@ -192,12 +190,19 @@ main (gint argc,
return 1;
}
+ {
+ GeglNode *proxy = gegl_node_get_output_proxy (gegl, "output");
+ GeglNode *iter = gegl_node_get_producer (proxy, "input", NULL);
if (o->rest)
{
- GeglNode *proxy = gegl_node_get_output_proxy (gegl, "output");
- GeglNode *iter = gegl_node_get_producer (proxy, "input", NULL);
- gegl_create_chain (o->rest, iter, proxy);
+ gegl_create_chain_argv (o->rest, iter, proxy);
+ if (o->serialize)
+ {
+ fprintf (stderr, "%s\n", gegl_serialize (iter,
+ gegl_node_get_producer (proxy, "input", NULL)));
+ }
}
+ }
switch (o->mode)
{
@@ -280,177 +285,3 @@ main (gint argc,
return 0;
}
-void gegl_create_chain (char **ops, GeglNode *start, GeglNode *proxy)
-{
- GeglNode *iter[10] = {start, NULL};
- GeglNode *new = NULL;
- gchar **arg = ops;
- int level = 0;
- char *level_op[10];
- char *level_pad[10];
- GHashTable *ht = NULL;
-
- level_op[level] = *arg;
-
- ht = g_hash_table_new (g_str_hash, g_str_equal);
-
- while (*arg)
- {
- if (strchr (*arg, ']'))
- {
- level--;
- gegl_node_connect_to (iter[level+1], "output", iter[level], level_pad[level]);
- }
- else
- {
- if (strchr (*arg, '=')) /* contains = sign, must be a property assignment */
- {
- char *match= strchr (*arg, '=');
- if (match[1] == '[')
- {
- char *pad = g_strdup (*arg);
- char *value = strchr (pad, '=') + 1;
- value[-1] = '\0';
- level_pad[level]=(void*)g_intern_string(pad);
- g_free (pad);
- level++;
-
- iter[level]=NULL;
- level_op[level]=NULL;
- level_pad[level]=NULL;
- }
- else
- {
- GType target_type = G_TYPE_INT;
- GValue gvalue={0,};
- char *key = g_strdup (*arg);
- char *value = strchr (key, '=') + 1;
- value[-1] = '\0';
-
- if (!strcmp (key, "id"))
- {
- g_hash_table_insert (ht, (void*)g_intern_string (value), iter[level]);
- }
- else if (!strcmp (key, "ref"))
- {
- if (g_hash_table_lookup (ht, g_intern_string (value)))
- iter[level] = g_hash_table_lookup (ht, g_intern_string (value));
- else
- g_warning ("unknown id '%s'", value);
- }
- else
- {
- unsigned int n_props = 0;
- GParamSpec **pspecs;
- int i;
-
- pspecs = gegl_operation_list_properties (level_op[level], &n_props);
- for (i = 0; i < n_props; i++)
- {
- if (!strcmp (pspecs[i]->name, key))
- target_type = pspecs[i]->value_type;
- }
- if (target_type == G_TYPE_DOUBLE || target_type == G_TYPE_FLOAT)
- {
- double val = g_strtod (value, NULL);
- gegl_node_set (iter[level], key, val, NULL);
- }
- else if (target_type == G_TYPE_BOOLEAN) {
- if (!strcmp (value, "true") || !strcmp (value, "TRUE") ||
- !strcmp (value, "YES") || !strcmp (value, "yes") ||
- !strcmp (value, "y") || !strcmp (value, "Y") ||
- !strcmp (value, "1") || !strcmp (value, "on"))
- {
- gegl_node_set (iter[level], key, TRUE, NULL);
- }
- else
- {
- gegl_node_set (iter[level], key, FALSE, NULL);
- }
- }
- else if (target_type == G_TYPE_INT)
- {
- int val = g_strtod (value, NULL);
- gegl_node_set (iter[level], key, val, NULL);
- }
- else if (target_type == GEGL_TYPE_COLOR)
- {
- GeglColor *color = g_object_new (GEGL_TYPE_COLOR,
- "string", value, NULL);
- gegl_node_set (iter[level], key, color, NULL);
- }
- else if (g_type_is_a (target_type, G_TYPE_ENUM))
- {
- GEnumClass *eclass = g_type_class_peek (target_type);
- GEnumValue *evalue = g_enum_get_value_by_nick (eclass, value);
- if (evalue)
- {
- gegl_node_set (new, key, evalue->value, NULL);
- }
- else
- {
- /* warn, but try to get a valid nick out of the old-style
- * value name
- */
- gchar *nick;
- gchar *c;
- g_printerr ("gedl (param_set %s): enum %s has no value '%s'\n",
- key,
- g_type_name (target_type),
- value);
- nick = g_strdup (value);
- for (c = nick; *c; c++)
- {
- *c = g_ascii_tolower (*c);
- if (*c == ' ')
- *c = '-';
- }
- evalue = g_enum_get_value_by_nick (eclass, nick);
- if (evalue)
- gegl_node_set (iter[level], key, evalue->value, NULL);
- g_free (nick);
- }
- }
- else
- {
- GValue gvalue_transformed={0,};
- g_value_init (&gvalue, G_TYPE_STRING);
- g_value_set_string (&gvalue, value);
- g_value_init (&gvalue_transformed, target_type);
- g_value_transform (&gvalue, &gvalue_transformed);
- gegl_node_set_property (iter[level], key, &gvalue_transformed);
- g_value_unset (&gvalue);
- g_value_unset (&gvalue_transformed);
- }
- }
- g_free (key);
- }
- }
- else
- {
- if (strchr (*arg, ':')) /* contains : is a non-prefixed operation */
- {
- level_op[level] = *arg;
- }
- else /* default to gegl: as prefix if no : specified */
- {
- char temp[1024];
- snprintf (temp, 1023, "gegl:%s", *arg);
- level_op[level] = (void*)g_intern_string (temp);
- }
- new = gegl_node_new_child (gegl_node_get_parent (proxy), "operation",
- level_op[level], NULL);
-
- if (iter[level])
- gegl_node_link_many (iter[level], new, proxy, NULL);
- else
- gegl_node_link_many (new, proxy, NULL);
- iter[level] = new;
- }
- }
- arg++;
- }
-
- g_hash_table_unref (ht);
- gegl_node_link_many (iter[level], proxy, NULL);
-}
diff --git a/bin/ui.c b/bin/ui.c
index c00f284..4d57534 100644
--- a/bin/ui.c
+++ b/bin/ui.c
@@ -93,7 +93,6 @@ static void sdl_add_audio_sample (int sample_pos, float left, float right)
static int audio_started = 0;
-void gegl_create_chain (char **ops, GeglNode *iter, GeglNode *proxy);
/* this structure contains the full application state, and is what
* re-renderings of the UI is directly based on.
@@ -346,7 +345,6 @@ static State *hack_state = NULL; // XXX: this shoudl be factored away
char **ops = NULL;
-
static void open_audio (int frequency)
{
SDL_AudioSpec spec = {0};
@@ -1372,7 +1370,7 @@ static void load_path (State *o)
if (o->ops)
{
- gegl_create_chain(o->ops,
+ gegl_create_chain_argv (o->ops,
gegl_node_get_producer (o->sink, "input", NULL),
o->sink);
}
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index e53777d..72956e0 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -97,6 +97,7 @@ GEGL_sources = \
gegl-xml.c \
gegl-gio.c \
gegl-random.c \
+ gegl-serialize.c \
gegl-matrix.c \
\
gegl-algorithms.h \
diff --git a/gegl/gegl-serialize.c b/gegl/gegl-serialize.c
new file mode 100644
index 0000000..24affd0
--- /dev/null
+++ b/gegl/gegl-serialize.c
@@ -0,0 +1,333 @@
+/* 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 2016 Øyvind Kolås
+ */
+
+#include "gegl.h"
+#include <string.h>
+
+void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
+{
+ GeglNode *iter[10] = {start, NULL};
+ GeglNode *new = NULL;
+ gchar **arg = ops;
+ int level = 0;
+ char *level_op[10];
+ char *level_pad[10];
+ GHashTable *ht = NULL;
+
+ level_op[level] = *arg;
+
+ ht = g_hash_table_new (g_str_hash, g_str_equal);
+
+ while (*arg)
+ {
+ if (strchr (*arg, ']'))
+ {
+ level--;
+ gegl_node_connect_to (iter[level+1], "output", iter[level], level_pad[level]);
+ }
+ else
+ {
+ if (strchr (*arg, '=')) /* contains = sign, must be a property assignment */
+ {
+ char *match= strchr (*arg, '=');
+ if (match[1] == '[')
+ {
+ char *pad = g_strdup (*arg);
+ char *value = strchr (pad, '=') + 1;
+ value[-1] = '\0';
+ level_pad[level]=(void*)g_intern_string(pad);
+ g_free (pad);
+ level++;
+
+ iter[level]=NULL;
+ level_op[level]=NULL;
+ level_pad[level]=NULL;
+ }
+ else
+ {
+ GType target_type = G_TYPE_INT;
+ GValue gvalue={0,};
+ char *key = g_strdup (*arg);
+ char *value = strchr (key, '=') + 1;
+ value[-1] = '\0';
+
+ if (!strcmp (key, "id"))
+ {
+ g_hash_table_insert (ht, (void*)g_intern_string (value), iter[level]);
+ }
+ else if (!strcmp (key, "ref"))
+ {
+ if (g_hash_table_lookup (ht, g_intern_string (value)))
+ iter[level] = g_hash_table_lookup (ht, g_intern_string (value));
+ else
+ g_warning ("unknown id '%s'", value);
+ }
+ else
+ {
+ unsigned int n_props = 0;
+ GParamSpec **pspecs;
+ int i;
+
+ pspecs = gegl_operation_list_properties (level_op[level], &n_props);
+ for (i = 0; i < n_props; i++)
+ {
+ if (!strcmp (pspecs[i]->name, key))
+ target_type = pspecs[i]->value_type;
+ }
+ if (target_type == G_TYPE_DOUBLE || target_type == G_TYPE_FLOAT)
+ {
+ double val = g_strtod (value, NULL);
+ gegl_node_set (iter[level], key, val, NULL);
+ }
+ else if (target_type == G_TYPE_BOOLEAN) {
+ if (!strcmp (value, "true") || !strcmp (value, "TRUE") ||
+ !strcmp (value, "YES") || !strcmp (value, "yes") ||
+ !strcmp (value, "y") || !strcmp (value, "Y") ||
+ !strcmp (value, "1") || !strcmp (value, "on"))
+ {
+ gegl_node_set (iter[level], key, TRUE, NULL);
+ }
+ else
+ {
+ gegl_node_set (iter[level], key, FALSE, NULL);
+ }
+ }
+ else if (target_type == G_TYPE_INT)
+ {
+ int val = g_strtod (value, NULL);
+ gegl_node_set (iter[level], key, val, NULL);
+ }
+ else if (target_type == GEGL_TYPE_COLOR)
+ {
+ GeglColor *color = g_object_new (GEGL_TYPE_COLOR,
+ "string", value, NULL);
+ gegl_node_set (iter[level], key, color, NULL);
+ }
+ else if (g_type_is_a (target_type, G_TYPE_ENUM))
+ {
+ GEnumClass *eclass = g_type_class_peek (target_type);
+ GEnumValue *evalue = g_enum_get_value_by_nick (eclass, value);
+ if (evalue)
+ {
+ gegl_node_set (new, key, evalue->value, NULL);
+ }
+ else
+ {
+ /* warn, but try to get a valid nick out of the old-style
+ * value name
+ */
+ gchar *nick;
+ gchar *c;
+ g_printerr ("gedl (param_set %s): enum %s has no value '%s'\n",
+ key,
+ g_type_name (target_type),
+ value);
+ nick = g_strdup (value);
+ for (c = nick; *c; c++)
+ {
+ *c = g_ascii_tolower (*c);
+ if (*c == ' ')
+ *c = '-';
+ }
+ evalue = g_enum_get_value_by_nick (eclass, nick);
+ if (evalue)
+ gegl_node_set (iter[level], key, evalue->value, NULL);
+ g_free (nick);
+ }
+ }
+ else
+ {
+ GValue gvalue_transformed={0,};
+ g_value_init (&gvalue, G_TYPE_STRING);
+ g_value_set_string (&gvalue, value);
+ g_value_init (&gvalue_transformed, target_type);
+ g_value_transform (&gvalue, &gvalue_transformed);
+ gegl_node_set_property (iter[level], key, &gvalue_transformed);
+ g_value_unset (&gvalue);
+ g_value_unset (&gvalue_transformed);
+ }
+ }
+ g_free (key);
+ }
+ }
+ else
+ {
+ if (strchr (*arg, ':')) /* contains : is a non-prefixed operation */
+ {
+ level_op[level] = *arg;
+ }
+ else /* default to gegl: as prefix if no : specified */
+ {
+ char temp[1024];
+ g_snprintf (temp, 1023, "gegl:%s", *arg);
+ level_op[level] = (void*)g_intern_string (temp);
+ }
+ new = gegl_node_new_child (gegl_node_get_parent (proxy), "operation",
+ level_op[level], NULL);
+
+ if (iter[level])
+ gegl_node_link_many (iter[level], new, proxy, NULL);
+ else
+ gegl_node_link_many (new, proxy, NULL);
+ iter[level] = new;
+ }
+ }
+ arg++;
+ }
+
+ g_hash_table_unref (ht);
+ gegl_node_link_many (iter[level], proxy, NULL);
+}
+
+void gegl_create_chain (const char *str, GeglNode *op_start, GeglNode *op_end)
+{
+ gchar **argv = NULL;
+ gint argc = 0;
+ g_shell_parse_argv (str, &argc, &argv, NULL);
+ if (argv)
+ {
+ gegl_create_chain_argv (argv, op_start, op_end);
+ g_strfreev (argv);
+ }
+}
+
+gchar *gegl_serialize (GeglNode *start, GeglNode *end)
+{
+ char *ret = NULL;
+ GeglNode *iter;
+ GString *str = g_string_new ("");
+ if (start == NULL && 0)
+ {
+ start = end;
+ while (gegl_node_get_producer (start, "input", NULL))
+ start = gegl_node_get_producer (start, "input", NULL);
+ }
+
+ iter = end;
+ while (iter)
+ {
+ if (iter == start)
+ {
+ iter = NULL;
+ }
+ else
+ {
+ GString *s2 = g_string_new ("");
+ g_string_append_printf (s2, " %s", gegl_node_get_operation (iter));
+
+ {
+ gint i;
+ guint n_properties;
+ GParamSpec **properties;
+
+ properties = gegl_operation_list_properties (gegl_node_get_operation (iter), &n_properties);
+ for (i = 0; i < n_properties; i++)
+ {
+ const gchar *property_name = g_param_spec_get_name (properties[i]);
+ GType property_type = G_PARAM_SPEC_VALUE_TYPE (properties[i]);
+
+ if (property_type == G_TYPE_FLOAT)
+ {
+ gfloat value;
+ gchar str[G_ASCII_DTOSTR_BUF_SIZE];
+ gegl_node_get (iter, properties[i]->name, &value, NULL);
+ g_ascii_dtostr (str, sizeof(str), value);
+ g_string_append_printf (s2, " %s=%s", property_name, str);
+ }
+ else if (property_type == G_TYPE_DOUBLE)
+ {
+ gdouble value;
+ gchar str[G_ASCII_DTOSTR_BUF_SIZE];
+ gegl_node_get (iter, property_name, &value, NULL);
+ g_ascii_dtostr (str, sizeof(str), value);
+ g_string_append_printf (s2, " %s=%s", property_name, str);
+ }
+ else if (property_type == G_TYPE_INT)
+ {
+ gint value;
+ gchar str[64];
+ gegl_node_get (iter, properties[i]->name, &value, NULL);
+ g_snprintf (str, sizeof (str), "%i", value);
+ g_string_append_printf (s2, " %s=%s", property_name, str);
+ }
+ else if (property_type == G_TYPE_BOOLEAN)
+ {
+ gboolean value;
+ gegl_node_get (iter, properties[i]->name, &value, NULL);
+ if (value)
+ g_string_append_printf (s2, " %s=true", property_name);
+ else
+ g_string_append_printf (s2, " %s=false", property_name);
+ }
+ else if (property_type == G_TYPE_STRING)
+ {
+ gchar *value;
+ gegl_node_get (iter, properties[i]->name, &value, NULL);
+ g_string_append_printf (s2, " %s='%s'", property_name, value);
+ g_free (value);
+ }
+ else if (g_type_is_a (property_type, G_TYPE_ENUM))
+ {
+ GEnumClass *eclass = g_type_class_peek (property_type);
+ GEnumValue *evalue;
+ gint value;
+
+ gegl_node_get (iter, properties[i]->name, &value, NULL);
+ evalue = g_enum_get_value (eclass, value);
+
+ g_string_append_printf (s2, " %s=%s", property_name, evalue->value_nick);
+ }
+ else if (property_type == GEGL_TYPE_COLOR)
+ {
+ GeglColor *color;
+ gchar *value;
+ gegl_node_get (iter, properties[i]->name, &color, NULL);
+ g_object_get (color, "string", &value, NULL);
+ g_object_unref (color);
+ g_string_append_printf (s2, " %s='%s'", property_name, value);
+ g_free (value);
+ }
+ else
+ {
+ g_warning ("%s: serialization of %s properties not implemented",
+ property_name, g_type_name (property_type));
+
+ }
+
+ {
+ GeglNode *aux = gegl_node_get_producer (iter, "aux", NULL);
+ if (aux)
+ {
+ char *str = gegl_serialize (NULL, aux);
+ g_string_append_printf (s2, " aux=[ %s ]", str);
+ g_free (str);
+ }
+ }
+ }
+ }
+
+ g_string_prepend (str, s2->str);
+ g_string_free (s2, TRUE);
+ iter = gegl_node_get_producer (iter, "input", NULL);
+ }
+ }
+ ret = str->str;
+ g_string_free (str, FALSE);
+
+ return ret;
+}
diff --git a/gegl/gegl-utils.h b/gegl/gegl-utils.h
index d4d3d03..417b31d 100644
--- a/gegl/gegl-utils.h
+++ b/gegl/gegl-utils.h
@@ -260,6 +260,12 @@ gint _gegl_float_epsilon_zero (float value);
gint _gegl_float_epsilon_equal (float v1,
float v2);
+/**
+ */
+void gegl_create_chain (const char *str, GeglNode *op_start, GeglNode *op_end);
+void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy);
+gchar *gegl_serialize (GeglNode *start, GeglNode *end);
+
G_END_DECLS
#endif /* __GEGL_UTILS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]