[gimp/metadata-browser] app: modified gegl blending modes to take mask and opacity inputs
- From: Roman Joost <romanofski src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/metadata-browser] app: modified gegl blending modes to take mask and opacity inputs
- Date: Thu, 13 Sep 2012 00:16:42 +0000 (UTC)
commit 7e4eb4a14f4938822b46094a2821dc1775a12c4d
Author: Ville Sokk <ville sokk gmail com>
Date: Fri May 18 23:35:00 2012 +0300
app: modified gegl blending modes to take mask and opacity inputs
app/core/gimplayer.c | 2 +-
app/gegl/gimp-gegl-nodes.c | 15 ---
app/operations/gimpoperationadditionmode.c | 110 ++++++++++++++++++-----
app/operations/gimpoperationantierasemode.c | 77 +++++++++++++----
app/operations/gimpoperationbehindmode.c | 115 +++++++++++++++++++-----
app/operations/gimpoperationburnmode.c | 55 ++++++++---
app/operations/gimpoperationcolorerasemode.c | 8 +-
app/operations/gimpoperationcolormode.c | 65 +++++++++----
app/operations/gimpoperationdarkenonlymode.c | 54 ++++++++---
app/operations/gimpoperationdifferencemode.c | 108 +++++++++++++++++-----
app/operations/gimpoperationdissolvemode.c | 108 ++++++++++++++++-------
app/operations/gimpoperationdividemode.c | 55 ++++++++---
app/operations/gimpoperationdodgemode.c | 55 ++++++++---
app/operations/gimpoperationerasemode.c | 34 +++++--
app/operations/gimpoperationgrainextractmode.c | 55 ++++++++---
app/operations/gimpoperationgrainmergemode.c | 55 ++++++++---
app/operations/gimpoperationhardlightmode.c | 67 ++++++++++-----
app/operations/gimpoperationhuemode.c | 79 +++++++++++------
app/operations/gimpoperationlightenonlymode.c | 54 ++++++++---
app/operations/gimpoperationmultiplymode.c | 106 +++++++++++++++++-----
app/operations/gimpoperationnormalmode.c | 110 +++++++++++++++++-----
app/operations/gimpoperationoverlaymode.c | 106 +++++++++++++++++-----
app/operations/gimpoperationpointlayermode.c | 43 ++++++++--
app/operations/gimpoperationpointlayermode.h | 5 +-
app/operations/gimpoperationreplacemode.c | 94 ++------------------
app/operations/gimpoperationreplacemode.h | 7 +-
app/operations/gimpoperationsaturationmode.c | 63 +++++++++----
app/operations/gimpoperationscreenmode.c | 103 +++++++++++++++++-----
app/operations/gimpoperationsoftlightmode.c | 58 +++++++++----
app/operations/gimpoperationsubtractmode.c | 56 +++++++++---
app/operations/gimpoperationvaluemode.c | 63 +++++++++----
31 files changed, 1403 insertions(+), 582 deletions(-)
---
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index a40d194..a98c46b 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -1942,7 +1942,7 @@ gimp_layer_set_opacity (GimpLayer *layer,
if (gimp_item_peek_node (GIMP_ITEM (layer)))
{
gegl_node_set (gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer)),
- "value", layer->opacity,
+ "opacity", layer->opacity,
NULL);
}
diff --git a/app/gegl/gimp-gegl-nodes.c b/app/gegl/gimp-gegl-nodes.c
index 21035f3..11e3d11 100644
--- a/app/gegl/gimp-gegl-nodes.c
+++ b/app/gegl/gimp-gegl-nodes.c
@@ -318,21 +318,6 @@ gimp_gegl_node_set_layer_mode (GeglNode *node,
switch (mode)
{
- case GIMP_COLOR_ERASE_MODE:
- case GIMP_ANTI_ERASE_MODE:
- gegl_node_set (node,
- "operation", "gimp:point-layer-mode",
- "blend-mode", mode,
- "premultiplied", premultiplied,
- NULL);
- return;
-
- default:
- break;
- }
-
- switch (mode)
- {
case GIMP_NORMAL_MODE: operation = "gimp:normal-mode"; break;
case GIMP_DISSOLVE_MODE: operation = "gimp:dissolve-mode"; break;
case GIMP_BEHIND_MODE: operation = "gimp:behind-mode"; break;
diff --git a/app/operations/gimpoperationadditionmode.c b/app/operations/gimpoperationadditionmode.c
index ce606e5..dda4585 100644
--- a/app/operations/gimpoperationadditionmode.c
+++ b/app/operations/gimpoperationadditionmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_addition_mode_prepare (GeglOperation *opera
static gboolean gimp_operation_addition_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationAdditionMode, gimp_operation_addition_mode,
static void
gimp_operation_addition_mode_class_init (GimpOperationAdditionModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:addition-mode",
@@ -73,6 +74,7 @@ gimp_operation_addition_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,95 @@ static gboolean
gimp_operation_addition_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
-
- while (samples--)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+
+ if (mask)
{
- gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
-
- for (b = RED; b < ALPHA; b++)
+ while (samples--)
{
- gfloat comp = in[b] + layer[b];
- comp = CLAMP (comp, 0, 1);
-
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] + layer[b];
+ comp = CLAMP (comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] + layer[b];
+ comp = CLAMP (comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ out[ALPHA] = in[ALPHA];
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
-
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- layer += 4;
- out += 4;
}
return TRUE;
diff --git a/app/operations/gimpoperationantierasemode.c b/app/operations/gimpoperationantierasemode.c
index 4116ef5..3553613 100644
--- a/app/operations/gimpoperationantierasemode.c
+++ b/app/operations/gimpoperationantierasemode.c
@@ -3,6 +3,7 @@
*
* gimpoperationantierasemode.c
* Copyright (C) 2008 Michael Natterer <mitch gimp org>
+ * 2012 Ville Sokk <ville sokk gmail com>
*
* 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
@@ -28,9 +29,11 @@
#include "gimpoperationantierasemode.h"
+static void gimp_operation_anti_erase_mode_prepare (GeglOperation *operation);
static gboolean gimp_operation_anti_erase_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -45,17 +48,18 @@ static void
gimp_operation_anti_erase_mode_class_init (GimpOperationAntiEraseModeClass *klass)
{
GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:anti-erase-mode",
"description", "GIMP anti erase mode operation",
NULL);
- point_class->process = gimp_operation_anti_erase_mode_process;
+ operation_class->prepare = gimp_operation_anti_erase_mode_prepare;
+ point_class->process = gimp_operation_anti_erase_mode_process;
}
static void
@@ -63,29 +67,70 @@ gimp_operation_anti_erase_mode_init (GimpOperationAntiEraseMode *self)
{
}
+static void
+gimp_operation_anti_erase_mode_prepare (GeglOperation *operation)
+{
+ const Babl *format = babl_format ("R'G'B'A float");
+
+ gegl_operation_set_format (operation, "input", format);
+ gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
+ gegl_operation_set_format (operation, "output", format);
+}
+
static gboolean
gimp_operation_anti_erase_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
-
- while (samples--)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+
+ if (mask)
{
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- layer += 4;
- out += 4;
+ while (samples--)
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+
+ out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * opacity * (*mask);
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+
+ out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * opacity;
+
+ in += 4;
+ layer += 4;
+ out += 4;
+ }
}
return TRUE;
diff --git a/app/operations/gimpoperationbehindmode.c b/app/operations/gimpoperationbehindmode.c
index 9412579..857cc30 100644
--- a/app/operations/gimpoperationbehindmode.c
+++ b/app/operations/gimpoperationbehindmode.c
@@ -32,6 +32,7 @@
static gboolean gimp_operation_behind_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,10 +47,10 @@ static void
gimp_operation_behind_mode_class_init (GimpOperationBehindModeClass *klass)
{
GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:behind-mode",
@@ -68,47 +69,113 @@ static gboolean
gimp_operation_behind_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
if (point->premultiplied)
{
- while (samples--)
+ if (mask)
{
- gint b;
-
- for (b = RED; b <= ALPHA; b++)
+ while (samples--)
{
- out[b] = in[b] + layer[b] * (1 - in[ALPHA]);
+ gint b;
+ gfloat value = opacity * (*mask);
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b] + layer[b] * value * (1 - in[ALPHA]);
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
}
+ }
+ else
+ {
+ while (samples--)
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b] + layer[b] * opacity * (1 - in[ALPHA]);
+ }
- in += 4;
- layer += 4;
- out += 4;
+ in += 4;
+ layer += 4;
+ out += 4;
+ }
}
}
else
{
- while (samples--)
+ if (mask)
{
- gint b;
-
- out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA];
- for (b = RED; b < ALPHA; b++)
+ while (samples--)
{
- out[b] = (in[b] * in[ALPHA] + layer[b] * layer[ALPHA] * (1 - in[ALPHA])) / out[ALPHA];
+ gint b;
+ gfloat value = opacity * (*mask);
+
+ out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * value;
+ if (out[ALPHA])
+ {
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = (in[b] * in[ALPHA] + layer[b] * value * layer[ALPHA] * value * (1 - in[ALPHA])) / out[ALPHA];
+ }
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gint b;
+
+ out[ALPHA] = in[ALPHA] + (1 - in[ALPHA]) * layer[ALPHA] * opacity;
+ if (out[ALPHA])
+ {
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = (in[b] * in[ALPHA] + layer[b] * opacity * layer[ALPHA] * opacity * (1 - in[ALPHA])) / out[ALPHA];
+ }
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
-
- in += 4;
- layer += 4;
- out += 4;
}
}
diff --git a/app/operations/gimpoperationburnmode.c b/app/operations/gimpoperationburnmode.c
index 3c8147f..f2ea7fb 100644
--- a/app/operations/gimpoperationburnmode.c
+++ b/app/operations/gimpoperationburnmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_burn_mode_prepare (GeglOperation *operation
static gboolean gimp_operation_burn_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationBurnMode, gimp_operation_burn_mode,
static void
gimp_operation_burn_mode_class_init (GimpOperationBurnModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:burn-mode",
@@ -73,6 +74,7 @@ gimp_operation_burn_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,58 @@ static gboolean
gimp_operation_burn_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp = (1 - in[b]) / layer[b];
- comp = CLAMP (1 - comp, 0, 1);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = (1 - in[b]) / layer[b];
+ comp = CLAMP (1 - comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
- out[ALPHA] = in[ALPHA];
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationcolorerasemode.c b/app/operations/gimpoperationcolorerasemode.c
index 4c8cf4c..cce0ce9 100644
--- a/app/operations/gimpoperationcolorerasemode.c
+++ b/app/operations/gimpoperationcolorerasemode.c
@@ -31,6 +31,7 @@
static gboolean gimp_operation_color_erase_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -44,11 +45,11 @@ G_DEFINE_TYPE (GimpOperationColorEraseMode, gimp_operation_color_erase_mode,
static void
gimp_operation_color_erase_mode_class_init (GimpOperationColorEraseModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:color-erase-mode",
@@ -67,6 +68,7 @@ static gboolean
gimp_operation_color_erase_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
diff --git a/app/operations/gimpoperationcolormode.c b/app/operations/gimpoperationcolormode.c
index 762753f..caa19f6 100644
--- a/app/operations/gimpoperationcolormode.c
+++ b/app/operations/gimpoperationcolormode.c
@@ -37,6 +37,7 @@ static void gimp_operation_color_mode_prepare (GeglOperation *operatio
static gboolean gimp_operation_color_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -50,11 +51,11 @@ G_DEFINE_TYPE (GimpOperationColorMode, gimp_operation_color_mode,
static void
gimp_operation_color_mode_class_init (GimpOperationColorModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:color-mode",
@@ -77,6 +78,7 @@ gimp_operation_color_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -84,14 +86,18 @@ static gboolean
gimp_operation_color_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
@@ -99,28 +105,47 @@ gimp_operation_color_mode_process (GeglOperation *operation,
GimpHSL layer_hsl, out_hsl;
GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
GimpRGB out_rgb = {in[0], in[1], in[2]};
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- gimp_rgb_to_hsl (&layer_rgb, &layer_hsl);
- gimp_rgb_to_hsl (&out_rgb, &out_hsl);
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
- out_hsl.h = layer_hsl.h;
- out_hsl.s = layer_hsl.s;
- gimp_hsl_to_rgb (&out_hsl, &out_rgb);
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- out[0] = out_rgb.r;
- out[1] = out_rgb.g;
- out[2] = out_rgb.b;
- out[3] = in[3];
+ if (comp_alpha && new_alpha)
+ {
+ ratio = comp_alpha / new_alpha;
- for (b = RED; b < ALPHA; b++)
- out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ gimp_rgb_to_hsl (&layer_rgb, &layer_hsl);
+ gimp_rgb_to_hsl (&out_rgb, &out_hsl);
+
+ out_hsl.h = layer_hsl.h;
+ out_hsl.s = layer_hsl.s;
+ gimp_hsl_to_rgb (&out_hsl, &out_rgb);
+
+ out[0] = out_rgb.r;
+ out[1] = out_rgb.g;
+ out[2] = out_rgb.b;
+ out[3] = in[3];
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationdarkenonlymode.c b/app/operations/gimpoperationdarkenonlymode.c
index 5f82bdf..b4a6e74 100644
--- a/app/operations/gimpoperationdarkenonlymode.c
+++ b/app/operations/gimpoperationdarkenonlymode.c
@@ -33,6 +33,7 @@ static void gimp_operation_darken_only_mode_prepare (GeglOperation *op
static gboolean gimp_operation_darken_only_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationDarkenOnlyMode, gimp_operation_darken_only_mode,
static void
gimp_operation_darken_only_mode_class_init (GimpOperationDarkenOnlyModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:darken-only-mode",
@@ -58,7 +59,6 @@ gimp_operation_darken_only_mode_class_init (GimpOperationDarkenOnlyModeClass *kl
NULL);
operation_class->prepare = gimp_operation_darken_only_mode_prepare;
-
point_class->process = gimp_operation_darken_only_mode_process;
}
@@ -74,6 +74,7 @@ gimp_operation_darken_only_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -81,34 +82,57 @@ static gboolean
gimp_operation_darken_only_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
+
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- for (b = RED; b < ALPHA; b++)
+ if (new_alpha && comp_alpha)
{
- gfloat comp = MIN (in[b], layer[b]);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = MIN (in[b], layer[b]);
- out[ALPHA] = in[ALPHA];
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationdifferencemode.c b/app/operations/gimpoperationdifferencemode.c
index 143188b..dcca241 100644
--- a/app/operations/gimpoperationdifferencemode.c
+++ b/app/operations/gimpoperationdifferencemode.c
@@ -33,6 +33,7 @@ static void gimp_operation_difference_mode_prepare (GeglOperation *ope
static gboolean gimp_operation_difference_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationDifferenceMode, gimp_operation_difference_mode,
static void
gimp_operation_difference_mode_class_init (GimpOperationDifferenceModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:difference-mode",
@@ -73,6 +74,7 @@ gimp_operation_difference_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,93 @@ static gboolean
gimp_operation_difference_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
-
- while (samples--)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+
+ if (mask)
{
- gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
-
- for (b = RED; b < ALPHA; b++)
+ while (samples--)
{
- gfloat comp = in[b] - layer[b];
- comp = (comp < 0) ? -comp : comp;
-
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] - layer[b];
+ comp = (comp < 0) ? -comp : comp;
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] - layer[b];
+ comp = (comp < 0) ? -comp : comp;
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
-
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- layer += 4;
- out += 4;
}
return TRUE;
diff --git a/app/operations/gimpoperationdissolvemode.c b/app/operations/gimpoperationdissolvemode.c
index f3de692..c906416 100644
--- a/app/operations/gimpoperationdissolvemode.c
+++ b/app/operations/gimpoperationdissolvemode.c
@@ -36,6 +36,7 @@ static void gimp_operation_dissolve_mode_prepare (GeglOperation *opera
static gboolean gimp_operation_dissolve_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *result,
@@ -51,13 +52,13 @@ static gint32 random_table[RANDOM_TABLE_SIZE];
static void
gimp_operation_dissolve_mode_class_init (GimpOperationDissolveModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_composer_class;
- GRand *gr;
- gint i;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_composer_class;
+ GRand *gr;
+ gint i;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_composer_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_composer_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:dissolve-mode",
@@ -88,6 +89,7 @@ gimp_operation_dissolve_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -95,45 +97,89 @@ static gboolean
gimp_operation_dissolve_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *result,
gint level)
{
- gint x, y;
- gfloat *in = in_buf;
- gfloat *out = out_buf;
- gfloat *aux = aux_buf;
-
- for (y = result->y; y < result->y + result->height; y++)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *out = out_buf;
+ gfloat *aux = aux_buf;
+ gfloat *mask = aux2_buf;
+ gint x, y;
+
+ if (mask)
{
- GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
+ for (y = result->y; y < result->y + result->height; y++)
+ {
+ GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
- /* fast forward through the rows pseudo random sequence */
- for (x = 0; x < result->x; x++)
- g_rand_int (gr);
+ /* fast forward through the rows pseudo random sequence */
+ for (x = 0; x < result->x; x++)
+ g_rand_int (gr);
- for (x = result->x; x < result->x + result->width; x++)
- {
- if (g_rand_int_range (gr, 0, 255) >= aux[3] * 255)
+ for (x = result->x; x < result->x + result->width; x++)
{
- out[0] = in[0];
- out[1] = in[1];
- out[2] = in[2];
- out[3] = in[3];
+ gfloat value = opacity * (*mask);
+
+ if (g_rand_int_range (gr, 0, 255) >= aux[3] * value * 255)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ }
+ else
+ {
+ out[0] = aux[0];
+ out[1] = aux[1];
+ out[2] = aux[2];
+ out[3] = 1.0;
+ }
+
+ in += 4;
+ out += 4;
+ aux += 4;
+ mask += 1;
}
- else
+ g_rand_free (gr);
+ }
+ }
+ else
+ {
+ for (y = result->y; y < result->y + result->height; y++)
+ {
+ GRand *gr = g_rand_new_with_seed (random_table[y % RANDOM_TABLE_SIZE]);
+
+ /* fast forward through the rows pseudo random sequence */
+ for (x = 0; x < result->x; x++)
+ g_rand_int (gr);
+
+ for (x = result->x; x < result->x + result->width; x++)
{
- out[0] = aux[0];
- out[1] = aux[1];
- out[2] = aux[2];
- out[3] = 1.0;
+ if (g_rand_int_range (gr, 0, 255) >= aux[3] * opacity * 255)
+ {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ }
+ else
+ {
+ out[0] = aux[0];
+ out[1] = aux[1];
+ out[2] = aux[2];
+ out[3] = 1.0;
+ }
+ in += 4;
+ out += 4;
+ aux += 4;
}
- in += 4;
- out += 4;
- aux += 4;
+ g_rand_free (gr);
}
- g_rand_free (gr);
}
return TRUE;
diff --git a/app/operations/gimpoperationdividemode.c b/app/operations/gimpoperationdividemode.c
index 1d4a27a..7840821 100644
--- a/app/operations/gimpoperationdividemode.c
+++ b/app/operations/gimpoperationdividemode.c
@@ -33,6 +33,7 @@ static void gimp_operation_divide_mode_prepare (GeglOperation *operati
static gboolean gimp_operation_divide_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationDivideMode, gimp_operation_divide_mode,
static void
gimp_operation_divide_mode_class_init (GimpOperationDivideModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:divide-mode",
@@ -73,6 +74,7 @@ gimp_operation_divide_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,58 @@ static gboolean
gimp_operation_divide_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp = (256 / 255.0 * in[b]) / (1 / 255.0 + layer[b]);
- comp = MIN (comp, 1);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = (256 / 255.0 * in[b]) / (1 / 255.0 + layer[b]);
+ comp = MIN (comp, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
- out[ALPHA] = in[ALPHA];
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationdodgemode.c b/app/operations/gimpoperationdodgemode.c
index 8f28928..992532e 100644
--- a/app/operations/gimpoperationdodgemode.c
+++ b/app/operations/gimpoperationdodgemode.c
@@ -33,6 +33,7 @@ static void gimp_operation_dodge_mode_prepare (GeglOperation *operatio
static gboolean gimp_operation_dodge_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationDodgeMode, gimp_operation_dodge_mode,
static void
gimp_operation_dodge_mode_class_init (GimpOperationDodgeModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:dodge-mode",
@@ -73,6 +74,7 @@ gimp_operation_dodge_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,58 @@ static gboolean
gimp_operation_dodge_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp = in[b] / (1 - layer[b]);
- comp = MIN (comp, 1);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] / (1 - layer[b]);
+ comp = MIN (comp, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
- out[ALPHA] = in[ALPHA];
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationerasemode.c b/app/operations/gimpoperationerasemode.c
index 8ded88b..b027474 100644
--- a/app/operations/gimpoperationerasemode.c
+++ b/app/operations/gimpoperationerasemode.c
@@ -32,6 +32,7 @@
static gboolean gimp_operation_erase_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -45,11 +46,11 @@ G_DEFINE_TYPE (GimpOperationEraseMode, gimp_operation_erase_mode,
static void
gimp_operation_erase_mode_class_init (GimpOperationEraseModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:erase-mode",
@@ -68,23 +69,29 @@ static gboolean
gimp_operation_erase_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
if (point->premultiplied)
{
while (samples--)
{
gint b;
+ gfloat value = opacity;
+ if (mask)
+ value *= (*mask);
- out[ALPHA] = in[ALPHA] - in[ALPHA] * layer[ALPHA];
+ out[ALPHA] = in[ALPHA] - in[ALPHA] * layer[ALPHA] * value;
for (b = RED; b < ALPHA; b++)
{
out[b] = in[b] / in[ALPHA] * out[ALPHA];
@@ -93,6 +100,9 @@ gimp_operation_erase_mode_process (GeglOperation *operation,
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
}
else
@@ -100,16 +110,22 @@ gimp_operation_erase_mode_process (GeglOperation *operation,
while (samples--)
{
gint b;
+ gfloat value = opacity;
+ if (mask)
+ value *= (*mask);
for (b = RED; b < ALPHA; b++)
{
out[b] = in[b];
}
- out[ALPHA] = in[ALPHA] - in[ALPHA] * layer[ALPHA];;
+ out[ALPHA] = in[ALPHA] - in[ALPHA] * layer[ALPHA] * value;
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
}
diff --git a/app/operations/gimpoperationgrainextractmode.c b/app/operations/gimpoperationgrainextractmode.c
index 3acccae..c30a55f 100644
--- a/app/operations/gimpoperationgrainextractmode.c
+++ b/app/operations/gimpoperationgrainextractmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_grain_extract_mode_prepare (GeglOperation *
static gboolean gimp_operation_grain_extract_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationGrainExtractMode, gimp_operation_grain_extract_mode,
static void
gimp_operation_grain_extract_mode_class_init (GimpOperationGrainExtractModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:grain-extract-mode",
@@ -73,6 +74,7 @@ gimp_operation_grain_extract_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -81,35 +83,58 @@ static gboolean
gimp_operation_grain_extract_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp = in[b] - layer[b] + 0.5;
- comp = CLAMP (comp, 0, 1);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] - layer[b] + 0.5;
+ comp = CLAMP (comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
- out[ALPHA] = in[ALPHA];
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationgrainmergemode.c b/app/operations/gimpoperationgrainmergemode.c
index fe9903c..5c707ba 100644
--- a/app/operations/gimpoperationgrainmergemode.c
+++ b/app/operations/gimpoperationgrainmergemode.c
@@ -33,6 +33,7 @@ static void gimp_operation_grain_merge_mode_prepare (GeglOperation *op
static gboolean gimp_operation_grain_merge_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationGrainMergeMode, gimp_operation_grain_merge_mode,
static void
gimp_operation_grain_merge_mode_class_init (GimpOperationGrainMergeModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:grain-merge-mode",
@@ -73,6 +74,7 @@ gimp_operation_grain_merge_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -81,35 +83,58 @@ static gboolean
gimp_operation_grain_merge_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp = in[b] + layer[b] - 0.5;
- comp = CLAMP (comp, 0, 1);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] + layer[b] - 0.5;
+ comp = CLAMP (comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
- out[ALPHA] = in[ALPHA];
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationhardlightmode.c b/app/operations/gimpoperationhardlightmode.c
index 2706ea4..b682cb7 100644
--- a/app/operations/gimpoperationhardlightmode.c
+++ b/app/operations/gimpoperationhardlightmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_hardlight_mode_prepare (GeglOperation *oper
static gboolean gimp_operation_hardlight_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationHardlightMode, gimp_operation_hardlight_mode,
static void
gimp_operation_hardlight_mode_class_init (GimpOperationHardlightModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hardlight-mode",
@@ -73,6 +74,7 @@ gimp_operation_hardlight_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,45 +82,68 @@ static gboolean
gimp_operation_hardlight_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp;
+ ratio = comp_alpha / new_alpha;
- if (layer[b] > 0.5)
+ for (b = RED; b < ALPHA; b++)
{
- comp = (1 - in[b]) * (1 - (layer[b] - 0.5) * 2);
- comp = MIN (1 - comp, 1);
+ gfloat comp;
+
+ if (layer[b] > 0.5)
+ {
+ comp = (1 - in[b]) * (1 - (layer[b] - 0.5) * 2);
+ comp = MIN (1 - comp, 1);
+ }
+ else
+ {
+ comp = in[b] * (layer[b] * 2);
+ comp = MIN (comp, 1);
+ }
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
}
- else
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
{
- comp = in[b] * (layer[b] * 2);
- comp = MIN (comp, 1);
+ out[b] = in[b];
}
-
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
}
- out[ALPHA] = in[ALPHA];
-
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationhuemode.c b/app/operations/gimpoperationhuemode.c
index 2483f8f..aaae343 100644
--- a/app/operations/gimpoperationhuemode.c
+++ b/app/operations/gimpoperationhuemode.c
@@ -37,6 +37,7 @@ static void gimp_operation_hue_mode_prepare (GeglOperation *operation)
static gboolean gimp_operation_hue_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -50,11 +51,11 @@ G_DEFINE_TYPE (GimpOperationHueMode, gimp_operation_hue_mode,
static void
gimp_operation_hue_mode_class_init (GimpOperationHueModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hue-mode",
@@ -77,6 +78,7 @@ gimp_operation_hue_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -84,14 +86,18 @@ static gboolean
gimp_operation_hue_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
@@ -99,31 +105,50 @@ gimp_operation_hue_mode_process (GeglOperation *operation,
GimpHSV layer_hsv, out_hsv;
GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
GimpRGB out_rgb = {in[0], in[1], in[2]};
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
-
- gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
- gimp_rgb_to_hsv (&out_rgb, &out_hsv);
-
- /* Composition should have no effect if saturation is zero.
- * otherwise, black would be painted red (see bug #123296).
- */
- if (layer_hsv.s)
- out_hsv.h = layer_hsv.h;
- gimp_hsv_to_rgb (&out_hsv, &out_rgb);
-
- out[0] = out_rgb.r;
- out[1] = out_rgb.g;
- out[2] = out_rgb.b;
- out[3] = in[3];
-
- for (b = RED; b < ALPHA; b++)
- out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ gfloat comp_alpha, new_alpha, ratio;
+
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ ratio = comp_alpha / new_alpha;
+
+ gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
+ gimp_rgb_to_hsv (&out_rgb, &out_hsv);
+
+ /* Composition should have no effect if saturation is zero.
+ * otherwise, black would be painted red (see bug #123296).
+ */
+ if (layer_hsv.s)
+ out_hsv.h = layer_hsv.h;
+ gimp_hsv_to_rgb (&out_hsv, &out_rgb);
+
+ out[0] = out_rgb.r;
+ out[1] = out_rgb.g;
+ out[2] = out_rgb.b;
+ out[3] = in[3];
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationlightenonlymode.c b/app/operations/gimpoperationlightenonlymode.c
index 6cca8a1..9bd7343 100644
--- a/app/operations/gimpoperationlightenonlymode.c
+++ b/app/operations/gimpoperationlightenonlymode.c
@@ -32,6 +32,7 @@ static void gimp_operation_lighten_only_mode_prepare (GeglOperation *o
static gboolean gimp_operation_lighten_only_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -45,11 +46,11 @@ G_DEFINE_TYPE (GimpOperationLightenOnlyMode, gimp_operation_lighten_only_mode,
static void
gimp_operation_lighten_only_mode_class_init (GimpOperationLightenOnlyModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:lighten-only-mode",
@@ -57,7 +58,6 @@ gimp_operation_lighten_only_mode_class_init (GimpOperationLightenOnlyModeClass *
NULL);
operation_class->prepare = gimp_operation_lighten_only_mode_prepare;
-
point_class->process = gimp_operation_lighten_only_mode_process;
}
@@ -73,6 +73,7 @@ gimp_operation_lighten_only_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,34 +81,57 @@ static gboolean
gimp_operation_lighten_only_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *result,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
+
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- for (b = RED; b < ALPHA; b++)
+ if (comp_alpha && new_alpha)
{
- gfloat comp = MAX (layer[b], in[b]);
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = MAX (layer[b], in[b]);
- out[ALPHA] = in[ALPHA];
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationmultiplymode.c b/app/operations/gimpoperationmultiplymode.c
index 6fba66e..8d690c9 100644
--- a/app/operations/gimpoperationmultiplymode.c
+++ b/app/operations/gimpoperationmultiplymode.c
@@ -33,6 +33,7 @@ static void gimp_operation_multiply_mode_prepare (GeglOperation *opera
static gboolean gimp_operation_multiply_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -47,10 +48,10 @@ static void
gimp_operation_multiply_mode_class_init (GimpOperationMultiplyModeClass *klass)
{
GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:multiply-mode",
@@ -73,6 +74,7 @@ gimp_operation_multiply_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,93 @@ static gboolean
gimp_operation_multiply_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
-
- while (samples--)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+
+ if (mask)
{
- gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
-
- for (b = RED; b < ALPHA; b++)
+ while (samples--)
{
- gfloat comp = layer[b] * in[b];
- comp = CLAMP (comp, 0, 1);
-
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = layer[b] * in[b];
+ comp = CLAMP (comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = layer[b] * in[b];
+ comp = CLAMP (comp, 0, 1);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
-
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- layer += 4;
- out += 4;
}
return TRUE;
diff --git a/app/operations/gimpoperationnormalmode.c b/app/operations/gimpoperationnormalmode.c
index d503738..5321e7c 100644
--- a/app/operations/gimpoperationnormalmode.c
+++ b/app/operations/gimpoperationnormalmode.c
@@ -36,6 +36,7 @@ static gboolean gimp_operation_normal_parent_process (GeglOperation *oper
static gboolean gimp_operation_normal_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -51,11 +52,11 @@ G_DEFINE_TYPE (GimpOperationNormalMode, gimp_operation_normal_mode,
static void
gimp_operation_normal_mode_class_init (GimpOperationNormalModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:normal-mode",
@@ -124,42 +125,101 @@ static gboolean
gimp_operation_normal_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
- gfloat *in = in_buf;
- gfloat *aux = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat *in = in_buf;
+ gfloat *aux = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+ gdouble opacity = point->opacity;
if (point->premultiplied)
{
- while (samples--)
+ if (mask)
{
- out[0] = aux[0] + in[0] * (1.0f - aux[3]);
- out[1] = aux[1] + in[1] * (1.0f - aux[3]);
- out[2] = aux[2] + in[2] * (1.0f - aux[3]);
- out[3] = aux[3] + in[3] - aux[3] * in[3];
-
- in += 4;
- aux += 4;
- out += 4;
+ while (samples--)
+ {
+ gfloat value = opacity * (*mask);
+ gfloat aux_alpha = aux[ALPHA] * value;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = aux[b] * value + in[b] * (1.0f - aux_alpha);
+ }
+
+ out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+
+ in += 4;
+ aux += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gfloat aux_alpha = aux[ALPHA] * opacity;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = aux[b] * opacity + in[b] * (1.0f - aux_alpha);
+ }
+
+ out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+
+ in += 4;
+ aux += 4;
+ out += 4;
+ }
}
}
else
{
- while (samples--)
+ if (mask)
+ {
+ while (samples--)
+ {
+ gfloat value = opacity * (*mask);
+ gfloat aux_alpha = aux[ALPHA] * value;
+ gint b;
+
+ out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0 - aux_alpha)) / out[ALPHA];
+ }
+
+ in += 4;
+ aux += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
{
- out[0] = aux[0] * aux[3] + in[0] * in[3] * (1.0 - aux[3]);
- out[1] = aux[1] * aux[3] + in[1] * in[3] * (1.0 - aux[3]);
- out[2] = aux[2] * aux[3] + in[2] * in[3] * (1.0 - aux[3]);
- out[3] = aux[3] + in[3] - aux[3] * in[3];
-
- in += 4;
- aux += 4;
- out += 4;
+ while (samples--)
+ {
+ gfloat aux_alpha = aux[ALPHA] * opacity;
+ gint b;
+
+ out[ALPHA] = aux_alpha + in[ALPHA] - aux_alpha * in[ALPHA];
+ for (b = RED; b < ALPHA; b++)
+ {
+ out[b] = (aux[b] * aux_alpha + in[b] * in[ALPHA] * (1.0 - aux_alpha)) / out[ALPHA];
+ }
+
+ in += 4;
+ aux += 4;
+ out += 4;
+ }
}
}
diff --git a/app/operations/gimpoperationoverlaymode.c b/app/operations/gimpoperationoverlaymode.c
index 49f068a..3174a60 100644
--- a/app/operations/gimpoperationoverlaymode.c
+++ b/app/operations/gimpoperationoverlaymode.c
@@ -33,6 +33,7 @@ static void gimp_operation_overlay_mode_prepare (GeglOperation *operat
static gboolean gimp_operation_overlay_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationOverlayMode, gimp_operation_overlay_mode,
static void
gimp_operation_overlay_mode_class_init (GimpOperationOverlayModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:overlay-mode",
@@ -58,7 +59,6 @@ gimp_operation_overlay_mode_class_init (GimpOperationOverlayModeClass *klass)
NULL);
operation_class->prepare = gimp_operation_overlay_mode_prepare;
-
point_class->process = gimp_operation_overlay_mode_process;
}
@@ -74,6 +74,7 @@ gimp_operation_overlay_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -81,34 +82,91 @@ static gboolean
gimp_operation_overlay_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
-
- while (samples--)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+
+ if (mask)
{
- gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
-
- for (b = RED; b < ALPHA; b++)
+ while (samples--)
{
- gfloat comp = in[b] * (in[b] + (2 * layer[b]) * (1 - in[b]));
-
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gint b;
+ gfloat ratio = comp_alpha / new_alpha;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] * (in[b] + (2 * layer[b]) * (1 - in[b]));
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] * (in[b] + (2 * layer[b]) * (1 - in[b]));
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
-
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- layer += 4;
- out += 4;
}
return TRUE;
diff --git a/app/operations/gimpoperationpointlayermode.c b/app/operations/gimpoperationpointlayermode.c
index 3b100c1..09c513a 100644
--- a/app/operations/gimpoperationpointlayermode.c
+++ b/app/operations/gimpoperationpointlayermode.c
@@ -72,7 +72,8 @@ enum
{
PROP_0,
PROP_BLEND_MODE,
- PROP_PREMULTIPLIED
+ PROP_PREMULTIPLIED,
+ PROP_OPACITY
};
@@ -89,6 +90,7 @@ static void gimp_operation_point_layer_mode_prepare (GeglOperation
static gboolean gimp_operation_point_layer_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -96,7 +98,7 @@ static gboolean gimp_operation_point_layer_mode_process (GeglOperation
G_DEFINE_TYPE (GimpOperationPointLayerMode, gimp_operation_point_layer_mode,
- GEGL_TYPE_OPERATION_POINT_COMPOSER)
+ GEGL_TYPE_OPERATION_POINT_COMPOSER3)
static guint32 dissolve_lut[DISSOLVE_REPEAT_WIDTH * DISSOLVE_REPEAT_HEIGHT];
@@ -105,11 +107,11 @@ static guint32 dissolve_lut[DISSOLVE_REPEAT_WIDTH * DISSOLVE_REPEAT_HEIGHT];
static void
gimp_operation_point_layer_mode_class_init (GimpOperationPointLayerModeClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
- GeglOperationPointComposerClass *point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
- GRand *rand = g_rand_new_with_seed (DISSOLVE_SEED);
- int i;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GeglOperationPointComposer3Class *point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GRand *rand = g_rand_new_with_seed (DISSOLVE_SEED);
+ int i;
object_class->set_property = gimp_operation_point_layer_mode_set_property;
object_class->get_property = gimp_operation_point_layer_mode_get_property;
@@ -138,6 +140,13 @@ gimp_operation_point_layer_mode_class_init (GimpOperationPointLayerModeClass *kl
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class, PROP_OPACITY,
+ g_param_spec_double ("opacity",
+ NULL, NULL,
+ 0.0, 1.0, 1.0,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
for (i = 0; i < DISSOLVE_REPEAT_WIDTH * DISSOLVE_REPEAT_HEIGHT; i++)
dissolve_lut[i] = g_rand_int (rand);
@@ -167,6 +176,10 @@ gimp_operation_point_layer_mode_set_property (GObject *object,
self->premultiplied = g_value_get_boolean (value);
break;
+ case PROP_OPACITY:
+ self->opacity = g_value_get_double (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -191,6 +204,10 @@ gimp_operation_point_layer_mode_get_property (GObject *object,
g_value_set_boolean (value, self->premultiplied);
break;
+ case PROP_OPACITY:
+ g_value_set_double (value, self->opacity);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -211,6 +228,7 @@ gimp_operation_point_layer_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "output", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
}
static void
@@ -294,6 +312,7 @@ static gboolean
gimp_operation_point_layer_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -301,9 +320,11 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation,
{
GimpOperationPointLayerMode *self = GIMP_OPERATION_POINT_LAYER_MODE (operation);
GimpLayerModeEffects blend_mode = self->blend_mode;
+ gdouble opacity = self->opacity;
gfloat *in = in_buf; /* composite of layers below */
gfloat *lay = aux_buf; /* layer */
+ gfloat *mask = aux2_buf; /* mask */
gfloat *out = out_buf; /* resulting composite */
glong sample = samples;
gint c = 0;
@@ -313,6 +334,11 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation,
while (sample--)
{
+ if (mask)
+ in[ALPHA] *= (*mask) * opacity;
+ else
+ in[ALPHA] *= opacity;
+
/* XXX: having such a switch in an innerloop is a horrible idea */
switch (blend_mode)
{
@@ -584,6 +610,9 @@ gimp_operation_point_layer_mode_process (GeglOperation *operation,
in += 4;
lay += 4;
out += 4;
+
+ if (mask)
+ mask += 4;
}
return TRUE;
diff --git a/app/operations/gimpoperationpointlayermode.h b/app/operations/gimpoperationpointlayermode.h
index f077024..a9ccec1 100644
--- a/app/operations/gimpoperationpointlayermode.h
+++ b/app/operations/gimpoperationpointlayermode.h
@@ -34,15 +34,16 @@ typedef struct _GimpOperationPointLayerModeClass GimpOperationPointLayerModeClas
struct _GimpOperationPointLayerModeClass
{
- GeglOperationPointComposerClass parent_class;
+ GeglOperationPointComposer3Class parent_class;
};
struct _GimpOperationPointLayerMode
{
- GeglOperationPointComposer parent_instance;
+ GeglOperationPointComposer3 parent_instance;
GimpLayerModeEffects blend_mode;
gboolean premultiplied;
+ gdouble opacity;
};
diff --git a/app/operations/gimpoperationreplacemode.c b/app/operations/gimpoperationreplacemode.c
index 30c64c1..6a38896 100644
--- a/app/operations/gimpoperationreplacemode.c
+++ b/app/operations/gimpoperationreplacemode.c
@@ -28,22 +28,6 @@
#include "gimpoperationreplacemode.h"
-enum
-{
- PROP_0,
- PROP_PREMULTIPLIED,
- PROP_OPACITY
-};
-
-
-static void gimp_operation_replace_mode_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_operation_replace_mode_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
static void gimp_operation_replace_mode_prepare (GeglOperation *operation);
static gboolean gimp_operation_replace_mode_process (GeglOperation *operation,
void *in_buf,
@@ -56,23 +40,18 @@ static gboolean gimp_operation_replace_mode_process (GeglOperation *o
G_DEFINE_TYPE (GimpOperationReplaceMode, gimp_operation_replace_mode,
- GEGL_TYPE_OPERATION_POINT_COMPOSER3)
+ GIMP_TYPE_OPERATION_POINT_LAYER_MODE)
static void
gimp_operation_replace_mode_class_init (GimpOperationReplaceModeClass *klass)
{
- GObjectClass *object_class;
GeglOperationClass *operation_class;
GeglOperationPointComposer3Class *point_class;
- object_class = G_OBJECT_CLASS (klass);
operation_class = GEGL_OPERATION_CLASS (klass);
point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
- object_class->set_property = gimp_operation_replace_mode_set_property;
- object_class->get_property = gimp_operation_replace_mode_get_property;
-
gegl_operation_class_set_keys (operation_class,
"name", "gimp:replace-mode",
"description", "GIMP replace mode operation",
@@ -80,21 +59,6 @@ gimp_operation_replace_mode_class_init (GimpOperationReplaceModeClass *klass)
operation_class->prepare = gimp_operation_replace_mode_prepare;
point_class->process = gimp_operation_replace_mode_process;
-
- g_object_class_install_property (object_class, PROP_PREMULTIPLIED,
- g_param_spec_boolean ("premultiplied",
- NULL, NULL,
- TRUE,
- GIMP_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (object_class, PROP_OPACITY,
- g_param_spec_double ("opacity",
- NULL, NULL,
- 0.0, 1.0,
- 1.0,
- GIMP_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
}
static void
@@ -103,50 +67,6 @@ gimp_operation_replace_mode_init (GimpOperationReplaceMode *self)
}
static void
-gimp_operation_replace_mode_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GimpOperationReplaceMode *self = GIMP_OPERATION_REPLACE_MODE (object);
-
- switch (property_id)
- {
- case PROP_PREMULTIPLIED:
- self->premultiplied = g_value_get_boolean (value);
- break;
- case PROP_OPACITY:
- self->opacity = g_value_get_double (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gimp_operation_replace_mode_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GimpOperationReplaceMode *self = GIMP_OPERATION_REPLACE_MODE (object);
-
- switch (property_id)
- {
- case PROP_PREMULTIPLIED:
- g_value_set_boolean (value, self->premultiplied);
- break;
- case PROP_OPACITY:
- g_value_set_double (value, self->opacity);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
gimp_operation_replace_mode_prepare (GeglOperation *operation)
{
const Babl *format = babl_format ("RGBA float");
@@ -167,12 +87,12 @@ gimp_operation_replace_mode_process (GeglOperation *operation,
const GeglRectangle *roi,
gint level)
{
- GimpOperationReplaceMode *self = GIMP_OPERATION_REPLACE_MODE (operation);
- gfloat opacity = self->opacity;
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *mask = aux2_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
diff --git a/app/operations/gimpoperationreplacemode.h b/app/operations/gimpoperationreplacemode.h
index 3d09c34..46712b4 100644
--- a/app/operations/gimpoperationreplacemode.h
+++ b/app/operations/gimpoperationreplacemode.h
@@ -23,6 +23,9 @@
#define __GIMP_OPERATION_REPLACE_MODE_H__
+#include "gimpoperationpointlayermode.h"
+
+
#define GIMP_TYPE_OPERATION_REPLACE_MODE (gimp_operation_replace_mode_get_type ())
#define GIMP_OPERATION_REPLACE_MODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_REPLACE_MODE, GimpOperationReplaceMode))
#define GIMP_OPERATION_REPLACE_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPERATION_REPLACE_MODE, GimpOperationReplaceModeClass))
@@ -36,7 +39,7 @@ typedef struct _GimpOperationReplaceModeClass GimpOperationReplaceModeClass;
struct _GimpOperationReplaceMode
{
- GeglOperationPointComposer3 parent_instance;
+ GimpOperationPointLayerMode parent_instance;
gdouble opacity;
gboolean premultiplied;
@@ -44,7 +47,7 @@ struct _GimpOperationReplaceMode
struct _GimpOperationReplaceModeClass
{
- GeglOperationPointComposer3Class parent_class;
+ GimpOperationPointLayerModeClass parent_class;
};
diff --git a/app/operations/gimpoperationsaturationmode.c b/app/operations/gimpoperationsaturationmode.c
index 20f142b..f9cdfe6 100644
--- a/app/operations/gimpoperationsaturationmode.c
+++ b/app/operations/gimpoperationsaturationmode.c
@@ -37,6 +37,7 @@ static void gimp_operation_saturation_mode_prepare (GeglOperation *ope
static gboolean gimp_operation_saturation_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -50,11 +51,11 @@ G_DEFINE_TYPE (GimpOperationSaturationMode, gimp_operation_saturation_mode,
static void
gimp_operation_saturation_mode_class_init (GimpOperationSaturationModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:saturation-mode",
@@ -77,6 +78,7 @@ gimp_operation_saturation_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -84,14 +86,18 @@ static gboolean
gimp_operation_saturation_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
@@ -99,27 +105,46 @@ gimp_operation_saturation_mode_process (GeglOperation *operation,
GimpHSV layer_hsv, out_hsv;
GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
GimpRGB out_rgb = {in[0], in[1], in[2]};
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
- gimp_rgb_to_hsv (&out_rgb, &out_hsv);
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
- out_hsv.s = layer_hsv.s;
- gimp_hsv_to_rgb (&out_hsv, &out_rgb);
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- out[0] = out_rgb.r;
- out[1] = out_rgb.g;
- out[2] = out_rgb.b;
- out[3] = in[3];
+ if (comp_alpha && new_alpha)
+ {
+ ratio = comp_alpha / new_alpha;
- for (b = RED; b < ALPHA; b++)
- out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
+ gimp_rgb_to_hsv (&out_rgb, &out_hsv);
+
+ out_hsv.s = layer_hsv.s;
+ gimp_hsv_to_rgb (&out_hsv, &out_rgb);
+
+ out[0] = out_rgb.r;
+ out[1] = out_rgb.g;
+ out[2] = out_rgb.b;
+ out[3] = in[3];
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationscreenmode.c b/app/operations/gimpoperationscreenmode.c
index 975d0d2..5cffcaa 100644
--- a/app/operations/gimpoperationscreenmode.c
+++ b/app/operations/gimpoperationscreenmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_screen_mode_prepare (GeglOperation *operati
static gboolean gimp_operation_screen_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -47,10 +48,10 @@ static void
gimp_operation_screen_mode_class_init (GimpOperationScreenModeClass *klass)
{
GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:screen-mode",
@@ -73,6 +74,7 @@ gimp_operation_screen_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,34 +82,91 @@ static gboolean
gimp_operation_screen_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
-
- while (samples--)
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
+
+ if (mask)
{
- gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
-
- for (b = RED; b < ALPHA; b++)
+ while (samples--)
{
- gfloat comp = 1 - (1 - in[b]) * (1 - layer[b]);
-
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = 1 - (1 - in[b]) * (1 - layer[b]);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ mask += 1;
+ out += 4;
+ }
+ }
+ else
+ {
+ while (samples--)
+ {
+ gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = 1 - (1 - in[b]) * (1 - layer[b]);
+
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
+
+ in += 4;
+ layer += 4;
+ out += 4;
}
-
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- layer += 4;
- out += 4;
}
return TRUE;
diff --git a/app/operations/gimpoperationsoftlightmode.c b/app/operations/gimpoperationsoftlightmode.c
index e9c1b82..d4d32bb 100644
--- a/app/operations/gimpoperationsoftlightmode.c
+++ b/app/operations/gimpoperationsoftlightmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_softlight_mode_prepare (GeglOperation *oper
static gboolean gimp_operation_softlight_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationSoftlightMode, gimp_operation_softlight_mode,
static void
gimp_operation_softlight_mode_class_init (GimpOperationSoftlightModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:softlight-mode",
@@ -58,7 +59,6 @@ gimp_operation_softlight_mode_class_init (GimpOperationSoftlightModeClass *klass
NULL);
operation_class->prepare = gimp_operation_softlight_mode_prepare;
-
point_class->process = gimp_operation_softlight_mode_process;
}
@@ -74,6 +74,7 @@ gimp_operation_softlight_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -81,36 +82,59 @@ static gboolean
gimp_operation_softlight_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
+
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- for (b = RED; b < ALPHA; b++)
+ if (comp_alpha && new_alpha)
{
- gfloat multiply = in[b] * layer[b];
- gfloat screen = 1 - (1 - in[b]) * (1 - layer[b]);
- gfloat comp = (1 - in[b]) * multiply + in[b] * screen;
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat multiply = in[b] * layer[b];
+ gfloat screen = 1 - (1 - in[b]) * (1 - layer[b]);
+ gfloat comp = (1 - in[b]) * multiply + in[b] * screen;
- out[ALPHA] = in[ALPHA];
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationsubtractmode.c b/app/operations/gimpoperationsubtractmode.c
index 3c22d08..a1de134 100644
--- a/app/operations/gimpoperationsubtractmode.c
+++ b/app/operations/gimpoperationsubtractmode.c
@@ -33,6 +33,7 @@ static void gimp_operation_subtract_mode_prepare (GeglOperation *opera
static gboolean gimp_operation_subtract_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -46,11 +47,11 @@ G_DEFINE_TYPE (GimpOperationSubtractMode, gimp_operation_subtract_mode,
static void
gimp_operation_subtract_mode_class_init (GimpOperationSubtractModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:subtract-mode",
@@ -73,6 +74,7 @@ gimp_operation_subtract_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -80,35 +82,59 @@ static gboolean
gimp_operation_subtract_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
gint b;
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- for (b = RED; b < ALPHA; b++)
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+
+ if (mask)
+ comp_alpha *= (*mask);
+
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
+
+ if (comp_alpha && new_alpha)
{
- gfloat comp = in[b] - layer[b];
- comp = (comp < 0) ? 0 : comp;
+ ratio = comp_alpha / new_alpha;
- out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
- }
+ for (b = RED; b < ALPHA; b++)
+ {
+ gfloat comp = in[b] - layer[b];
+ comp = (comp < 0) ? 0 : comp;
- out[ALPHA] = in[ALPHA];
+ out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+
+ out[ALPHA] = in[ALPHA];
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
diff --git a/app/operations/gimpoperationvaluemode.c b/app/operations/gimpoperationvaluemode.c
index e336901..c4eb389 100644
--- a/app/operations/gimpoperationvaluemode.c
+++ b/app/operations/gimpoperationvaluemode.c
@@ -37,6 +37,7 @@ static void gimp_operation_value_mode_prepare (GeglOperation *operatio
static gboolean gimp_operation_value_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
@@ -50,11 +51,11 @@ G_DEFINE_TYPE (GimpOperationValueMode, gimp_operation_value_mode,
static void
gimp_operation_value_mode_class_init (GimpOperationValueModeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposerClass *point_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointComposer3Class *point_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
+ point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:value-mode",
@@ -77,6 +78,7 @@ gimp_operation_value_mode_prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
+ gegl_operation_set_format (operation, "aux2", babl_format ("Y float"));
gegl_operation_set_format (operation, "output", format);
}
@@ -84,14 +86,18 @@ static gboolean
gimp_operation_value_mode_process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
+ void *aux2_buf,
void *out_buf,
glong samples,
const GeglRectangle *roi,
gint level)
{
- gfloat *in = in_buf;
- gfloat *layer = aux_buf;
- gfloat *out = out_buf;
+ GimpOperationPointLayerMode *point = GIMP_OPERATION_POINT_LAYER_MODE (operation);
+ gfloat opacity = point->opacity;
+ gfloat *in = in_buf;
+ gfloat *layer = aux_buf;
+ gfloat *mask = aux2_buf;
+ gfloat *out = out_buf;
while (samples--)
{
@@ -99,27 +105,46 @@ gimp_operation_value_mode_process (GeglOperation *operation,
GimpHSV layer_hsv, out_hsv;
GimpRGB layer_rgb = {layer[0], layer[1], layer[2]};
GimpRGB out_rgb = {in[0], in[1], in[2]};
- gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]);
- gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- gfloat ratio = comp_alpha / new_alpha;
+ gfloat comp_alpha, new_alpha, ratio;
- gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
- gimp_rgb_to_hsv (&out_rgb, &out_hsv);
+ comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity;
+ if (mask)
+ comp_alpha *= (*mask);
- out_hsv.v = layer_hsv.v;
- gimp_hsv_to_rgb (&out_hsv, &out_rgb);
+ new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
- out[0] = out_rgb.r;
- out[1] = out_rgb.g;
- out[2] = out_rgb.b;
- out[3] = in[3];
+ if (comp_alpha && new_alpha)
+ {
+ ratio = comp_alpha / new_alpha;
- for (b = RED; b < ALPHA; b++)
- out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ gimp_rgb_to_hsv (&layer_rgb, &layer_hsv);
+ gimp_rgb_to_hsv (&out_rgb, &out_hsv);
+
+ out_hsv.v = layer_hsv.v;
+ gimp_hsv_to_rgb (&out_hsv, &out_rgb);
+
+ out[0] = out_rgb.r;
+ out[1] = out_rgb.g;
+ out[2] = out_rgb.b;
+ out[3] = in[3];
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = out[b] * ratio + in[b] * (1 - ratio) + 0.0001;
+ }
+ else
+ {
+ for (b = RED; b <= ALPHA; b++)
+ {
+ out[b] = in[b];
+ }
+ }
in += 4;
layer += 4;
out += 4;
+
+ if (mask)
+ mask += 1;
}
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]