[gegl] oilify: add optional per-pixel buffers for controlling parameters
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] oilify: add optional per-pixel buffers for controlling parameters
- Date: Fri, 19 Jul 2019 15:14:19 +0000 (UTC)
commit 3e81f45ee346cba423f56e0f6ae2012fabd2a8a5
Author: Øyvind Kolås <pippin gimp org>
Date: Fri Jul 19 17:01:52 2019 +0200
oilify: add optional per-pixel buffers for controlling parameters
The mask-radius and exponent paremeters could in the original GIMP plug-in be
controlled per-pixel by extra specified drawables. This can now be achieved by
connecting the relevant paramterer maps to aux (mask-radius scaling factor) and
aux2 (exponent scaling factor).
operations/common-gpl3+/oilify.c | 108 ++++++++++++++++++++++++++++-----------
1 file changed, 78 insertions(+), 30 deletions(-)
---
diff --git a/operations/common-gpl3+/oilify.c b/operations/common-gpl3+/oilify.c
index 16a803dc7..5bdc2a089 100644
--- a/operations/common-gpl3+/oilify.c
+++ b/operations/common-gpl3+/oilify.c
@@ -17,6 +17,7 @@
* Copyright 1996 Torsten Martinsen
* Copyright 2007 Daniel Richard G.
* Copyright 2011 Hans Lo <hansshulo gmail com>
+ * Copyright 2019 Øyvind Kolås
*/
#include "config.h"
@@ -25,12 +26,13 @@
#ifdef GEGL_PROPERTIES
property_int (mask_radius, _("Mask Radius"), 4)
- description (_("Radius of circle around pixel"))
+ description (_("Radius of circle around pixel, can also be scaled per pixel by a buffer on the aux
pad."))
value_range (1, 100)
ui_range (1, 25)
ui_meta ("unit", "pixel-distance")
property_int (exponent, _("Exponent"), 8)
+ description (_("Exponent for processing; controls smoothness - can be scaled per pixel with a buffer on
the aux2 pad."))
value_range (1, 20)
property_int (intensities, _("Number of intensities"), 128)
@@ -42,7 +44,7 @@ property_boolean (use_inten, _("Intensity Mode"), TRUE)
#else
-#define GEGL_OP_AREA_FILTER
+#define GEGL_OP_COMPOSER3
#define GEGL_OP_NAME oilify
#define GEGL_OP_C_SOURCE oilify.c
@@ -263,24 +265,30 @@ oilify_pixel (gint x,
static void
prepare (GeglOperation *operation)
{
- GeglProperties *o;
- GeglOperationAreaFilter *op_area;
const Babl *space = gegl_operation_get_source_space (operation, "input");
- op_area = GEGL_OPERATION_AREA_FILTER (operation);
- o = GEGL_PROPERTIES (operation);
-
- op_area->left =
- op_area->right =
- op_area->top =
- op_area->bottom = o->mask_radius;
-
gegl_operation_set_format (operation, "input",
babl_format_with_space ("RGBA float", space));
gegl_operation_set_format (operation, "output",
babl_format_with_space ("RGBA float", space));
}
+static GeglRectangle
+get_required_for_output (GeglOperation *operation,
+ const gchar *input_pad,
+ const GeglRectangle *region)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ GeglRectangle rect = *region;
+
+ rect.x -= o->mask_radius;
+ rect.y -= o->mask_radius;
+ rect.width += o->mask_radius * 2;
+ rect.height += o->mask_radius * 2;
+
+ return rect;
+}
+
#include "opencl/gegl-cl.h"
#include "gegl-buffer-cl-iterator.h"
@@ -387,13 +395,14 @@ cl_process (GeglOperation *operation,
static gboolean
process (GeglOperation *operation,
GeglBuffer *input,
+ GeglBuffer *aux,
+ GeglBuffer *aux2,
GeglBuffer *output,
const GeglRectangle *result,
gint level)
{
- GeglProperties *o = GEGL_PROPERTIES (operation);
- GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
- const Babl *format = gegl_operation_get_format (operation, "output");
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ const Babl *format = gegl_operation_get_format (operation, "output");
gint x = o->mask_radius; /* initial x */
gint y = o->mask_radius; /* and y coordinates */
@@ -401,28 +410,49 @@ process (GeglOperation *operation,
gfloat *dst_buf;
gfloat *inten_buf;
gfloat *out_pixel;
+ gfloat *mask_radius_pixel = NULL;
+ gfloat *exponent_pixel = NULL;
+ gfloat *mask_radius_buf = NULL;
+ gfloat *exponent_buf = NULL;
gint n_pixels = result->width * result->height;
GeglRectangle src_rect;
gint total_pixels;
- if (gegl_operation_use_opencl (operation))
+ /* the opencl implementation doesn't (yet) support the parameter buffers */
+ if (aux == NULL &&
+ aux2 == NULL &&
+ gegl_operation_use_opencl (operation))
if (cl_process (operation, input, output, result))
return TRUE;
-
- src_rect.x = result->x - op_area->left;
- src_rect.width = result->width + op_area->left + op_area->right;
- src_rect.y = result->y - op_area->top;
- src_rect.height = result->height + op_area->top + op_area->bottom;
+ src_rect = *result;
+ src_rect.x -= o->mask_radius;
+ src_rect.y -= o->mask_radius;
+ src_rect.width += o->mask_radius*2;
+ src_rect.height += o->mask_radius*2;
total_pixels = src_rect.width * src_rect.height;
src_buf = gegl_malloc (4 * total_pixels * sizeof (gfloat));
dst_buf = gegl_malloc (4 * n_pixels * sizeof (gfloat));
+
if (o->use_inten)
inten_buf = gegl_malloc (total_pixels * sizeof (gfloat));
else
inten_buf = NULL;
+ if (aux)
+ {
+ mask_radius_buf = mask_radius_pixel = gegl_malloc (n_pixels * sizeof (gfloat));
+ gegl_buffer_get (aux, result, 1.0, babl_format_with_space ("Y float", format),
+ mask_radius_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+ }
+ if (aux2)
+ {
+ exponent_buf = exponent_pixel = gegl_malloc (n_pixels * sizeof (gfloat));
+ gegl_buffer_get (aux2, result, 1.0, babl_format_with_space ("Y float", format),
+ exponent_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+ }
+
gegl_buffer_get (input, &src_rect, 1.0, format,
src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
@@ -434,12 +464,26 @@ process (GeglOperation *operation,
while (n_pixels--)
{
+ float mask_radius = o->mask_radius;
+ float exponent = o->exponent;
+
+ if (exponent_pixel)
+ {
+ exponent *= CLAMP(*exponent_pixel, 0.0, 1.0);
+ exponent_pixel++;
+ }
+ if (mask_radius_pixel)
+ {
+ mask_radius *= CLAMP(*mask_radius_pixel, 0.0, 1.0);
+ mask_radius_pixel++;
+ }
+
if (inten_buf)
- oilify_pixel_inten (x, y, o->mask_radius, o->exponent, o->intensities,
- src_rect.width, src_buf, inten_buf, out_pixel);
+ oilify_pixel_inten (x, y, mask_radius, exponent, o->intensities,
+ src_rect.width, src_buf, inten_buf, out_pixel);
else
- oilify_pixel (x, y, o->mask_radius, o->exponent, o->intensities,
- src_rect.width, src_buf, out_pixel);
+ oilify_pixel (x, y, mask_radius, exponent, o->intensities,
+ src_rect.width, src_buf, out_pixel);
out_pixel += 4;
/* update x and y coordinates */
@@ -451,7 +495,6 @@ process (GeglOperation *operation,
}
}
-
gegl_buffer_set (output, result, 0,
babl_format_with_space ("RGBA float", format),
dst_buf, GEGL_AUTO_ROWSTRIDE);
@@ -459,6 +502,10 @@ process (GeglOperation *operation,
gegl_free (dst_buf);
if (inten_buf)
gegl_free (inten_buf);
+ if (mask_radius_buf)
+ gegl_free (mask_radius_buf);
+ if (exponent_buf)
+ gegl_free (exponent_buf);
return TRUE;
}
@@ -466,13 +513,14 @@ process (GeglOperation *operation,
static void
gegl_op_class_init (GeglOpClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationFilterClass *filter_class;
+ GeglOperationClass *operation_class;
+ GeglOperationComposer3Class *composer3_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- filter_class = GEGL_OPERATION_FILTER_CLASS (klass);
+ composer3_class = GEGL_OPERATION_COMPOSER3_CLASS (klass);
- filter_class->process = process;
+ composer3_class->process = process;
+ operation_class->get_required_for_output = get_required_for_output;
operation_class->prepare = prepare;
operation_class->threaded = FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]