[gegl] gegl_create_chain: move into library



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]