[gegl] newsprint: add per colorant pattern parameter
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] newsprint: add per colorant pattern parameter
- Date: Wed, 17 Jul 2019 15:10:31 +0000 (UTC)
commit de3f48eda0a6ad2f8208a9d4593d1cc48cfa98b5
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Jul 17 16:23:14 2019 +0200
newsprint: add per colorant pattern parameter
operations/common/newsprint.c | 237 +++++++++++++++++++++++++++---------------
1 file changed, 152 insertions(+), 85 deletions(-)
---
diff --git a/operations/common/newsprint.c b/operations/common/newsprint.c
index 32d9fdb64..8a5bdf692 100644
--- a/operations/common/newsprint.c
+++ b/operations/common/newsprint.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
- * Copyright 2017 Øyvind Kolås <pippin gimp org>
+ * Copyright 2017,2019 Øyvind Kolås <pippin gimp org>
*/
#include "config.h"
@@ -40,50 +40,58 @@ property_enum (color_model, _("Color Model"),
GeglNewsprintColorModel, gegl_newsprint_color_model, GEGL_NEWSPRINT_COLOR_MODEL_BLACK_ON_WHITE)
description (_("How many inks to use just black, rg, rgb (additive), or cmyk"))
-property_enum (pattern, _("Pattern"),
- GeglNewsprintPattern, gegl_newsprint_pattern, GEGL_NEWSPRINT_PATTERN_LINE)
- description (_("Halftoning/dot pattern to use"))
-
property_double (period, _("Period"), 12.0)
value_range (0.0, 200.0)
description (_("The number of pixels across one repetition of a base pattern at base
resolution."))
-property_double (turbulence, _("Turbulence"), 0.0)
- value_range (0.0, 1.0) // rename to wave-pinch or period-pinch?
- description (_("Color saturation dependent compression of period"))
+property_enum (pattern2, _("Red and cyan pattern"),
+ GeglNewsprintPattern, gegl_newsprint_pattern, GEGL_NEWSPRINT_PATTERN_LINE)
+ description (_("Halftoning/dot pattern to use"))
+ ui_meta ("visible", "color-model {rgb, cmyk}")
+ ui_meta ("label", "[color-model {rgb} : rgb-label,"
+ " color-model {cmyk} : cmyk-label]")
+ ui_meta ("rgb-label", _("Red pattern"))
+ ui_meta ("cmyk-label", _("Cyan pattern"))
-property_double (blocksize, _("Blocksize"), -1.0)
- value_range (-1.0, 64.0)
- description (_("Number of periods per tile, this tiling avoids high frequency anomaly that
angle boost causes"))
-
-property_double (angleboost, _("Angle Boost"), 0.0)
- value_range (0.0, 4.0)
- description (_("Multiplication factor for desired rotation of the local space for texture,
the way this is computed makes it weak for desaturated colors and possibly stronger where there is color."))
-
-property_double (twist, _("Black and green angle"), 75.0)
+property_double (twist2, _("Red and cyan angle"), 15.0)
value_range (-180.0, 180.0)
ui_meta ("unit", "degree")
ui_meta ("direction", "ccw")
- description (_("Angle offset for patterns"))
- ui_meta ("label", "[color-model {white-on-black,"
- " black-on-white} : bw-label,"
- " color-model {rgb} : rgb-label,"
- " color-model {cmyk} : cmyk-label]")
- ui_meta ("bw-label", _("Angle"))
- ui_meta ("rgb-label", _("Green angle"))
- ui_meta ("cmyk-label", _("Black angle"))
+ ui_meta ("visible", "color-model {rgb, cmyk}")
+ ui_meta ("label", "[color-model {rgb} : rgb-label,"
+ " color-model {cmyk} : cmyk-label]")
+ ui_meta ("rgb-label", _("Red angle"))
+ ui_meta ("cmyk-label", _("Cyan angle"))
-property_double (twist2, _("Red and cyan angle"), 15.0)
+property_enum (pattern3, _("Green and magenta pattern"),
+ GeglNewsprintPattern, gegl_newsprint_pattern, GEGL_NEWSPRINT_PATTERN_LINE)
+ description (_("Halftoning/dot pattern to use"))
+ ui_meta ("visible", "color-model {rgb, cmyk}")
+ ui_meta ("label", "[color-model {rgb} : rgb-label,"
+ " color-model {cmyk} : cmyk-label]")
+ ui_meta ("rgb-label", _("Green pattern"))
+ ui_meta ("cmyk-label", _("Magenta pattern"))
+
+property_double (twist3, _("Green and magenta angle"), 45.0)
value_range (-180.0, 180.0)
ui_meta ("unit", "degree")
ui_meta ("direction", "ccw")
ui_meta ("visible", "color-model {rgb, cmyk}")
ui_meta ("label", "[color-model {rgb} : rgb-label,"
" color-model {cmyk} : cmyk-label]")
- ui_meta ("rgb-label", _("Red angle"))
- ui_meta ("cmyk-label", _("Cyan angle"))
+ ui_meta ("rgb-label", _("Green angle"))
+ ui_meta ("cmyk-label", _("Magenta angle"))
-property_double (twist3, _("Blue and magenta angle"), 45.0)
+property_enum (pattern4, _("Blue and Yellow pattern"),
+ GeglNewsprintPattern, gegl_newsprint_pattern, GEGL_NEWSPRINT_PATTERN_LINE)
+ description (_("Halftoning/dot pattern to use"))
+ ui_meta ("visible", "color-model {rgb, cmyk}")
+ ui_meta ("label", "[color-model {rgb} : rgb-label,"
+ " color-model {cmyk} : cmyk-label]")
+ ui_meta ("rgb-label", _("Blue pattern"))
+ ui_meta ("cmyk-label", _("Yellow pattern"))
+
+property_double (twist4, _("Blue and Yellow angle"), 0.0)
value_range (-180.0, 180.0)
ui_meta ("unit", "degree")
ui_meta ("direction", "ccw")
@@ -91,13 +99,47 @@ property_double (twist3, _("Blue and magenta angle"), 45.0)
ui_meta ("label", "[color-model {rgb} : rgb-label,"
" color-model {cmyk} : cmyk-label]")
ui_meta ("rgb-label", _("Blue angle"))
- ui_meta ("cmyk-label", _("Magenta angle"))
+ ui_meta ("cmyk-label", _("Yellow angle"))
-property_double (twist4, _("Yellow angle"), 0.0)
+property_enum (pattern, _("Black pattern"),
+ GeglNewsprintPattern, gegl_newsprint_pattern, GEGL_NEWSPRINT_PATTERN_LINE)
+ description (_("Halftoning/dot pattern to use"))
+ ui_meta ("visible", "color-model {white-on-black, black-on-white, cmyk}")
+ ui_meta ("label", "[color-model {white-on-black,"
+ " black-on-white} : bw-label,"
+ " color-model {cmyk} : cmyk-label]")
+ ui_meta ("bw-label", _("Pattern"))
+ ui_meta ("cmyk-label", _("Black pattern"))
+
+
+property_double (twist, _("Black angle"), 75.0)
value_range (-180.0, 180.0)
ui_meta ("unit", "degree")
ui_meta ("direction", "ccw")
- ui_meta ("visible", "color-model {cmyk}")
+ description (_("Angle offset for patterns"))
+ ui_meta ("visible", "color-model {white-on-black, black-on-white, cmyk}")
+ ui_meta ("label", "[color-model {white-on-black,"
+ " black-on-white} : bw-label,"
+ " color-model {cmyk} : cmyk-label]")
+ ui_meta ("bw-label", _("Angle"))
+ ui_meta ("cmyk-label", _("Black angle"))
+
+property_int (aa_samples, _("Anti-alias oversampling factor"), 16)
+ value_range (1, 128)
+ description (_("Number of samples that are averaged for antialiasing the result."))
+
+property_double (turbulence, _("Turbulence"), 0.0)
+ value_range (0.0, 1.0) // rename to wave-pinch or period-pinch?
+ description (_("Color saturation dependent compression of period"))
+
+property_double (blocksize, _("Blocksize"), -1.0)
+ value_range (-1.0, 64.0)
+ description (_("Number of periods per tile, this tiling avoids high frequency anomaly that
angle boost causes"))
+
+property_double (angleboost, _("Angle Boost"), 0.0)
+ value_range (0.0, 4.0)
+ description (_("Multiplication factor for desired rotation of the local space for texture,
the way this is computed makes it weak for desaturated colors and possibly stronger where there is color."))
+
#else
@@ -109,12 +151,29 @@ property_double (twist4, _("Yellow angle"), 0.0)
#include <math.h>
-static inline float dmodf(float x, float y)
+
+static inline float int_fabsf(float x)
+{
+ union {float f; uint32_t i;} u = {x};
+ u.i &= 0x7fffffff;
+ return u.f;
+}
+#define fabsf int_fabsf
+
+static inline int int_floorf (float x)
+{
+ int i = (int)x; /* truncate */
+ return i - ( i > x ); /* convert trunc to floor */
+}
+
+#define floorf int_floorf
+
+static inline float int_fmodf(float x, float y)
{
return x - y * floorf(x/y);
}
-#define fmodf dmodf
+#define fmodf int_fmodf
/* for details and more liberal licensing of the following function, see
https://pippin.gimp.org/spachrotyzer/ */
@@ -131,46 +190,46 @@ float spachrotyze (
float turbulence,
float blocksize,
float angleboost,
- float twist)
+ float twist,
+ int max_aa_samples)
{
- int max_aa_samples = 16;
- float acc = 0.0;
+ float acc = 0.0f;
- float angle = 3.1415 / 2- ((hue * angleboost) + twist);
+ float angle = 3.1415f / 2.f - ((hue * angleboost) + twist);
- float width = (period * (1.0 - turbulence) +
+ float width = (period * (1.0f - turbulence) +
(period * offset) * turbulence);
float vec0 = cosf (angle);
float vec1 = sinf (angle);
- float xi = 0.5;
- float yi = 0.2;
+ float xi = 0.5f;
+ float yi = 0.2f;
int count = 0;
int in = 0;
- float old_acc = 0.0;
+ float old_acc = 0.0f;
- x += period * 2;
- y += period * 2;
+ x += period * 2.f;
+ y += period * 2.f;
for (int i = 0; i < max_aa_samples ; i++)
{
- xi = fmodf (xi + 0.618033988749854, 1.0);
- yi = fmodf (yi + (0.618033988749854/1.61235), 1.0);
+ xi = fmodf (xi + 0.618033988749854f, 1.0f);
+ yi = fmodf (yi + (0.618033988749854f/1.61235f), 1.0f);
old_acc = acc;
{
- float u = fmodf (x + xi - 0.5 * width, blocksize * width);
- float v = fmodf (y + yi - 0.5 * width, blocksize * width);
+ float u = fmodf (x + xi - 0.5f * width, blocksize * width);
+ float v = fmodf (y + yi - 0.5f * width, blocksize * width);
float w = vec0 * u + vec1 * v;
float q = vec1 * u - vec0 * v;
float wperiod = fmodf (w, width);
- float wphase = (wperiod / width) * 2.0 - 1.0;
+ float wphase = (wperiod / width) * 2.0f - 1.0f;
float qperiod = fmodf (q, width);
- float qphase = (qperiod / width) * 2.0 - 1.0;
+ float qphase = (qperiod / width) * 2.0f - 1.0f;
if (pattern == 0) /* line */
{
@@ -180,12 +239,12 @@ float spachrotyze (
else if (pattern == 1) /* dot */
{
if (qphase * qphase + wphase * wphase <
- part_white * part_white * 2.0)
+ part_white * part_white * 2.0f)
in ++;
}
else if (pattern == 2) /* diamond */
{
- if ((fabsf(wphase) + fabsf(qphase))/2.0 < part_white )
+ if ((fabsf (wphase) + fabsf (qphase))/2.0f < part_white )
in++;
}
else if (pattern == 3) /* dot-to-diamond-to-dot */
@@ -194,36 +253,35 @@ float spachrotyze (
float ay = fabsf (qphase ) ;
float v = 0.0;
- if (ax + ay > 1.0)
+ if (ax + ay > 1.0f)
{
- ay = 1.0 - ay;
- ax = 1.0 - ax;
- v = 2.0 - sqrtf (ay * ay + ax * ax);
+ ay = 1.0f - ay;
+ ax = 1.0f - ax;
+ v = 2.0f - hypotf (ax, ay);
}
else
{
- v = sqrtf (ay * ay + ax * ax);
+ v = hypotf (ax, ay);
}
- v/=2.0;
+ v/=2.0f;
if (v < part_white)
in++;
}
else if (pattern == 4) /* cross */
{
- float part_white2 = powf (part_white, 2.0);
+ float part_white2 = part_white * part_white;
if (fabsf (wphase) < part_white2 ||
fabsf (qphase) < part_white2)
in++;
}
count ++;
- acc = in * 1.0/ count;
+ acc = in * 1.0f / count;
if (i > 3 &&
- fabs (acc - old_acc) < 0.23)
+ fabsf (acc - old_acc) < 0.23f)
break;
old_acc = acc;
}
-
}
return acc;
}
@@ -289,8 +347,8 @@ process (GeglOperation *operation,
while (n_pixels--)
{
float luminance = in_pixel[1];
- float chroma = fabs(in_pixel[0]-in_pixel[1]);
- float angle = fabs(in_pixel[2]-in_pixel[1]);
+ float chroma = fabsf (in_pixel[0]-in_pixel[1]);
+ float angle = fabsf (in_pixel[2]-in_pixel[1]);
float gray = spachrotyze (x, y,
luminance, chroma, angle,
@@ -299,7 +357,8 @@ process (GeglOperation *operation,
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist));
+ degrees_to_radians (o->twist),
+ o->aa_samples);
for (int c = 0; c < 3; c++)
out_pixel[c] = gray;
@@ -316,8 +375,8 @@ process (GeglOperation *operation,
while (n_pixels--)
{
float luminance = in_pixel[1];
- float chroma = fabs(in_pixel[0]-in_pixel[1]);
- float angle = fabs(in_pixel[2]-in_pixel[1]);
+ float chroma = fabsf (in_pixel[0]-in_pixel[1]);
+ float angle = fabsf (in_pixel[2]-in_pixel[1]);
float gray = 1.0-spachrotyze (x, y,
1.0-luminance, chroma, angle,
@@ -326,7 +385,8 @@ process (GeglOperation *operation,
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist));
+ degrees_to_radians (o->twist),
+ o->aa_samples);
for (int c = 0; c < 3; c++)
out_pixel[c] = gray;
@@ -342,35 +402,38 @@ process (GeglOperation *operation,
case GEGL_NEWSPRINT_COLOR_MODEL_RGB:
while (n_pixels--)
{
- float pinch = fabs(in_pixel[0]-in_pixel[1]);
- float angle = fabs(in_pixel[2]-in_pixel[1]);
+ float pinch = fabsf (in_pixel[0]-in_pixel[1]);
+ float angle = fabsf (in_pixel[2]-in_pixel[1]);
out_pixel[0] = spachrotyze (x, y,
in_pixel[0], pinch, angle,
- o->pattern,
+ o->pattern2,
o->period / (1.0*(1<<level)),
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist2));
+ degrees_to_radians (o->twist2),
+ o->aa_samples);
out_pixel[1] = spachrotyze (x, y,
in_pixel[1], pinch, angle,
- o->pattern,
+ o->pattern3,
o->period / (1.0*(1<<level)),
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist));
+ degrees_to_radians (o->twist3),
+ o->aa_samples);
out_pixel[2] = spachrotyze (x, y,
in_pixel[2], pinch, angle,
- o->pattern,
+ o->pattern4,
o->period / (1.0*(1<<level)),
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist3));
+ degrees_to_radians (o->twist4),
+ o->aa_samples);
out_pixel[3] = 1.0;
out_pixel += 4;
@@ -383,8 +446,8 @@ process (GeglOperation *operation,
case GEGL_NEWSPRINT_COLOR_MODEL_CMYK:
while (n_pixels--)
{
- float pinch = fabs(in_pixel[0]-in_pixel[1]);
- float angle = fabs(in_pixel[2]-in_pixel[1]);
+ float pinch = fabsf (in_pixel[0]-in_pixel[1]);
+ float angle = fabsf (in_pixel[2]-in_pixel[1]);
float c = 1.0 - in_pixel[0];
float m = 1.0 - in_pixel[1];
float iy = 1.0 - in_pixel[2];
@@ -409,30 +472,33 @@ process (GeglOperation *operation,
c = spachrotyze (x, y,
c, pinch, angle,
- o->pattern,
+ o->pattern2,
o->period / (1.0*(1<<level)),
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist2));
+ degrees_to_radians (o->twist2),
+ o->aa_samples);
m = spachrotyze (x, y,
m, pinch, angle,
- o->pattern,
+ o->pattern3,
o->period / (1.0*(1<<level)),
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist3));
+ degrees_to_radians (o->twist3),
+ o->aa_samples);
iy = spachrotyze (x, y,
iy, pinch, angle,
- o->pattern,
+ o->pattern4,
o->period / (1.0*(1<<level)),
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist4));
+ degrees_to_radians (o->twist4),
+ o->aa_samples);
k = spachrotyze (x, y,
k, pinch, angle,
@@ -441,7 +507,8 @@ process (GeglOperation *operation,
o->turbulence,
blocksize,
o->angleboost,
- degrees_to_radians (o->twist));
+ degrees_to_radians (o->twist),
+ o->aa_samples);
if (k < 1.0) {
c = c * (1.0 - k) + k;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]