[gegl] operations: add gegl:lens-flare
- From: Thomas Manni <tmanni src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] operations: add gegl:lens-flare
- Date: Sun, 28 Dec 2014 12:56:30 +0000 (UTC)
commit 2373fbfdb247ffd2ab73051eecefd59230a43844
Author: Thomas Manni <thomas manni free fr>
Date: Sun Dec 28 13:45:15 2014 +0100
operations: add gegl:lens-flare
operations/common/Makefile.am | 1 +
operations/common/lens-flare.c | 516 +++++++++++++++++++++++++++
po/POTFILES.in | 1 +
tests/compositions/Makefile.am | 1 +
tests/compositions/lens-flare.xml | 15 +
tests/compositions/reference/lens-flare.png | Bin 0 -> 327275 bytes
6 files changed, 534 insertions(+), 0 deletions(-)
---
diff --git a/operations/common/Makefile.am b/operations/common/Makefile.am
index 0ed85b3..76839cb 100644
--- a/operations/common/Makefile.am
+++ b/operations/common/Makefile.am
@@ -61,6 +61,7 @@ op_LTLIBRARIES = \
invert-linear.la \
layer.la \
lens-distortion.la \
+ lens-flare.la \
levels.la \
linear-gradient.la \
load.la \
diff --git a/operations/common/lens-flare.c b/operations/common/lens-flare.c
new file mode 100644
index 0000000..7f68247
--- /dev/null
+++ b/operations/common/lens-flare.c
@@ -0,0 +1,516 @@
+/* This file is an image processing operation for GEGL
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Karl-Johan Andersson <t96kja student tdb uu se>
+ *
+ * GEGL port: Thomas Manni <thomas manni free fr>
+ *
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+#include <math.h>
+
+#ifdef GEGL_PROPERTIES
+
+property_double (pos_x, _("X position"), 0.5)
+ description (_("X coordinates of the flare center"))
+ ui_range (0.0, 1.0)
+ ui_meta ("unit", "relative-coordinate")
+ ui_meta ("axis", "x")
+
+property_double (pos_y, _("Y position"), 0.5)
+ description (_("Y coordinates of the flare center"))
+ ui_range (0.0, 1.0)
+ ui_meta ("unit", "relative-coordinate")
+ ui_meta ("axis", "y")
+
+#else
+
+#define GEGL_OP_POINT_FILTER
+#define GEGL_OP_C_FILE "lens-flare.c"
+
+#include "gegl-op.h"
+
+#define NUMREF 19
+
+typedef struct
+{
+ gdouble ccol[3];
+ gfloat size;
+ gint xp;
+ gint yp;
+ gint type;
+} Reflect;
+
+typedef struct
+{
+ Reflect ref[NUMREF];
+ gdouble color[3];
+ gdouble glow[3];
+ gdouble inner[3];
+ gdouble outer[3];
+ gdouble halo[3];
+ gfloat color_size;
+ gfloat glow_size;
+ gfloat inner_size;
+ gfloat outer_size;
+ gfloat halo_size;
+ gint center_x;
+ gint center_y;
+} LfParamsType;
+
+static inline void
+fixpix (gfloat *pixel,
+ gfloat procent,
+ gdouble *colpro)
+{
+ pixel[0] += (1.0 - pixel[0]) * procent * colpro[0];
+ pixel[1] += (1.0 - pixel[1]) * procent * colpro[1];
+ pixel[2] += (1.0 - pixel[2]) * procent * colpro[2];
+}
+
+static void
+init_params (LfParamsType *params,
+ GeglProperties *o)
+{
+ Reflect *ref1 = params->ref;
+
+ params->color[0] = 0.937255;
+ params->color[1] = 0.937255;
+ params->color[2] = 0.937255;
+ params->glow[0] = 0.960784;
+ params->glow[1] = 0.960784;
+ params->glow[2] = 0.960784;
+ params->inner[0] = 1.0;
+ params->inner[1] = 0.149020;
+ params->inner[2] = 0.168627;
+ params->outer[0] = 0.270588;
+ params->outer[1] = 0.231373;
+ params->outer[2] = 0.250980;
+ params->halo[0] = 0.313726;
+ params->halo[1] = 0.058824;
+ params->halo[2] = 0.015686;
+
+ ref1[0].type = 1;
+ ref1[0].ccol[0] = 0.0;
+ ref1[0].ccol[1] = 0.054902;
+ ref1[0].ccol[2] = 0.443137;
+
+ ref1[1].type = 1;
+ ref1[1].ccol[0] = 0.352941;
+ ref1[1].ccol[1] = 0.709804;
+ ref1[1].ccol[2] = 0.556863;
+
+ ref1[2].type = 1;
+ ref1[2].ccol[0] = 0.219608;
+ ref1[2].ccol[1] = 0.549020;
+ ref1[2].ccol[2] = 0.415686;
+
+ ref1[3].type = 2;
+ ref1[3].ccol[0] = 0.035294;
+ ref1[3].ccol[1] = 0.113725;
+ ref1[3].ccol[2] = 0.074510;
+
+ ref1[4].type = 2;
+ ref1[4].ccol[0] = 0.094118;
+ ref1[4].ccol[1] = 0.054902;
+ ref1[4].ccol[2] = 0.0;
+
+ ref1[5].type = 2;
+ ref1[5].ccol[0] = 0.094118;
+ ref1[5].ccol[1] = 0.054902;
+ ref1[5].ccol[2] = 0.0;
+
+ ref1[6].type = 2;
+ ref1[6].ccol[0] = 0.164706;
+ ref1[6].ccol[1] = 0.074510;
+ ref1[6].ccol[2] = 0.0;
+
+ ref1[7].type = 2;
+ ref1[7].ccol[0] = 0.0;
+ ref1[7].ccol[1] = 0.035294;
+ ref1[7].ccol[2] = 0.066667;
+
+ ref1[8].type = 2;
+ ref1[8].ccol[0] = 0.0;
+ ref1[8].ccol[1] = 0.015686;
+ ref1[8].ccol[2] = 0.039216;
+
+ ref1[9].type = 2;
+ ref1[9].ccol[0] = 0.019608;
+ ref1[9].ccol[1] = 0.019608;
+ ref1[9].ccol[2] = 0.054902;
+
+ ref1[10].type = 2;
+ ref1[10].ccol[0] = 0.035294;
+ ref1[10].ccol[1] = 0.015686;
+ ref1[10].ccol[2] = 0.0;
+
+ ref1[11].type = 2;
+ ref1[11].ccol[0] = 0.035294;
+ ref1[11].ccol[1] = 0.015686;
+ ref1[11].ccol[2] = 0.0;
+
+ ref1[12].type = 3;
+ ref1[12].ccol[0] = 0.133333;
+ ref1[12].ccol[1] = 0.074510;
+ ref1[12].ccol[2] = 0.0;
+
+ ref1[13].type = 3;
+ ref1[13].ccol[0] = 0.054902;
+ ref1[13].ccol[1] = 0.101961;
+ ref1[13].ccol[2] = 0.0;
+
+ ref1[14].type = 3;
+ ref1[14].ccol[0] = 0.039216;
+ ref1[14].ccol[1] = 0.098039;
+ ref1[14].ccol[2] = 0.050980;
+
+ ref1[15].type = 4;
+ ref1[15].ccol[0] = 0.035294;
+ ref1[15].ccol[1] = 0.0;
+ ref1[15].ccol[2] = 0.066667;
+
+ ref1[16].type = 4;
+ ref1[16].ccol[0] = 0.035294;
+ ref1[16].ccol[1] = 0.062745;
+ ref1[16].ccol[2] = 0.019608;
+
+ ref1[17].type = 4;
+ ref1[17].ccol[0] = 0.066667;
+ ref1[17].ccol[1] = 0.015686;
+ ref1[17].ccol[2] = 0.0;
+
+ ref1[18].type = 4;
+ ref1[18].ccol[0] = 0.066667;
+ ref1[18].ccol[1] = 0.015686;
+ ref1[18].ccol[2] = 0.0;
+}
+
+static void
+update_params (gdouble sx,
+ gdouble sy,
+ gint width,
+ gint height,
+ LfParamsType *params)
+{
+ gint xh, yh, dx, dy, matt;
+ Reflect *ref1 = params->ref;
+
+ params->center_x = gegl_coordinate_relative_to_pixel(sx,
+ width);
+ params->center_y = gegl_coordinate_relative_to_pixel(sy,
+ height);
+
+ matt = width;
+
+ params->color_size = (gfloat) matt * 0.0375;
+ params->glow_size = (gfloat) matt * 0.078125;
+ params->inner_size = (gfloat) matt * 0.1796875;
+ params->outer_size = (gfloat) matt * 0.3359375;
+ params->halo_size = (gfloat) matt * 0.084375;
+
+ xh = width / 2;
+ yh = height / 2;
+ dx = xh - params->center_x;
+ dy = yh - params->center_y;
+
+ ref1[0].size = (gfloat) matt * 0.027;
+ ref1[0].xp = 0.6699 * dx + xh;
+ ref1[0].yp = 0.6699 * dy + yh;
+
+ ref1[1].size = (gfloat) matt * 0.01;
+ ref1[1].xp = 0.2692 * dx + xh;
+ ref1[1].yp = 0.2692 * dy + yh;
+
+ ref1[2].size = (gfloat) matt * 0.005;
+ ref1[2].xp = -0.0112 * dx + xh;
+ ref1[2].yp = -0.0112 * dy + yh;
+
+ ref1[3].size = (gfloat) matt * 0.031;
+ ref1[3].xp = 0.6490 * dx + xh;
+ ref1[3].yp = 0.6490 * dy + yh;
+
+ ref1[4].size = (gfloat) matt * 0.015;
+ ref1[4].xp = 0.4696 * dx + xh;
+ ref1[4].yp = 0.4696 * dy + yh;
+
+ ref1[5].size = (gfloat) matt * 0.037;
+ ref1[5].xp = 0.4087 * dx + xh;
+ ref1[5].yp = 0.4087 * dy + yh;
+
+ ref1[6].size = (gfloat) matt * 0.022;
+ ref1[6].xp = -0.2003 * dx + xh;
+ ref1[6].yp = -0.2003 * dy + yh;
+
+ ref1[7].size = (gfloat) matt * 0.025;
+ ref1[7].xp = -0.4103 * dx + xh;
+ ref1[7].yp = -0.4103 * dy + yh;
+
+ ref1[8].size = (gfloat) matt * 0.058;
+ ref1[8].xp = -0.4503 * dx + xh;
+ ref1[8].yp = -0.4503 * dy + yh;
+
+ ref1[9].size = (gfloat) matt * 0.017;
+ ref1[9].xp = -0.5112 * dx + xh;
+ ref1[9].yp = -0.5112 * dy + yh;
+
+ ref1[10].size = (gfloat) matt * 0.2;
+ ref1[10].xp = -1.496 * dx + xh;
+ ref1[10].yp = -1.496 * dy + yh;
+
+ ref1[11].size = (gfloat) matt * 0.5;
+ ref1[11].xp = -1.496 * dx + xh;
+ ref1[11].yp = -1.496 * dy + yh;
+
+ ref1[12].size = (gfloat) matt * 0.075;
+ ref1[12].xp = 0.4487 * dx + xh;
+ ref1[12].yp = 0.4487 * dy + yh;
+
+ ref1[13].size = (gfloat) matt * 0.1;
+ ref1[13].xp = dx + xh;
+ ref1[13].yp = dy + yh;
+
+ ref1[14].size = (gfloat) matt * 0.039;
+ ref1[14].xp = -1.301 * dx + xh;
+ ref1[14].yp = -1.301 * dy + yh;
+
+ ref1[15].size = (gfloat) matt * 0.19;
+ ref1[15].xp = 1.309 * dx + xh;
+ ref1[15].yp = 1.309 * dy + yh;
+
+ ref1[16].size = (gfloat) matt * 0.195;
+ ref1[16].xp = 1.309 * dx + xh;
+ ref1[16].yp = 1.309 * dy + yh;
+
+ ref1[17].size = (gfloat) matt * 0.20;
+ ref1[17].xp = 1.309 * dx + xh;
+ ref1[17].yp = 1.309 * dy + yh;
+
+ ref1[18].size = (gfloat) matt * 0.038;
+ ref1[18].xp = -1.301 * dx + xh;
+ ref1[18].yp = -1.301 * dy + yh;
+}
+
+static void
+prepare (GeglOperation *operation)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ const Babl *format = babl_format ("R'G'B'A float");
+ LfParamsType *params = NULL;
+
+ if (o->user_data == NULL)
+ o->user_data = g_slice_new0 (LfParamsType);
+
+ params = (LfParamsType *) o->user_data;
+
+ init_params (params, o);
+
+ gegl_operation_set_format (operation, "input", format);
+ gegl_operation_set_format (operation, "output", format);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeglOperation *op = (void*) object;
+ GeglProperties *o = GEGL_PROPERTIES (op);
+
+ if (o->user_data)
+ {
+ g_slice_free (LfParamsType, o->user_data);
+ o->user_data = NULL;
+ }
+
+ G_OBJECT_CLASS (gegl_op_parent_class)->finalize (object);
+}
+
+static gboolean
+process (GeglOperation *operation,
+ void *in_buf,
+ void *out_buf,
+ glong n_pixels,
+ const GeglRectangle *roi,
+ gint level)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ LfParamsType *params = (LfParamsType *) o->user_data;
+ GeglRectangle *whole_region;
+
+ gint x, y, b, idx, i;
+ gfloat hyp;
+ gfloat procent;
+ gfloat *pixel;
+ gfloat *input = in_buf;
+ gfloat *output = out_buf;
+
+ whole_region = gegl_operation_source_get_bounding_box (operation, "input");
+
+ update_params (o->pos_x,
+ o->pos_y,
+ whole_region->width,
+ whole_region->height,
+ params);
+
+ pixel = g_new (gfloat, 3);
+
+ for (y = 0; y < roi->height; y++)
+ {
+ for (x = 0; x < roi->width; x++)
+ {
+ idx = (x + y * roi->width) * 4;
+
+ for (b = 0; b < 3; b++)
+ pixel[b] = input[idx + b];
+
+ hyp = hypot (x + roi->x - params->center_x,
+ y + roi->y - params->center_y);
+
+ /* center color */
+ procent = params->color_size - hyp;
+ procent /= params->color_size;
+ if (procent > 0.0)
+ {
+ procent *= procent;
+ fixpix (pixel, procent, params->color);
+ }
+
+ /* glow color */
+ procent = params->glow_size - hyp;
+ procent /= params->glow_size;
+ if (procent > 0.0)
+ {
+ procent *= procent;
+ fixpix (pixel, procent, params->glow);
+ }
+
+ /* inner color */
+ procent = params->inner_size - hyp;
+ procent /= params->inner_size;
+ if (procent > 0.0)
+ {
+ procent *= procent;
+ fixpix (pixel, procent, params->inner);
+ }
+
+ /* outer color */
+ procent = params->outer_size - hyp;
+ procent /= params->outer_size;
+ if (procent > 0.0)
+ fixpix (pixel, procent, params->outer);
+
+ /* halo color */
+ procent = hyp - params->halo_size;
+ procent /= (params->halo_size * 0.07);
+ procent = fabs (procent);
+ if (procent < 1.0)
+ fixpix (pixel, 1.0 - procent, params->halo);
+
+ /* generate reflections */
+
+ for (i = 0; i < NUMREF; i++)
+ {
+ Reflect r = params->ref[i];
+ gdouble hyp = hypot (x + roi->x - r.xp,
+ y + roi->y - r.yp);
+ switch (r.type)
+ {
+ case 1:
+ procent = r.size - hyp;
+ procent /= r.size;
+ if (procent > 0.0)
+ {
+ procent *= procent;
+ fixpix (pixel, procent, (gdouble *) &r.ccol);
+ }
+ break;
+ case 2:
+ procent = r.size - hyp;
+ procent /= (r.size * 0.15);
+
+ if (procent > 0.0)
+ {
+ if (procent > 1.0)
+ procent = 1.0;
+
+ fixpix (pixel, procent, (gdouble *) &r.ccol);
+ }
+ break;
+ case 3:
+ procent = r.size - hyp;
+ procent /= (r.size * 0.12);
+
+ if (procent > 0.0)
+ {
+ if (procent > 1.0)
+ procent = 1.0 - (procent * 0.12);
+
+ fixpix (pixel, procent, (gdouble *) &r.ccol);
+ }
+ break;
+ case 4:
+ procent = hyp - r.size;
+ procent /= (r.size * 0.04);
+ procent = fabs (procent);
+
+ if (procent < 1.0)
+ fixpix (pixel, 1.0 - procent, (gdouble *) &r.ccol);
+ break;
+ }
+ }
+
+ /* write result to output */
+
+ for (b = 0; b < 3; b++)
+ output[idx + b] = pixel[b];
+
+ output[idx + 3] = input[idx + 3];
+ }
+ }
+
+ g_free (pixel);
+
+ return TRUE;
+}
+
+static void
+gegl_op_class_init (GeglOpClass *klass)
+{
+ GObjectClass *object_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointFilterClass *filter_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ operation_class = GEGL_OPERATION_CLASS (klass);
+ filter_class = GEGL_OPERATION_POINT_FILTER_CLASS (klass);
+
+ object_class->finalize = finalize;
+
+ operation_class->prepare = prepare;
+ operation_class->opencl_support = FALSE;
+
+ filter_class->process = process;
+
+ gegl_operation_class_set_keys (operation_class,
+ "name", "gegl:lens-flare",
+ "title", _("Lens Flare"),
+ "categories", "light",
+ "license", "GPL3+",
+ "description", _("Adds a lens flare effect."),
+ NULL);
+}
+
+#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7e6fa1e..87286d3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -55,6 +55,7 @@ operations/common/invert-gamma.c
operations/common/invert-linear.c
operations/common/layer.c
operations/common/lens-distortion.c
+operations/common/lens-flare.c
operations/common/levels.c
operations/common/linear-gradient.c
operations/common/load.c
diff --git a/tests/compositions/Makefile.am b/tests/compositions/Makefile.am
index 71d746d..e75ae54 100644
--- a/tests/compositions/Makefile.am
+++ b/tests/compositions/Makefile.am
@@ -34,6 +34,7 @@ TESTS = \
hdr-color.xml \
illusion.xml \
image-compare.xml \
+ lens-flare.xml \
mantiuk06.xml \
noise-cell.xml \
noise-hurl.xml \
diff --git a/tests/compositions/lens-flare.xml b/tests/compositions/lens-flare.xml
new file mode 100644
index 0000000..c43a3b8
--- /dev/null
+++ b/tests/compositions/lens-flare.xml
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<gegl>
+ <node operation='gegl:lens-flare'>
+ <params>
+ <param name='pos-x'>0.2</param>
+ <param name='pos-y'>0.2</param>
+ </params>
+ </node>
+ <node operation='gegl:load'>
+ <params>
+ <param name='path'>data/boats.png</param>
+ </params>
+ </node>
+</gegl>
+
diff --git a/tests/compositions/reference/lens-flare.png b/tests/compositions/reference/lens-flare.png
new file mode 100644
index 0000000..ede5a9d
Binary files /dev/null and b/tests/compositions/reference/lens-flare.png differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]