mirror of https://github.com/GNOME/gimp.git
app: modified gegl blending modes to take mask and opacity inputs
This commit is contained in:
parent
efa52edf6e
commit
e377eb01cd
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -316,21 +316,6 @@ gimp_gegl_node_set_layer_mode (GeglNode *node,
|
|||
|
||||
g_return_if_fail (GEGL_IS_NODE (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;
|
||||
|
|
|
@ -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;
|
||||
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--)
|
||||
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);
|
||||
gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
|
||||
gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
|
||||
|
||||
out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
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;
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
if (comp_alpha && new_alpha)
|
||||
{
|
||||
gfloat ratio = comp_alpha / new_alpha;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
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--)
|
||||
if (mask)
|
||||
{
|
||||
out[RED] = in[RED];
|
||||
out[GREEN] = in[GREEN];
|
||||
out[BLUE] = in[BLUE];
|
||||
out[ALPHA] = in[ALPHA];
|
||||
while (samples--)
|
||||
{
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
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 (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[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
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--)
|
||||
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;
|
||||
gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
|
||||
gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
|
||||
|
||||
out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
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;
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
if (comp_alpha && new_alpha)
|
||||
{
|
||||
gfloat ratio = comp_alpha / new_alpha;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
|
||||
for (y = result->y; y < result->y + result->height; y++)
|
||||
if (mask)
|
||||
{
|
||||
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++)
|
||||
for (y = result->y; y < result->y + result->height; y++)
|
||||
{
|
||||
if (g_rand_int_range (gr, 0, 255) >= aux[3] * 255)
|
||||
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] = 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
|
||||
{
|
||||
out[0] = aux[0];
|
||||
out[1] = aux[1];
|
||||
out[2] = aux[2];
|
||||
out[3] = 1.0;
|
||||
}
|
||||
in += 4;
|
||||
out += 4;
|
||||
aux += 4;
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
g_rand_free (gr);
|
||||
}
|
||||
g_rand_free (gr);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
else
|
||||
{
|
||||
comp = in[b] * (layer[b] * 2);
|
||||
comp = MIN (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;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
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 = 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[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
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--)
|
||||
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);
|
||||
gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
|
||||
gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
|
||||
|
||||
out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
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;
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
if (comp_alpha && new_alpha)
|
||||
{
|
||||
gfloat ratio = comp_alpha / new_alpha;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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];
|
||||
while (samples--)
|
||||
{
|
||||
gfloat value = opacity * (*mask);
|
||||
gfloat aux_alpha = aux[ALPHA] * value;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
aux += 4;
|
||||
out += 4;
|
||||
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)
|
||||
{
|
||||
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];
|
||||
while (samples--)
|
||||
{
|
||||
gfloat value = opacity * (*mask);
|
||||
gfloat aux_alpha = aux[ALPHA] * value;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
aux += 4;
|
||||
out += 4;
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
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--)
|
||||
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]));
|
||||
gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
|
||||
gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
|
||||
|
||||
out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
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;
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
if (comp_alpha && new_alpha)
|
||||
{
|
||||
gfloat ratio = comp_alpha / new_alpha;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -102,50 +66,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)
|
||||
{
|
||||
|
@ -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--)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
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--)
|
||||
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]);
|
||||
gfloat comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity * (*mask);
|
||||
gfloat new_alpha = in[ALPHA] + (1 - in[ALPHA]) * comp_alpha;
|
||||
|
||||
out[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
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;
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
if (comp_alpha && new_alpha)
|
||||
{
|
||||
gfloat ratio = comp_alpha / new_alpha;
|
||||
gint b;
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
|
||||
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 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[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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[b] = comp * ratio + in[b] * (1 - ratio) + 0.0001;
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = RED; b <= ALPHA; b++)
|
||||
{
|
||||
out[b] = in[b];
|
||||
}
|
||||
}
|
||||
|
||||
out[ALPHA] = in[ALPHA];
|
||||
|
||||
in += 4;
|
||||
layer += 4;
|
||||
out += 4;
|
||||
|
||||
if (mask)
|
||||
mask += 1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue