[gegl] recursive-transform: merge back recursive-transform-plus changes
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] recursive-transform: merge back recursive-transform-plus changes
- Date: Sun, 17 Jun 2018 19:44:30 +0000 (UTC)
commit 6be0a86583f9c10c7710c96c21c261e4227c4727
Author: Ell <ell_se yahoo com>
Date: Sun Jun 17 14:44:11 2018 -0400
recursive-transform: merge back recursive-transform-plus changes
... which add support for applying multiple transformations
simultaneously, by specifiying a semicolon-separated list of
matrices through the "transform" property.
Note that, currently, the "fade-color" and "fade-opacity" properties
are applied to all transforms; in the future, we might want to add
per-transform fade properties. This can be done without breaking
backward-compatibility, and the global fade properties can still be
useful.
operations/common/recursive-transform.c | 286 ++++++++++++------
operations/workshop/Makefile.am | 1 -
operations/workshop/recursive-transform-plus.c | 392 -------------------------
po/POTFILES.in | 1 -
4 files changed, 203 insertions(+), 477 deletions(-)
---
diff --git a/operations/common/recursive-transform.c b/operations/common/recursive-transform.c
index d0d254814..cca5b3030 100644
--- a/operations/common/recursive-transform.c
+++ b/operations/common/recursive-transform.c
@@ -20,12 +20,14 @@
#include <glib/gi18n-lib.h>
#define MAX_ITERATIONS 20
+#define MAX_TRANSFORMS 10
#define EPSILON 1e-6
#ifdef GEGL_PROPERTIES
-property_string (transform, _("Transform"), "")
- description (_("Transformation matrix, using SVG syntax"))
+property_string (transform, _("Transform"), "matrix (1, 0, 0, 0, 1, 0, 0, 0, 1)")
+ description (_("Transformation matrix, using SVG syntax "
+ "(or multiple matrices, separated by semicolons)"))
property_int (first_iteration, _("First iteration"), 0)
description (_("First iteration"))
@@ -62,23 +64,24 @@ property_enum (sampler_type, _("Resampling method"),
typedef struct
{
- GeglNode *transform_node;
+ GeglNode *transform_nodes[MAX_TRANSFORMS];
GeglNode *color_overlay_node;
GeglNode *opacity_node;
- GeglNode *over_node;
+ GeglNode *over_nodes[MAX_TRANSFORMS];
} Iteration;
static void
update_graph (GeglOperation *operation)
{
- GeglProperties *o = GEGL_PROPERTIES (operation);
- Iteration *iters = o->user_data;
- GeglNode *node = operation->node;
- GeglNode *input;
- GeglNode *output;
- GeglMatrix3 transform;
- gdouble fade_color[4];
- gint i;
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ Iteration *iters = o->user_data;
+ GeglNode *node = operation->node;
+ GeglNode *input;
+ GeglNode *output;
+ gchar **matrix_strs;
+ gdouble fade_color[4];
+ gint i;
+ gint j;
if (! iters)
return;
@@ -90,17 +93,30 @@ update_graph (GeglOperation *operation)
for (i = 0; i <= MAX_ITERATIONS; i++)
{
- gegl_node_disconnect (iters[i].over_node, "input");
- gegl_node_disconnect (iters[i].over_node, "aux");
- gegl_node_disconnect (iters[i].opacity_node, "input");
- gegl_node_disconnect (iters[i].color_overlay_node, "input");
- gegl_node_disconnect (iters[i].transform_node, "input");
+ for (j = MAX_TRANSFORMS - 1; j >= 0; j--)
+ {
+ gegl_node_disconnect (iters[i].over_nodes[j], "input");
+ gegl_node_disconnect (iters[i].over_nodes[j], "aux");
+ }
+
+ gegl_node_disconnect (iters[i].opacity_node, "input");
+ gegl_node_disconnect (iters[i].color_overlay_node, "input");
+
+ for (j = 0; j < MAX_TRANSFORMS; j++)
+ gegl_node_disconnect (iters[i].transform_nodes[j], "input");
}
if (o->first_iteration == 0 && o->iterations == 0)
return;
- gegl_matrix3_parse_string (&transform, o->transform);
+ matrix_strs = g_strsplit (o->transform, ";", MAX_TRANSFORMS + 1);
+
+ if (! matrix_strs[0])
+ {
+ g_strfreev (matrix_strs);
+
+ return;
+ }
gegl_color_get_rgba (o->fade_color,
&fade_color[0],
@@ -108,78 +124,172 @@ update_graph (GeglOperation *operation)
&fade_color[2],
&fade_color[3]);
- for (i = o->iterations; i >= 0; i--)
+ if (! matrix_strs[1])
{
- GeglNode *source_node;
- GeglMatrix3 matrix;
- gchar *matrix_str;
- gint n = o->first_iteration + i;
- gint j;
-
- gegl_matrix3_identity (&matrix);
+ GeglMatrix3 transform;
- for (j = 0; j < n; j++)
- gegl_matrix3_multiply (&matrix, &transform, &matrix);
+ gegl_matrix3_parse_string (&transform, matrix_strs[0]);
- matrix_str = gegl_matrix3_to_string (&matrix);
+ for (i = o->iterations; i >= 0; i--)
+ {
+ GeglNode *source_node;
+ GeglMatrix3 matrix;
+ gchar *matrix_str;
+ gint n = o->first_iteration + i;
- gegl_node_set (iters[i].transform_node,
- "transform", matrix_str,
- "sampler", o->sampler_type,
- NULL);
+ gegl_matrix3_identity (&matrix);
- g_free (matrix_str);
+ for (j = 0; j < n; j++)
+ gegl_matrix3_multiply (&matrix, &transform, &matrix);
- gegl_node_link (input, iters[i].transform_node);
- source_node = iters[i].transform_node;
+ matrix_str = gegl_matrix3_to_string (&matrix);
- if (n > 0 && fabs (fade_color[3]) > EPSILON)
- {
- GeglColor *color = gegl_color_new (NULL);
- gdouble a = 1.0 - pow (1.0 - fade_color[3], n);
-
- gegl_color_set_rgba (color,
- fade_color[0],
- fade_color[1],
- fade_color[2],
- a);
-
- gegl_node_set (iters[i].color_overlay_node,
- "value", color,
- "srgb", TRUE,
+ gegl_node_set (iters[i].transform_nodes[0],
+ "transform", matrix_str,
+ "sampler", o->sampler_type,
NULL);
- g_object_unref (color);
+ g_free (matrix_str);
- gegl_node_link (source_node, iters[i].color_overlay_node);
- source_node = iters[i].color_overlay_node;
- }
+ gegl_node_link (input, iters[i].transform_nodes[0]);
+ source_node = iters[i].transform_nodes[0];
- if (n > 0 && fabs (o->fade_opacity - 1.0) > EPSILON)
- {
- gegl_node_set (iters[i].opacity_node,
- "value", pow (o->fade_opacity, n),
- NULL);
+ if (n > 0 && fabs (fade_color[3]) > EPSILON)
+ {
+ GeglColor *color = gegl_color_new (NULL);
+ gdouble a = 1.0 - pow (1.0 - fade_color[3], n);
- gegl_node_link (source_node, iters[i].opacity_node);
- source_node = iters[i].opacity_node;
- }
+ gegl_color_set_rgba (color,
+ fade_color[0],
+ fade_color[1],
+ fade_color[2],
+ a);
- gegl_node_connect_to (source_node, "output",
- iters[i].over_node, ! o->paste_below ? "input" :
- "aux");
+ gegl_node_set (iters[i].color_overlay_node,
+ "value", color,
+ "srgb", TRUE,
+ NULL);
- if (i == 0)
- {
- gegl_node_link (iters[i].over_node, output);
+ g_object_unref (color);
+
+ gegl_node_link (source_node, iters[i].color_overlay_node);
+ source_node = iters[i].color_overlay_node;
+ }
+
+ if (n > 0 && fabs (o->fade_opacity - 1.0) > EPSILON)
+ {
+ gegl_node_set (iters[i].opacity_node,
+ "value", pow (o->fade_opacity, n),
+ NULL);
+
+ gegl_node_link (source_node, iters[i].opacity_node);
+ source_node = iters[i].opacity_node;
+ }
+
+ gegl_node_connect_to (source_node, "output",
+ iters[i].over_nodes[0], ! o->paste_below ? "input" :
+ "aux");
+
+ if (i == 0)
+ {
+ gegl_node_link (iters[i].over_nodes[0], output);
+ }
+ else
+ {
+ gegl_node_connect_to (iters[i].over_nodes[0], "output",
+ iters[i - 1].over_nodes[0], ! o->paste_below ? "aux" :
+ "input");
+ }
}
- else
+ }
+ else
+ {
+ gint n_iterations = MIN (o->first_iteration + o->iterations, MAX_ITERATIONS);
+ gint n_transforms;
+
+ for (n_transforms = 0;
+ n_transforms < MAX_TRANSFORMS && matrix_strs[n_transforms];
+ n_transforms++);
+
+ for (i = n_iterations; i >= 0; i--)
{
- gegl_node_connect_to (iters[i].over_node, "output",
- iters[i - 1].over_node, ! o->paste_below ? "aux" :
- "input");
+ if (i < n_iterations)
+ {
+ GeglNode *source_node = NULL;
+
+ for (j = 0; j < n_transforms; j++)
+ {
+ gegl_node_set (iters[i].transform_nodes[j],
+ "transform", matrix_strs[j],
+ "sampler", o->sampler_type,
+ NULL);
+
+ gegl_node_link (iters[i + 1].over_nodes[n_transforms - 1],
+ iters[i].transform_nodes[j]);
+
+ if (j == 0)
+ {
+ source_node = iters[i].transform_nodes[j];
+ }
+ else
+ {
+ if (! o->paste_below)
+ {
+ gegl_node_connect_to (source_node, "output",
+ iters[i].over_nodes[j - 1], "input");
+ gegl_node_connect_to (iters[i].transform_nodes[j], "output",
+ iters[i].over_nodes[j - 1], "aux");
+ }
+ else
+ {
+ gegl_node_connect_to (source_node, "output",
+ iters[i].over_nodes[j - 1], "aux");
+ gegl_node_connect_to (iters[i].transform_nodes[j], "output",
+ iters[i].over_nodes[j - 1], "input");
+ }
+
+ source_node = iters[i].over_nodes[j - 1];
+ }
+ }
+
+ if (fabs (fade_color[3]) > EPSILON)
+ {
+ gegl_node_set (iters[i].color_overlay_node,
+ "value", o->fade_color,
+ "srgb", TRUE,
+ NULL);
+
+ gegl_node_link (source_node, iters[i].color_overlay_node);
+ source_node = iters[i].color_overlay_node;
+ }
+
+ if (fabs (o->fade_opacity - 1.0) > EPSILON)
+ {
+ gegl_node_set (iters[i].opacity_node,
+ "value", o->fade_opacity,
+ NULL);
+
+ gegl_node_link (source_node, iters[i].opacity_node);
+ source_node = iters[i].opacity_node;
+ }
+
+ gegl_node_connect_to (source_node, "output",
+ iters[i].over_nodes[n_transforms - 1], ! o->paste_below ? "aux" :
+ "input");
+ }
+
+ if (i >= o->first_iteration)
+ {
+ gegl_node_connect_to (input, "output",
+ iters[i].over_nodes[n_transforms - 1], ! o->paste_below ? "input" :
+ "aux");
+ }
}
+
+ gegl_node_link (iters[0].over_nodes[n_transforms - 1], output);
}
+
+ g_strfreev (matrix_strs);
}
static void
@@ -189,16 +299,23 @@ attach (GeglOperation *operation)
Iteration *iters = o->user_data;
GeglNode *node = operation->node;
gint i;
+ gint j;
if (! iters)
iters = o->user_data = g_new (Iteration, MAX_ITERATIONS + 1);
for (i = 0; i <= MAX_ITERATIONS; i++)
{
- iters[i].transform_node =
- gegl_node_new_child (node,
- "operation", "gegl:transform",
- NULL);
+ for (j = 0; j < MAX_TRANSFORMS; j++)
+ {
+ iters[i].transform_nodes[j] =
+ gegl_node_new_child (node,
+ "operation", "gegl:transform",
+ NULL);
+
+ gegl_operation_meta_watch_node (operation,
+ iters[i].transform_nodes[j]);
+ }
iters[i].color_overlay_node =
gegl_node_new_child (node,
@@ -210,17 +327,20 @@ attach (GeglOperation *operation)
"operation", "gegl:opacity",
NULL);
- iters[i].over_node =
- gegl_node_new_child (node,
- "operation", "gegl:over",
- NULL);
-
gegl_operation_meta_watch_nodes (operation,
- iters[i].transform_node,
iters[i].color_overlay_node,
iters[i].opacity_node,
- iters[i].over_node,
NULL);
+
+ for (j = 0; j < MAX_TRANSFORMS; j++)
+ {
+ iters[i].over_nodes[j] =
+ gegl_node_new_child (node,
+ "operation", "gegl:over",
+ NULL);
+
+ gegl_operation_meta_watch_node (operation, iters[i].over_nodes[j]);
+ }
}
update_graph (operation);
diff --git a/operations/workshop/Makefile.am b/operations/workshop/Makefile.am
index 5f6107a10..52a3ce1b3 100644
--- a/operations/workshop/Makefile.am
+++ b/operations/workshop/Makefile.am
@@ -24,6 +24,5 @@ op_LTLIBRARIES = \
integral-image.la \
linear-sinusoid.la \
rawbayer-load.la \
- recursive-transform-plus.la \
segment-kmeans.la \
selective-hue-saturation.la
diff --git a/po/POTFILES.in b/po/POTFILES.in
index efb2c6b53..819f38466 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -259,6 +259,5 @@ operations/workshop/hstack.c
operations/workshop/integral-image.c
operations/workshop/linear-sinusoid.c
operations/workshop/rawbayer-load.c
-operations/workshop/recursive-transform-plus.c
operations/workshop/segment-kmeans.c
operations/workshop/selective-hue-saturation.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]