[gimp] app: layer mode code shuffling
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: layer mode code shuffling
- Date: Thu, 17 Aug 2017 15:24:08 +0000 (UTC)
commit 71bbd88e00ccfd5b27c17c1fa3c1c9fe9ced3797
Author: Ell <ell_se yahoo com>
Date: Thu Aug 17 10:26:49 2017 -0400
app: layer mode code shuffling
Commit 3635cf04ab69bafb76d7583da804f580f2d5fbf3 moved the special
handling of bottom-layer compositing to GimpOperationLayerMode.
This required giving the op more control over the process()
function of its subclasses. As a temporary workaround, the commit
bypassed the subclasses entirely, using "gimp:layer-mode" for all
modes. This is the reckoning :)
Add a process() virtual function to GimpOperationLayerMode, which
its subclasses should override instead of
GeglOperationPointComposer3's process() functions. Reinstate the
subclasses (by returning the correct op in
gimp_layer_mode_get_oepration()), and have them override this
function.
Improve the way gimp_operation_layer_mode_process() dispatches to
the actual process function, to slightly lower its overhead and
fix some thread-safety issues.
Remove the "function" field of the layer-mode info array, and have
gimp_layer_mode_get_function() return the
GimpOperationLayerMode::process() function of the corresponding
op's class (caching the result, to keep it cheap.) This reduces
redundancy, allows us to make the ops' process() functions private,
and simplifies SSE dispatching (only used by NORMAL mode,
currently.)
Move the blend and composite functions of the non-specialized
layer modes to gimpoperationlayermode-{blend,composite}.[hc],
respectively, to improve code organization.
Move the SSE2 composite functions to a separate file, so that they
can be built as part of libapplayermodes_sse2, allowing
libapplayermodes to be built without SSE2 compiler flags. This
allows building GIMP with SSE acceleration enabled, while running
the resulting binary on a target with no SSE accelration.
Add a "blend_function" field to the layer-mode info array, and use
it to specify the blend function for the non-specialized modes.
This replaces the separate switch() statement that we used
previously.
Remove the "affected_region" field of the layer-mode info array.
We don't need it anymore, since we can go back to using
GimpOperationLayerMode's virtual get_affected_region() function.
Last but not least, a bunch of code cleanups and consistency
adjustments.
app/Makefile.am | 2 +-
app/config/Makefile.am | 2 +-
.../gimpoperationadditionlegacy.c | 21 +-
.../gimpoperationadditionlegacy.h | 11 +-
.../layer-modes-legacy/gimpoperationburnlegacy.c | 22 +-
.../layer-modes-legacy/gimpoperationburnlegacy.h | 11 +-
.../gimpoperationdarkenonlylegacy.c | 21 +-
.../gimpoperationdarkenonlylegacy.h | 11 +-
.../gimpoperationdifferencelegacy.c | 21 +-
.../gimpoperationdifferencelegacy.h | 11 +-
.../layer-modes-legacy/gimpoperationdividelegacy.c | 21 +-
.../layer-modes-legacy/gimpoperationdividelegacy.h | 11 +-
.../layer-modes-legacy/gimpoperationdodgelegacy.c | 21 +-
.../layer-modes-legacy/gimpoperationdodgelegacy.h | 11 +-
.../gimpoperationgrainextractlegacy.c | 21 +-
.../gimpoperationgrainextractlegacy.h | 11 +-
.../gimpoperationgrainmergelegacy.c | 21 +-
.../gimpoperationgrainmergelegacy.h | 11 +-
.../gimpoperationhardlightlegacy.c | 21 +-
.../gimpoperationhardlightlegacy.h | 11 +-
.../gimpoperationhslcolorlegacy.c | 21 +-
.../gimpoperationhslcolorlegacy.h | 11 +-
.../layer-modes-legacy/gimpoperationhsvhuelegacy.c | 21 +-
.../layer-modes-legacy/gimpoperationhsvhuelegacy.h | 11 +-
.../gimpoperationhsvsaturationlegacy.c | 21 +-
.../gimpoperationhsvsaturationlegacy.h | 11 +-
.../gimpoperationhsvvaluelegacy.c | 21 +-
.../gimpoperationhsvvaluelegacy.h | 11 +-
.../gimpoperationlightenonlylegacy.c | 21 +-
.../gimpoperationlightenonlylegacy.h | 11 +-
.../gimpoperationmultiplylegacy.c | 21 +-
.../gimpoperationmultiplylegacy.h | 11 +-
.../layer-modes-legacy/gimpoperationscreenlegacy.c | 21 +-
.../layer-modes-legacy/gimpoperationscreenlegacy.h | 11 +-
.../gimpoperationsoftlightlegacy.c | 21 +-
.../gimpoperationsoftlightlegacy.h | 11 +-
.../gimpoperationsubtractlegacy.c | 21 +-
.../gimpoperationsubtractlegacy.h | 11 +-
app/operations/layer-modes/Makefile.am | 45 +-
app/operations/layer-modes/gimp-layer-modes.c | 192 +-
app/operations/layer-modes/gimp-layer-modes.h | 3 +-
.../layer-modes/gimpoperationantierase.c | 27 +-
.../layer-modes/gimpoperationantierase.h | 11 +-
app/operations/layer-modes/gimpoperationbehind.c | 24 +-
app/operations/layer-modes/gimpoperationbehind.h | 9 -
app/operations/layer-modes/gimpoperationdissolve.c | 38 +-
app/operations/layer-modes/gimpoperationdissolve.h | 11 +-
app/operations/layer-modes/gimpoperationerase.c | 23 +-
app/operations/layer-modes/gimpoperationerase.h | 11 +-
.../layer-modes/gimpoperationlayermode-blend.c | 1168 +++++++++++
.../layer-modes/gimpoperationlayermode-blend.h | 167 ++
.../gimpoperationlayermode-composite-sse2.c | 105 +
.../layer-modes/gimpoperationlayermode-composite.c | 434 ++++
.../layer-modes/gimpoperationlayermode-composite.h | 98 +
.../layer-modes/gimpoperationlayermode.c | 2162 ++------------------
.../layer-modes/gimpoperationlayermode.h | 49 +-
app/operations/layer-modes/gimpoperationmerge.c | 23 +-
app/operations/layer-modes/gimpoperationmerge.h | 11 +-
.../layer-modes/gimpoperationnormal-sse2.c | 79 +-
.../layer-modes/gimpoperationnormal-sse4.c | 80 +-
app/operations/layer-modes/gimpoperationnormal.c | 43 +-
app/operations/layer-modes/gimpoperationnormal.h | 76 +-
app/operations/layer-modes/gimpoperationreplace.c | 26 +-
app/operations/layer-modes/gimpoperationreplace.h | 11 +-
app/operations/layer-modes/gimpoperationsplit.c | 23 +-
app/operations/layer-modes/gimpoperationsplit.h | 11 +-
app/operations/operations-types.h | 26 +-
app/paint/gimppaintcore-loops.c | 54 +-
app/tests/Makefile.am | 2 +-
69 files changed, 2828 insertions(+), 2795 deletions(-)
---
diff --git a/app/Makefile.am b/app/Makefile.am
index ad8f776..97807cb 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -147,9 +147,9 @@ gimpconsoleldadd = \
file/libappfile.a \
text/libapptext.a \
paint/libapppaint.a \
+ operations/libappoperations.a \
operations/layer-modes/libapplayermodes.a \
operations/layer-modes-legacy/libapplayermodeslegacy.a \
- operations/libappoperations.a \
gegl/libappgegl.a \
config/libappconfig.a \
$(libgimpconfig) \
diff --git a/app/config/Makefile.am b/app/config/Makefile.am
index 97bc714..13d9221 100644
--- a/app/config/Makefile.am
+++ b/app/config/Makefile.am
@@ -103,9 +103,9 @@ test_config_LDADD = \
../text/libapptext.a \
../paint/libapppaint.a \
../gegl/libappgegl.a \
+ ../operations/libappoperations.a \
../operations/layer-modes/libapplayermodes.a \
../operations/layer-modes-legacy/libapplayermodeslegacy.a \
- ../operations/libappoperations.a \
libappconfig.a \
../gimp-debug.o \
../gimp-log.o \
diff --git a/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.c
index 3279028..e42b315 100644
--- a/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationadditionlegacy.h"
+static gboolean gimp_operation_addition_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationAdditionLegacy, gimp_operation_addition_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationAdditionLegacy, gimp_operation_addition_legacy,
static void
gimp_operation_addition_legacy_class_init (GimpOperationAdditionLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:addition-legacy",
"description", "GIMP addition mode operation",
NULL);
- point_class->process = gimp_operation_addition_legacy_process;
+ layer_mode_class->process = gimp_operation_addition_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_addition_legacy_init (GimpOperationAdditionLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_addition_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.h
index 730a5dc..7049567 100644
--- a/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationadditionlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationAdditionLegacyClass
};
-GType gimp_operation_addition_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_addition_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_addition_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_ADDITION_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationburnlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationburnlegacy.c
index a00a131..531f097 100644
--- a/app/operations/layer-modes-legacy/gimpoperationburnlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationburnlegacy.c
@@ -27,6 +27,17 @@
#include "gimpoperationburnlegacy.h"
+
+static gboolean gimp_operation_burn_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationBurnLegacy, gimp_operation_burn_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -34,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationBurnLegacy, gimp_operation_burn_legacy,
static void
gimp_operation_burn_legacy_class_init (GimpOperationBurnLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:burn-legacy",
"description", "GIMP burn mode operation",
NULL);
- point_class->process = gimp_operation_burn_legacy_process;
+ layer_mode_class->process = gimp_operation_burn_legacy_process;
}
static void
@@ -53,7 +61,7 @@ gimp_operation_burn_legacy_init (GimpOperationBurnLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_burn_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationburnlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationburnlegacy.h
index 5e350d9..669e784 100644
--- a/app/operations/layer-modes-legacy/gimpoperationburnlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationburnlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationBurnLegacyClass
};
-GType gimp_operation_burn_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_burn_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_burn_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_BURN_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.c
b/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.c
index a35abbd..74c770c 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationdarkenonlylegacy.h"
+static gboolean gimp_operation_darken_only_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationDarkenOnlyLegacy, gimp_operation_darken_only_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationDarkenOnlyLegacy, gimp_operation_darken_only_legacy,
static void
gimp_operation_darken_only_legacy_class_init (GimpOperationDarkenOnlyLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:darken-only-legacy",
"description", "GIMP darken only mode operation",
NULL);
- point_class->process = gimp_operation_darken_only_legacy_process;
+ layer_mode_class->process = gimp_operation_darken_only_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_darken_only_legacy_init (GimpOperationDarkenOnlyLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_darken_only_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.h
b/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.h
index 5f416b3..f72a151 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationDarkenOnlyLegacyClass
};
-GType gimp_operation_darken_only_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_darken_only_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_darken_only_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_DARKEN_ONLY_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.c
b/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.c
index 1fa5ffa..0ff29ed 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationdifferencelegacy.h"
+static gboolean gimp_operation_difference_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationDifferenceLegacy, gimp_operation_difference_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationDifferenceLegacy, gimp_operation_difference_legacy,
static void
gimp_operation_difference_legacy_class_init (GimpOperationDifferenceLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:difference-legacy",
"description", "GIMP difference mode operation",
NULL);
- point_class->process = gimp_operation_difference_legacy_process;
+ layer_mode_class->process = gimp_operation_difference_legacy_process;
}
static void
@@ -55,7 +62,7 @@ gimp_operation_difference_legacy_init (GimpOperationDifferenceLegacy *self)
}
-gboolean
+static gboolean
gimp_operation_difference_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.h
b/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.h
index 727a623..312aebb 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationdifferencelegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationDifferenceLegacyClass
};
-GType gimp_operation_difference_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_difference_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_difference_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_DIFFERENCE_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationdividelegacy.c
b/app/operations/layer-modes-legacy/gimpoperationdividelegacy.c
index 48564a7..50afd3a 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdividelegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationdividelegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationdividelegacy.h"
+static gboolean gimp_operation_divide_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationDivideLegacy, gimp_operation_divide_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationDivideLegacy, gimp_operation_divide_legacy,
static void
gimp_operation_divide_legacy_class_init (GimpOperationDivideLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:divide-legacy",
"description", "GIMP divide mode operation",
NULL);
- point_class->process = gimp_operation_divide_legacy_process;
+ layer_mode_class->process = gimp_operation_divide_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_divide_legacy_init (GimpOperationDivideLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_divide_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationdividelegacy.h
b/app/operations/layer-modes-legacy/gimpoperationdividelegacy.h
index cd5589d..3fadfc9 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdividelegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationdividelegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationDivideLegacyClass
};
-GType gimp_operation_divide_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_divide_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_divide_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_DIVIDE_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.c
b/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.c
index 01b25f2..d94c518 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationdodgelegacy.h"
+static gboolean gimp_operation_dodge_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationDodgeLegacy, gimp_operation_dodge_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationDodgeLegacy, gimp_operation_dodge_legacy,
static void
gimp_operation_dodge_legacy_class_init (GimpOperationDodgeLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:dodge-legacy",
"description", "GIMP dodge mode operation",
NULL);
- point_class->process = gimp_operation_dodge_legacy_process;
+ layer_mode_class->process = gimp_operation_dodge_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_dodge_legacy_init (GimpOperationDodgeLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_dodge_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.h
b/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.h
index 2eafabd..2013fd0 100644
--- a/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationdodgelegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationDodgeLegacyClass
};
-GType gimp_operation_dodge_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_dodge_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_dodge_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_DODGE_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c
index 802fde2..1646c0d 100644
--- a/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationgrainextractlegacy.h"
+static gboolean gimp_operation_grain_extract_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationGrainExtractLegacy, gimp_operation_grain_extract_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationGrainExtractLegacy, gimp_operation_grain_extract_leg
static void
gimp_operation_grain_extract_legacy_class_init (GimpOperationGrainExtractLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:grain-extract-legacy",
"description", "GIMP grain extract mode operation",
NULL);
- point_class->process = gimp_operation_grain_extract_legacy_process;
+ layer_mode_class->process = gimp_operation_grain_extract_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_grain_extract_legacy_init (GimpOperationGrainExtractLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_grain_extract_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.h
index 7c86455..e6acc28 100644
--- a/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationGrainExtractLegacyClass
};
-GType gimp_operation_grain_extract_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_grain_extract_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_grain_extract_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_GRAIN_EXTRACT_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c
b/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c
index a5e0117..fddd93d 100644
--- a/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationgrainmergelegacy.h"
+static gboolean gimp_operation_grain_merge_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationGrainMergeLegacy, gimp_operation_grain_merge_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationGrainMergeLegacy, gimp_operation_grain_merge_legacy,
static void
gimp_operation_grain_merge_legacy_class_init (GimpOperationGrainMergeLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:grain-merge-legacy",
"description", "GIMP grain merge mode operation",
NULL);
- point_class->process = gimp_operation_grain_merge_legacy_process;
+ layer_mode_class->process = gimp_operation_grain_merge_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_grain_merge_legacy_init (GimpOperationGrainMergeLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_grain_merge_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.h
b/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.h
index 579f545..7aeacf2 100644
--- a/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationGrainMergeLegacyClass
};
-GType gimp_operation_grain_merge_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_grain_merge_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_grain_merge_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_GRAIN_MERGE_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c
index acc7798..96a3233 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationhardlightlegacy.h"
+static gboolean gimp_operation_hardlight_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationHardlightLegacy, gimp_operation_hardlight_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationHardlightLegacy, gimp_operation_hardlight_legacy,
static void
gimp_operation_hardlight_legacy_class_init (GimpOperationHardlightLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hardlight-legacy",
"description", "GIMP hardlight mode operation",
NULL);
- point_class->process = gimp_operation_hardlight_legacy_process;
+ layer_mode_class->process = gimp_operation_hardlight_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_hardlight_legacy_init (GimpOperationHardlightLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_hardlight_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.h
index 1a82e95..ebcbe8b 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationHardlightLegacyClass
};
-GType gimp_operation_hardlight_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_hardlight_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_hardlight_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_HARDLIGHT_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.c
index b4c2dfe..fa4afe9 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.c
@@ -32,6 +32,16 @@
#include "gimpoperationhslcolorlegacy.h"
+static gboolean gimp_operation_hsl_color_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationHslColorLegacy, gimp_operation_hsl_color_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -39,18 +49,15 @@ G_DEFINE_TYPE (GimpOperationHslColorLegacy, gimp_operation_hsl_color_legacy,
static void
gimp_operation_hsl_color_legacy_class_init (GimpOperationHslColorLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hsl-color-legacy",
"description", "GIMP color mode operation",
NULL);
- point_class->process = gimp_operation_hsl_color_legacy_process;
+ layer_mode_class->process = gimp_operation_hsl_color_legacy_process;
}
static void
@@ -58,7 +65,7 @@ gimp_operation_hsl_color_legacy_init (GimpOperationHslColorLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_hsl_color_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.h
index 182d007..34ce586 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationhslcolorlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationHslColorLegacyClass
};
-GType gimp_operation_hsl_color_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_hsl_color_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_hsl_color_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_HSL_COLOR_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.c
b/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.c
index 863ee39..1141ba8 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.c
@@ -32,6 +32,16 @@
#include "gimpoperationhsvhuelegacy.h"
+static gboolean gimp_operation_hsv_hue_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationHsvHueLegacy, gimp_operation_hsv_hue_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -39,18 +49,15 @@ G_DEFINE_TYPE (GimpOperationHsvHueLegacy, gimp_operation_hsv_hue_legacy,
static void
gimp_operation_hsv_hue_legacy_class_init (GimpOperationHsvHueLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hsv-hue-legacy",
"description", "GIMP hue mode operation",
NULL);
- point_class->process = gimp_operation_hsv_hue_legacy_process;
+ layer_mode_class->process = gimp_operation_hsv_hue_legacy_process;
}
static void
@@ -58,7 +65,7 @@ gimp_operation_hsv_hue_legacy_init (GimpOperationHsvHueLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_hsv_hue_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.h
b/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.h
index 8f353b4..5686da5 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationhsvhuelegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationHsvHueLegacyClass
};
-GType gimp_operation_hsv_hue_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_hsv_hue_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_hsv_hue_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_HSV_HUE_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.c
index 9d8d18c..81d85a2 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.c
@@ -32,6 +32,16 @@
#include "gimpoperationhsvsaturationlegacy.h"
+static gboolean gimp_operation_hsv_saturation_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationHsvSaturationLegacy, gimp_operation_hsv_saturation_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -39,18 +49,15 @@ G_DEFINE_TYPE (GimpOperationHsvSaturationLegacy, gimp_operation_hsv_saturation_l
static void
gimp_operation_hsv_saturation_legacy_class_init (GimpOperationHsvSaturationLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hsv-saturation-legacy",
"description", "GIMP saturation mode operation",
NULL);
- point_class->process = gimp_operation_hsv_saturation_legacy_process;
+ layer_mode_class->process = gimp_operation_hsv_saturation_legacy_process;
}
static void
@@ -58,7 +65,7 @@ gimp_operation_hsv_saturation_legacy_init (GimpOperationHsvSaturationLegacy *sel
{
}
-gboolean
+static gboolean
gimp_operation_hsv_saturation_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.h
index 71cc96e..d0127a4 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationHsvSaturationLegacyClass
};
-GType gimp_operation_hsv_saturation_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_hsv_saturation_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_hsv_saturation_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_HSV_SATURATION_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.c
b/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.c
index 5091dfa..3659a89 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.c
@@ -32,6 +32,16 @@
#include "gimpoperationhsvvaluelegacy.h"
+static gboolean gimp_operation_hsv_value_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationHsvValueLegacy, gimp_operation_hsv_value_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -39,18 +49,15 @@ G_DEFINE_TYPE (GimpOperationHsvValueLegacy, gimp_operation_hsv_value_legacy,
static void
gimp_operation_hsv_value_legacy_class_init (GimpOperationHsvValueLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:hsv-value-legacy",
"description", "GIMP value mode operation",
NULL);
- point_class->process = gimp_operation_hsv_value_legacy_process;
+ layer_mode_class->process = gimp_operation_hsv_value_legacy_process;
}
static void
@@ -58,7 +65,7 @@ gimp_operation_hsv_value_legacy_init (GimpOperationHsvValueLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_hsv_value_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.h
b/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.h
index 439c22f..bf119cf 100644
--- a/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationHsvValueLegacyClass
};
-GType gimp_operation_hsv_value_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_hsv_value_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_hsv_value_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_HSV_VALUE_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.c
b/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.c
index a696aca..88a1a31 100644
--- a/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationlightenonlylegacy.h"
+static gboolean gimp_operation_lighten_only_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationLightenOnlyLegacy, gimp_operation_lighten_only_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationLightenOnlyLegacy, gimp_operation_lighten_only_legac
static void
gimp_operation_lighten_only_legacy_class_init (GimpOperationLightenOnlyLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:lighten-only-legacy",
"description", "GIMP lighten only legacy operation",
NULL);
- point_class->process = gimp_operation_lighten_only_legacy_process;
+ layer_mode_class->process = gimp_operation_lighten_only_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_lighten_only_legacy_init (GimpOperationLightenOnlyLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_lighten_only_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.h
b/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.h
index d9570af..124de63 100644
--- a/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationlightenonlylegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationLightenOnlyLegacyClass
};
-GType gimp_operation_lighten_only_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_lighten_only_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_lighten_only_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_LIGHTEN_ONLY_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.c
b/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.c
index 74e59a0..b6bcdcf 100644
--- a/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationmultiplylegacy.h"
+static gboolean gimp_operation_multiply_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationMultiplyLegacy, gimp_operation_multiply_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationMultiplyLegacy, gimp_operation_multiply_legacy,
static void
gimp_operation_multiply_legacy_class_init (GimpOperationMultiplyLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:multiply-legacy",
"description", "GIMP multiply legacy operation",
NULL);
- point_class->process = gimp_operation_multiply_legacy_process;
+ layer_mode_class->process = gimp_operation_multiply_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_multiply_legacy_init (GimpOperationMultiplyLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_multiply_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.h
b/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.h
index 70779a5..7a47726 100644
--- a/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationmultiplylegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationMultiplyLegacyClass
};
-GType gimp_operation_multiply_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_multiply_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_multiply_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_MULTIPLY_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.c
index e8ed506..205ac8e 100644
--- a/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationscreenlegacy.h"
+static gboolean gimp_operation_screen_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationScreenLegacy, gimp_operation_screen_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationScreenLegacy, gimp_operation_screen_legacy,
static void
gimp_operation_screen_legacy_class_init (GimpOperationScreenLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:screen-legacy",
"description", "GIMP screen mode operation",
NULL);
- point_class->process = gimp_operation_screen_legacy_process;
+ layer_mode_class->process = gimp_operation_screen_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_screen_legacy_init (GimpOperationScreenLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_screen_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.h
index f8d0830..976a015 100644
--- a/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationscreenlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationScreenLegacyClass
};
-GType gimp_operation_screen_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_screen_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_screen_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_SCREEN_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c
index 4a65354..22eda93 100644
--- a/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationsoftlightlegacy.h"
+static gboolean gimp_operation_softlight_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationSoftlightLegacy, gimp_operation_softlight_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -52,11 +62,8 @@ static const gchar* reference_xml = "<?xml version='1.0' encoding='UTF-8'?>"
static void
gimp_operation_softlight_legacy_class_init (GimpOperationSoftlightLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:softlight-legacy",
@@ -65,7 +72,7 @@ gimp_operation_softlight_legacy_class_init (GimpOperationSoftlightLegacyClass *k
"reference-composition", reference_xml,
NULL);
- point_class->process = gimp_operation_softlight_legacy_process;
+ layer_mode_class->process = gimp_operation_softlight_legacy_process;
}
static void
@@ -73,7 +80,7 @@ gimp_operation_softlight_legacy_init (GimpOperationSoftlightLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_softlight_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.h
index 77516bb..687ade2 100644
--- a/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationSoftlightLegacyClass
};
-GType gimp_operation_softlight_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_softlight_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_softlight_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_SOFTLIGHT_LEGACY_H__ */
diff --git a/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.c
b/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.c
index 5e11adf..32505b1 100644
--- a/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.c
+++ b/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.c
@@ -28,6 +28,16 @@
#include "gimpoperationsubtractlegacy.h"
+static gboolean gimp_operation_subtract_legacy_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationSubtractLegacy, gimp_operation_subtract_legacy,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationSubtractLegacy, gimp_operation_subtract_legacy,
static void
gimp_operation_subtract_legacy_class_init (GimpOperationSubtractLegacyClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:subtract-legacy",
"description", "GIMP subtract mode operation",
NULL);
- point_class->process = gimp_operation_subtract_legacy_process;
+ layer_mode_class->process = gimp_operation_subtract_legacy_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_subtract_legacy_init (GimpOperationSubtractLegacy *self)
{
}
-gboolean
+static gboolean
gimp_operation_subtract_legacy_process (GeglOperation *op,
void *in_p,
void *layer_p,
diff --git a/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.h
b/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.h
index ba1021b..9223e82 100644
--- a/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.h
+++ b/app/operations/layer-modes-legacy/gimpoperationsubtractlegacy.h
@@ -47,16 +47,7 @@ struct _GimpOperationSubtractLegacyClass
};
-GType gimp_operation_subtract_legacy_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_subtract_legacy_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_subtract_legacy_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_SUBTRACT_LEGACY_H__ */
diff --git a/app/operations/layer-modes/Makefile.am b/app/operations/layer-modes/Makefile.am
index f7bedd2..9bd64b9 100644
--- a/app/operations/layer-modes/Makefile.am
+++ b/app/operations/layer-modes/Makefile.am
@@ -9,7 +9,6 @@ AM_CPPFLAGS = \
$(CAIRO_CFLAGS) \
$(GEGL_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
- $(SSE2_EXTRA_CFLAGS) \
-I$(includedir)
noinst_LIBRARIES = \
@@ -19,30 +18,36 @@ noinst_LIBRARIES = \
libapplayermodes.a
libapplayermodes_generic_a_sources = \
- gimp-layer-modes.c \
- gimp-layer-modes.h \
+ gimp-layer-modes.c \
+ gimp-layer-modes.h \
\
- gimpoperationlayermode.c \
- gimpoperationlayermode.h \
+ gimpoperationlayermode.c \
+ gimpoperationlayermode.h \
+ gimpoperationlayermode-blend.c \
+ gimpoperationlayermode-blend.h \
+ gimpoperationlayermode-composite.c \
+ gimpoperationlayermode-composite.h \
\
- gimpoperationantierase.c \
- gimpoperationantierase.h \
- gimpoperationbehind.c \
- gimpoperationbehind.h \
- gimpoperationdissolve.c \
- gimpoperationdissolve.h \
- gimpoperationerase.c \
- gimpoperationerase.h \
- gimpoperationmerge.c \
- gimpoperationmerge.h \
- gimpoperationnormal.c \
- gimpoperationnormal.h \
- gimpoperationreplace.c \
- gimpoperationreplace.h \
- gimpoperationsplit.c \
+ gimpoperationantierase.c \
+ gimpoperationantierase.h \
+ gimpoperationbehind.c \
+ gimpoperationbehind.h \
+ gimpoperationdissolve.c \
+ gimpoperationdissolve.h \
+ gimpoperationerase.c \
+ gimpoperationerase.h \
+ gimpoperationmerge.c \
+ gimpoperationmerge.h \
+ gimpoperationnormal.c \
+ gimpoperationnormal.h \
+ gimpoperationreplace.c \
+ gimpoperationreplace.h \
+ gimpoperationsplit.c \
gimpoperationsplit.h
libapplayermodes_sse2_a_sources = \
+ gimpoperationlayermode-composite-sse2.c \
+ \
gimpoperationnormal-sse2.c
libapplayermodes_sse4_a_sources = \
diff --git a/app/operations/layer-modes/gimp-layer-modes.c b/app/operations/layer-modes/gimp-layer-modes.c
index efaee4d..1e7eade 100644
--- a/app/operations/layer-modes/gimp-layer-modes.c
+++ b/app/operations/layer-modes/gimp-layer-modes.c
@@ -25,33 +25,8 @@
#include "../operations-types.h"
-#include "operations/layer-modes-legacy/gimpoperationadditionlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationburnlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationdarkenonlylegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationdifferencelegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationdividelegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationdodgelegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationgrainextractlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationgrainmergelegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationhardlightlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationhslcolorlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationhsvhuelegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationhsvsaturationlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationhsvvaluelegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationlightenonlylegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationmultiplylegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationscreenlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationsoftlightlegacy.h"
-#include "operations/layer-modes-legacy/gimpoperationsubtractlegacy.h"
-
-#include "gimpoperationantierase.h"
-#include "gimpoperationbehind.h"
-#include "gimpoperationdissolve.h"
-#include "gimpoperationerase.h"
-#include "gimpoperationmerge.h"
-#include "gimpoperationnormal.h"
-#include "gimpoperationreplace.h"
-#include "gimpoperationsplit.h"
+#include "gimpoperationlayermode.h"
+#include "gimpoperationlayermode-blend.h"
#include "gimp-layer-modes.h"
@@ -62,14 +37,13 @@ struct _GimpLayerModeInfo
{
GimpLayerMode layer_mode;
const gchar *op_name;
- GimpLayerModeFunc function;
+ GimpLayerModeBlendFunc blend_function;
GimpLayerModeFlags flags;
GimpLayerModeContext context;
GimpLayerCompositeMode paint_composite_mode;
GimpLayerCompositeMode composite_mode;
GimpLayerColorSpace composite_space;
GimpLayerColorSpace blend_space;
- GimpLayerCompositeRegion affected_region;
};
@@ -80,7 +54,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_NORMAL_LEGACY,
.op_name = "gimp:normal",
- .function = gimp_operation_normal_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -94,19 +67,16 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DISSOLVE,
.op_name = "gimp:dissolve",
- .function = gimp_operation_dissolve_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
- .composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
- .affected_region = GIMP_LAYER_COMPOSITE_REGION_SOURCE
+ .composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER
},
{ GIMP_LAYER_MODE_BEHIND_LEGACY,
.op_name = "gimp:behind",
- .function = gimp_operation_behind_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -121,7 +91,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_MULTIPLY_LEGACY,
.op_name = "gimp:multiply-legacy",
- .function = gimp_operation_multiply_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -136,7 +105,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SCREEN_LEGACY,
.op_name = "gimp:screen-legacy",
- .function = gimp_operation_screen_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -151,7 +119,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_OVERLAY_LEGACY,
.op_name = "gimp:softlight-legacy",
- .function = gimp_operation_softlight_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -166,7 +133,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
.op_name = "gimp:difference-legacy",
- .function = gimp_operation_difference_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -181,7 +147,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_ADDITION_LEGACY,
.op_name = "gimp:addition-legacy",
- .function = gimp_operation_addition_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -196,7 +161,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SUBTRACT_LEGACY,
.op_name = "gimp:subtract-legacy",
- .function = gimp_operation_subtract_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -211,7 +175,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY,
.op_name = "gimp:darken-only-legacy",
- .function = gimp_operation_darken_only_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -226,7 +189,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY,
.op_name = "gimp:lighten-only-legacy",
- .function = gimp_operation_lighten_only_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -241,7 +203,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSV_HUE_LEGACY,
.op_name = "gimp:hsv-hue-legacy",
- .function = gimp_operation_hsv_hue_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -256,7 +217,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSV_SATURATION_LEGACY,
.op_name = "gimp:hsv-saturation-legacy",
- .function = gimp_operation_hsv_saturation_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -271,7 +231,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSL_COLOR_LEGACY,
.op_name = "gimp:hsl-color-legacy",
- .function = gimp_operation_hsl_color_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -286,7 +245,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSV_VALUE_LEGACY,
.op_name = "gimp:hsv-value-legacy",
- .function = gimp_operation_hsv_value_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -301,7 +259,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DIVIDE_LEGACY,
.op_name = "gimp:divide-legacy",
- .function = gimp_operation_divide_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -316,7 +273,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DODGE_LEGACY,
.op_name = "gimp:dodge-legacy",
- .function = gimp_operation_dodge_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -331,7 +287,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_BURN_LEGACY,
.op_name = "gimp:burn-legacy",
- .function = gimp_operation_burn_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -346,7 +301,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
.op_name = "gimp:hardlight-legacy",
- .function = gimp_operation_hardlight_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -361,7 +315,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
.op_name = "gimp:softlight-legacy",
- .function = gimp_operation_softlight_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -376,7 +329,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
.op_name = "gimp:grain-extract-legacy",
- .function = gimp_operation_grain_extract_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -391,7 +343,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY,
.op_name = "gimp:grain-merge-legacy",
- .function = gimp_operation_grain_merge_legacy_process,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -406,7 +357,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_COLOR_ERASE_LEGACY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
.flags = GIMP_LAYER_MODE_FLAG_LEGACY |
GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
@@ -422,7 +372,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_OVERLAY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_overlay,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -433,7 +383,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LCH_HUE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_lch_hue,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -445,7 +395,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LCH_CHROMA,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_lch_chroma,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -457,7 +407,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LCH_COLOR,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_lch_color,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -469,7 +419,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LCH_LIGHTNESS,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_lch_lightness,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -481,7 +431,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_NORMAL,
.op_name = "gimp:normal",
- .function = gimp_operation_normal_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -492,7 +441,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_BEHIND,
.op_name = "gimp:behind",
- .function = gimp_operation_behind_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_PAINT |
GIMP_LAYER_MODE_CONTEXT_FADE,
@@ -504,7 +452,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_MULTIPLY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_multiply,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -515,7 +463,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SCREEN,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_screen,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -526,7 +474,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DIFFERENCE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_difference,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -537,7 +485,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_ADDITION,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_addition,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -548,7 +496,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SUBTRACT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_subtract,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -559,7 +507,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DARKEN_ONLY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_darken_only,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -571,7 +519,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LIGHTEN_ONLY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_lighten_only,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -583,7 +531,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSV_HUE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_hsv_hue,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -595,7 +543,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSV_SATURATION,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_hsv_saturation,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -607,7 +555,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSL_COLOR,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_hsl_color,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -619,7 +567,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HSV_VALUE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_hsv_value,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -631,7 +579,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DIVIDE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_divide,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -642,7 +590,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_DODGE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_dodge,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -653,7 +601,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_BURN,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_burn,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -664,7 +612,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HARDLIGHT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_hardlight,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -675,7 +623,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SOFTLIGHT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_softlight,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -686,7 +634,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_GRAIN_EXTRACT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_grain_extract,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -697,7 +645,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_GRAIN_MERGE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_grain_merge,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -708,7 +656,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_VIVID_LIGHT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_vivid_light,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -719,7 +667,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_PIN_LIGHT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_pin_light,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -730,7 +678,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LINEAR_LIGHT,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_linear_light,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -741,7 +689,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_HARD_MIX,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_hard_mix,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -752,7 +700,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_EXCLUSION,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_exclusion,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -763,7 +711,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LINEAR_BURN,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_linear_burn,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -774,7 +722,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_luma_darken_only,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -785,7 +733,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_luma_lighten_only,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -796,7 +744,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_LUMINANCE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_luminance,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -808,7 +756,7 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_COLOR_ERASE,
.op_name = "gimp:layer-mode",
- .function = gimp_operation_layer_mode_process_pixels,
+ .blend_function = gimp_operation_layer_mode_blend_color_erase,
.flags = GIMP_LAYER_MODE_FLAG_SUBTRACTIVE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP,
@@ -820,7 +768,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_ERASE,
.op_name = "gimp:erase",
- .function = gimp_operation_erase_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_SUBTRACTIVE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
@@ -832,7 +779,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_MERGE,
.op_name = "gimp:merge",
- .function = gimp_operation_merge_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_ALL,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
@@ -843,7 +789,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_SPLIT,
.op_name = "gimp:split",
- .function = gimp_operation_split_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_SUBTRACTIVE,
@@ -855,7 +800,6 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_PASS_THROUGH,
.op_name = "gimp:replace",
- .function = gimp_operation_replace_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_MODE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_GROUP,
@@ -866,25 +810,21 @@ static const GimpLayerModeInfo layer_mode_infos[] =
{ GIMP_LAYER_MODE_REPLACE,
.op_name = "gimp:replace",
- .function = gimp_operation_replace_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_FADE,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
.composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
- .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
- .affected_region = GIMP_LAYER_COMPOSITE_REGION_DESTINATION
+ .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR
},
{ GIMP_LAYER_MODE_ANTI_ERASE,
.op_name = "gimp:anti-erase",
- .function = gimp_operation_anti_erase_process,
.flags = GIMP_LAYER_MODE_FLAG_BLEND_SPACE_IMMUTABLE |
GIMP_LAYER_MODE_FLAG_COMPOSITE_SPACE_IMMUTABLE,
.context = GIMP_LAYER_MODE_CONTEXT_FADE,
.paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
- .composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER,
- .affected_region = GIMP_LAYER_COMPOSITE_REGION_SOURCE
+ .composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER
}
};
@@ -1172,7 +1112,7 @@ gimp_layer_modes_init (void)
static const GimpLayerModeInfo *
gimp_layer_mode_info (GimpLayerMode mode)
{
- g_return_val_if_fail (mode < G_N_ELEMENTS (layer_mode_infos),
+ g_return_val_if_fail (mode >= 0 && mode < G_N_ELEMENTS (layer_mode_infos),
&layer_mode_infos[0]);
return &layer_mode_infos[mode];
@@ -1280,18 +1220,53 @@ gimp_layer_mode_get_paint_composite_mode (GimpLayerMode mode)
const gchar *
gimp_layer_mode_get_operation (GimpLayerMode mode)
{
- return "gimp:layer-mode";
+ const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
+
+ if (! info)
+ return "gimp:layer-mode";
+
+ return info->op_name;
}
GimpLayerModeFunc
gimp_layer_mode_get_function (GimpLayerMode mode)
{
+ const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
+ static GimpLayerModeFunc funcs[G_N_ELEMENTS (layer_mode_infos)];
+
+ if (! info)
+ info = layer_mode_infos;
+
+ mode = info - layer_mode_infos;
+
+ if (! funcs[mode])
+ {
+ GeglNode *node;
+ GeglOperation *operation;
+
+ node = gegl_node_new_child (NULL,
+ "operation", info->op_name,
+ NULL);
+
+ operation = gegl_node_get_gegl_operation (node);
+
+ funcs[mode] = GIMP_OPERATION_LAYER_MODE_GET_CLASS (operation)->process;
+
+ g_object_unref (node);
+ }
+
+ return funcs[mode];
+}
+
+GimpLayerModeBlendFunc
+gimp_layer_mode_get_blend_function (GimpLayerMode mode)
+{
const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
if (! info)
- return gimp_operation_layer_mode_process_pixels;
+ return NULL;
- return info->function;
+ return info->blend_function;
}
GimpLayerModeContext
@@ -1460,17 +1435,6 @@ gimp_layer_mode_get_format (GimpLayerMode mode,
}
GimpLayerCompositeRegion
-gimp_layer_mode_get_affected_region (GimpLayerMode mode)
-{
- const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
-
- if (! info)
- return GIMP_LAYER_COMPOSITE_REGION_INTERSECTION;
-
- return info->affected_region;
-}
-
-GimpLayerCompositeRegion
gimp_layer_mode_get_included_region (GimpLayerMode mode,
GimpLayerCompositeMode composite_mode)
{
diff --git a/app/operations/layer-modes/gimp-layer-modes.h b/app/operations/layer-modes/gimp-layer-modes.h
index a8463cd..ef80605 100644
--- a/app/operations/layer-modes/gimp-layer-modes.h
+++ b/app/operations/layer-modes/gimp-layer-modes.h
@@ -41,6 +41,7 @@ GimpLayerCompositeMode gimp_layer_mode_get_paint_composite_mode (GimpLayer
const gchar * gimp_layer_mode_get_operation (GimpLayerMode mode);
GimpLayerModeFunc gimp_layer_mode_get_function (GimpLayerMode mode);
+GimpLayerModeBlendFunc gimp_layer_mode_get_blend_function (GimpLayerMode mode);
GimpLayerModeContext gimp_layer_mode_get_context (GimpLayerMode mode);
@@ -62,8 +63,6 @@ const Babl * gimp_layer_mode_get_format (GimpLayer
GimpLayerColorSpace blend_space,
const Babl
*preferred_format);
-GimpLayerCompositeRegion gimp_layer_mode_get_affected_region (GimpLayerMode mode);
-
GimpLayerCompositeRegion gimp_layer_mode_get_included_region (GimpLayerMode mode,
GimpLayerCompositeMode
composite_mode);
diff --git a/app/operations/layer-modes/gimpoperationantierase.c
b/app/operations/layer-modes/gimpoperationantierase.c
index 572b800..b7a2d2d 100644
--- a/app/operations/layer-modes/gimpoperationantierase.c
+++ b/app/operations/layer-modes/gimpoperationantierase.c
@@ -28,7 +28,16 @@
#include "gimpoperationantierase.h"
-static GimpLayerCompositeRegion gimp_operation_anti_erase_get_affected_region (GimpOperationLayerMode
*layer_mode);
+
+static gboolean gimp_operation_anti_erase_process (GeglOperation *op,
+ void *in,
+ void
*layer,
+ void
*mask,
+ void *out,
+ glong
samples,
+ const GeglRectangle *roi,
+ gint
level);
+static GimpLayerCompositeRegion gimp_operation_anti_erase_get_affected_region (GimpOperationLayerMode
*layer_mode);
G_DEFINE_TYPE (GimpOperationAntiErase, gimp_operation_anti_erase,
@@ -38,21 +47,15 @@ G_DEFINE_TYPE (GimpOperationAntiErase, gimp_operation_anti_erase,
static void
gimp_operation_anti_erase_class_init (GimpOperationAntiEraseClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
- GimpOperationLayerModeClass *layer_mode_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
- layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:anti-erase",
"description", "GIMP anti erase mode operation",
NULL);
- point_class->process = gimp_operation_anti_erase_process;
-
+ layer_mode_class->process = gimp_operation_anti_erase_process;
layer_mode_class->get_affected_region = gimp_operation_anti_erase_get_affected_region;
}
@@ -61,7 +64,7 @@ gimp_operation_anti_erase_init (GimpOperationAntiErase *self)
{
}
-gboolean
+static gboolean
gimp_operation_anti_erase_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -79,7 +82,7 @@ gimp_operation_anti_erase_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
diff --git a/app/operations/layer-modes/gimpoperationantierase.h
b/app/operations/layer-modes/gimpoperationantierase.h
index 8e275fe..010dc94 100644
--- a/app/operations/layer-modes/gimpoperationantierase.h
+++ b/app/operations/layer-modes/gimpoperationantierase.h
@@ -47,16 +47,7 @@ struct _GimpOperationAntiEraseClass
};
-GType gimp_operation_anti_erase_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_anti_erase_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_anti_erase_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_ANTI_ERASE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationbehind.c
b/app/operations/layer-modes/gimpoperationbehind.c
index 8ecb61a..82f0faf 100644
--- a/app/operations/layer-modes/gimpoperationbehind.c
+++ b/app/operations/layer-modes/gimpoperationbehind.c
@@ -28,6 +28,17 @@
#include "gimpoperationbehind.h"
+
+static gboolean gimp_operation_behind_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationBehind, gimp_operation_behind,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +46,15 @@ G_DEFINE_TYPE (GimpOperationBehind, gimp_operation_behind,
static void
gimp_operation_behind_class_init (GimpOperationBehindClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:behind",
"description", "GIMP behind mode operation",
NULL);
- point_class->process = gimp_operation_behind_process;
+ layer_mode_class->process = gimp_operation_behind_process;
}
static void
@@ -54,7 +62,7 @@ gimp_operation_behind_init (GimpOperationBehind *self)
{
}
-gboolean
+static gboolean
gimp_operation_behind_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -72,7 +80,7 @@ gimp_operation_behind_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
diff --git a/app/operations/layer-modes/gimpoperationbehind.h
b/app/operations/layer-modes/gimpoperationbehind.h
index 17b4f64..d72e679 100644
--- a/app/operations/layer-modes/gimpoperationbehind.h
+++ b/app/operations/layer-modes/gimpoperationbehind.h
@@ -49,14 +49,5 @@ struct _GimpOperationBehindClass
GType gimp_operation_behind_get_type (void) G_GNUC_CONST;
-gboolean gimp_operation_behind_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
-
#endif /* __GIMP_OPERATION_BEHIND_H__ */
diff --git a/app/operations/layer-modes/gimpoperationdissolve.c
b/app/operations/layer-modes/gimpoperationdissolve.c
index 993c821..4d7b2f4 100644
--- a/app/operations/layer-modes/gimpoperationdissolve.c
+++ b/app/operations/layer-modes/gimpoperationdissolve.c
@@ -32,7 +32,15 @@
#define RANDOM_TABLE_SIZE 4096
-static GimpLayerCompositeRegion gimp_operation_dissolve_get_affected_region (GimpOperationLayerMode
*layer_mode);
+static gboolean gimp_operation_dissolve_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong
samples,
+ const GeglRectangle
*result,
+ gint
level);
+static GimpLayerCompositeRegion gimp_operation_dissolve_get_affected_region (GimpOperationLayerMode
*layer_mode);
G_DEFINE_TYPE (GimpOperationDissolve, gimp_operation_dissolve,
@@ -45,15 +53,10 @@ static gint32 random_table[RANDOM_TABLE_SIZE];
static void
gimp_operation_dissolve_class_init (GimpOperationDissolveClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_composer_class;
- GimpOperationLayerModeClass *layer_mode_class;
- GRand *gr;
- gint i;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_composer_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
- layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
+ GRand *gr;
+ gint i;
gegl_operation_class_set_keys (operation_class,
"name", "gimp:dissolve",
@@ -61,8 +64,7 @@ gimp_operation_dissolve_class_init (GimpOperationDissolveClass *klass)
"categories", "compositors",
NULL);
- point_composer_class->process = gimp_operation_dissolve_process;
-
+ layer_mode_class->process = gimp_operation_dissolve_process;
layer_mode_class->get_affected_region = gimp_operation_dissolve_get_affected_region;
/* generate a table of random seeds */
@@ -78,7 +80,7 @@ gimp_operation_dissolve_init (GimpOperationDissolve *self)
{
}
-gboolean
+static gboolean
gimp_operation_dissolve_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -118,8 +120,8 @@ gimp_operation_dissolve_process (GeglOperation *op,
out[1] = in[1];
out[2] = in[2];
- if (layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
- layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_SRC_ATOP)
+ if (layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
+ layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_SRC_ATOP)
{
out[3] = in[3];
}
@@ -134,8 +136,8 @@ gimp_operation_dissolve_process (GeglOperation *op,
out[1] = layer[1];
out[2] = layer[2];
- if (layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
- layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_DST_ATOP)
+ if (layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
+ layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_DST_ATOP)
{
out[3] = 1.0f;
}
@@ -159,7 +161,7 @@ gimp_operation_dissolve_process (GeglOperation *op,
return TRUE;
}
-GimpLayerCompositeRegion
+static GimpLayerCompositeRegion
gimp_operation_dissolve_get_affected_region (GimpOperationLayerMode *layer_mode)
{
return GIMP_LAYER_COMPOSITE_REGION_SOURCE;
diff --git a/app/operations/layer-modes/gimpoperationdissolve.h
b/app/operations/layer-modes/gimpoperationdissolve.h
index 8b89ca1..7dea99a 100644
--- a/app/operations/layer-modes/gimpoperationdissolve.h
+++ b/app/operations/layer-modes/gimpoperationdissolve.h
@@ -47,16 +47,7 @@ struct _GimpOperationDissolve
};
-GType gimp_operation_dissolve_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_dissolve_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *result,
- gint level);
+GType gimp_operation_dissolve_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_DISSOLVE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationerase.c b/app/operations/layer-modes/gimpoperationerase.c
index 1cc1ba8..ff0aa37 100644
--- a/app/operations/layer-modes/gimpoperationerase.c
+++ b/app/operations/layer-modes/gimpoperationerase.c
@@ -28,6 +28,16 @@
#include "gimpoperationerase.h"
+static gboolean gimp_operation_erase_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationErase, gimp_operation_erase,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationErase, gimp_operation_erase,
static void
gimp_operation_erase_class_init (GimpOperationEraseClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:erase",
"description", "GIMP erase mode operation",
NULL);
- point_class->process = gimp_operation_erase_process;
+ layer_mode_class->process = gimp_operation_erase_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_erase_init (GimpOperationErase *self)
{
}
-gboolean
+static gboolean
gimp_operation_erase_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -72,7 +79,7 @@ gimp_operation_erase_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
while (samples--)
diff --git a/app/operations/layer-modes/gimpoperationerase.h b/app/operations/layer-modes/gimpoperationerase.h
index 0d15ab1..5f9bb4d 100644
--- a/app/operations/layer-modes/gimpoperationerase.h
+++ b/app/operations/layer-modes/gimpoperationerase.h
@@ -47,16 +47,7 @@ struct _GimpOperationEraseClass
};
-GType gimp_operation_erase_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_erase_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_erase_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_ERASE_MODE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationlayermode-blend.c
b/app/operations/layer-modes/gimpoperationlayermode-blend.c
new file mode 100644
index 0000000..dd01115
--- /dev/null
+++ b/app/operations/layer-modes/gimpoperationlayermode-blend.c
@@ -0,0 +1,1168 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationlayermode-blend.c
+ * Copyright (C) 2017 Michael Natterer <mitch gimp org>
+ * 2017 Øyvind Kolås <pippin gimp org>
+ * 2017 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl-plugin.h>
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
+
+#include "../operations-types.h"
+
+#include "gimpoperationlayermode-blend.h"
+
+
+/* non-subtractive blending functions. these functions must set comp[ALPHA]
+ * to the same value as layer[ALPHA]. when in[ALPHA] or layer[ALPHA] are
+ * zero, the value of comp[RED..BLUE] is unconstrained (in particular, it may
+ * be NaN).
+ */
+
+
+void /* aka linear_dodge */
+gimp_operation_layer_mode_blend_addition (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] + layer[c];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_burn (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val = 1.0f - (1.0f - in[c]) / layer[c];
+
+ /* The CLAMP macro is deliberately inlined and written
+ * to map comp == NAN (0 / 0) -> 1
+ */
+ comp[c] = val < 0 ? 0.0f : val < 1.0f ? val : 1.0f;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_darken_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = MIN (in[c], layer[c]);
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_difference (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ comp[c] = in[c] - layer[c];
+
+ if (comp[c] < 0)
+ comp[c] = -comp[c];
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_divide (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val = in[c] / layer[c];
+
+ /* make infinities(or NaN) correspond to a high number,
+ * to get more predictable math, ideally higher than 5.0
+ * but it seems like some babl conversions might be
+ * acting up then
+ */
+ if (!(val > -42949672.0f && val < 5.0f))
+ val = 5.0f;
+
+ comp[c] = val;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_dodge (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val = in[c] / (1.0f - layer[c]);
+
+ val = MIN (val, 1.0f);
+
+ comp[c] = val;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_exclusion (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ comp[c] = 0.5f - 2.0f * (in[c] - 0.5f) * (layer[c] - 0.5f);
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_grain_extract (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] - layer[c] + 0.5f;
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_grain_merge (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] + layer[c] - 0.5f;
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_hard_mix (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ comp[c] = in[c] + layer[c] < 1.0f ? 0.0f : 1.0f;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_hardlight (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val;
+
+ if (layer[c] > 0.5f)
+ {
+ val = (1.0f - in[c]) * (1.0f - (layer[c] - 0.5f) * 2.0f);
+ val = MIN (1.0f - val, 1.0f);
+ }
+ else
+ {
+ val = in[c] * (layer[c] * 2.0f);
+ val = MIN (val, 1.0f);
+ }
+
+ comp[c] = val;
+ }
+ }
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_hsl_color (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gfloat dest_min, dest_max, dest_l;
+ gfloat src_min, src_max, src_l;
+
+ dest_min = MIN (in[0], in[1]);
+ dest_min = MIN (dest_min, in[2]);
+ dest_max = MAX (in[0], in[1]);
+ dest_max = MAX (dest_max, in[2]);
+ dest_l = (dest_min + dest_max) / 2.0f;
+
+ src_min = MIN (layer[0], layer[1]);
+ src_min = MIN (src_min, layer[2]);
+ src_max = MAX (layer[0], layer[1]);
+ src_max = MAX (src_max, layer[2]);
+ src_l = (src_min + src_max) / 2.0f;
+
+ if (src_l != 0.0f && src_l != 1.0f)
+ {
+ gboolean dest_high;
+ gboolean src_high;
+ gfloat ratio;
+ gfloat offset;
+ gint c;
+
+ dest_high = dest_l > 0.5f;
+ src_high = src_l > 0.5f;
+
+ dest_l = MIN (dest_l, 1.0f - dest_l);
+ src_l = MIN (src_l, 1.0f - src_l);
+
+ ratio = dest_l / src_l;
+
+ offset = 0.0f;
+ if (dest_high) offset += 1.0f - 2.0f * dest_l;
+ if (src_high) offset += 2.0f * dest_l - ratio;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = layer[c] * ratio + offset;
+ }
+ else
+ {
+ comp[RED] = dest_l;
+ comp[GREEN] = dest_l;
+ comp[BLUE] = dest_l;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_hsv_hue (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gfloat src_min, src_max, src_delta;
+ gfloat dest_min, dest_max, dest_delta, dest_s;
+
+ src_min = MIN (layer[0], layer[1]);
+ src_min = MIN (src_min, layer[2]);
+ src_max = MAX (layer[0], layer[1]);
+ src_max = MAX (src_max, layer[2]);
+ src_delta = src_max - src_min;
+
+ if (src_delta != 0.0f)
+ {
+ gfloat ratio;
+ gfloat offset;
+ gint c;
+
+ dest_min = MIN (in[0], in[1]);
+ dest_min = MIN (dest_min, in[2]);
+ dest_max = MAX (in[0], in[1]);
+ dest_max = MAX (dest_max, in[2]);
+ dest_delta = dest_max - dest_min;
+ dest_s = dest_max ? dest_delta / dest_max : 0.0f;
+
+ ratio = dest_s * dest_max / src_delta;
+ offset = dest_max - src_max * ratio;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = layer[c] * ratio + offset;
+ }
+ else
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c];
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_hsv_saturation (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gfloat src_min, src_max, src_delta, src_s;
+ gfloat dest_min, dest_max, dest_delta;
+
+ dest_min = MIN (in[0], in[1]);
+ dest_min = MIN (dest_min, in[2]);
+ dest_max = MAX (in[0], in[1]);
+ dest_max = MAX (dest_max, in[2]);
+ dest_delta = dest_max - dest_min;
+
+ if (dest_delta != 0.0f)
+ {
+ gfloat ratio;
+ gfloat offset;
+ gint c;
+
+ src_min = MIN (layer[0], layer[1]);
+ src_min = MIN (src_min, layer[2]);
+ src_max = MAX (layer[0], layer[1]);
+ src_max = MAX (src_max, layer[2]);
+ src_delta = src_max - src_min;
+ src_s = src_max ? src_delta / src_max : 0.0f;
+
+ ratio = src_s * dest_max / dest_delta;
+ offset = (1.0f - ratio) * dest_max;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] * ratio + offset;
+ }
+ else
+ {
+ comp[RED] = dest_max;
+ comp[GREEN] = dest_max;
+ comp[BLUE] = dest_max;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_hsv_value (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gfloat dest_v;
+ gfloat src_v;
+
+ dest_v = MAX (in[0], in[1]);
+ dest_v = MAX (dest_v, in[2]);
+
+ src_v = MAX (layer[0], layer[1]);
+ src_v = MAX (src_v, layer[2]);
+
+ if (dest_v != 0.0f)
+ {
+ gfloat ratio = src_v / dest_v;
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] * ratio;
+ }
+ else
+ {
+ comp[RED] = src_v;
+ comp[GREEN] = src_v;
+ comp[BLUE] = src_v;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_lch_chroma (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gfloat A1 = in[1];
+ gfloat B1 = in[2];
+ gfloat c1 = hypotf (A1, B1);
+
+ if (c1 != 0.0f)
+ {
+ gfloat A2 = layer[1];
+ gfloat B2 = layer[2];
+ gfloat c2 = hypotf (A2, B2);
+ gfloat A = c2 * A1 / c1;
+ gfloat B = c2 * B1 / c1;
+
+ comp[0] = in[0];
+ comp[1] = A;
+ comp[2] = B;
+ }
+ else
+ {
+ comp[0] = in[0];
+ comp[1] = in[1];
+ comp[2] = in[2];
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_lch_color (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ comp[0] = in[0];
+ comp[1] = layer[1];
+ comp[2] = layer[2];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_lch_hue (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gfloat A2 = layer[1];
+ gfloat B2 = layer[2];
+ gfloat c2 = hypotf (A2, B2);
+
+ if (c2 > 0.1f)
+ {
+ gfloat A1 = in[1];
+ gfloat B1 = in[2];
+ gfloat c1 = hypotf (A1, B1);
+ gfloat A = c1 * A2 / c2;
+ gfloat B = c1 * B2 / c2;
+
+ comp[0] = in[0];
+ comp[1] = A;
+ comp[2] = B;
+ }
+ else
+ {
+ comp[0] = in[0];
+ comp[1] = in[1];
+ comp[2] = in[2];
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_lch_lightness (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ comp[0] = layer[0];
+ comp[1] = in[1];
+ comp[2] = in[2];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_lighten_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = MAX (in[c], layer[c]);
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_linear_burn (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] + layer[c] - 1.0f;
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+/* added according to:
+ http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html */
+void
+gimp_operation_layer_mode_blend_linear_light (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val;
+
+ if (layer[c] <= 0.5f)
+ {
+ val = in[c] + 2.0 * layer[c] - 1.0f;
+ }
+ else
+ {
+ val = in[c] + 2.0 * (layer[c] - 0.5f);
+ }
+ comp[c] = val;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_luma_darken_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+ gfloat dest_luminance =
+ GIMP_RGB_LUMINANCE(in[0], in[1], in[2]);
+ gfloat src_luminance =
+ GIMP_RGB_LUMINANCE(layer[0], layer[1], layer[2]);
+
+ if (dest_luminance <= src_luminance)
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c];
+ else
+ for (c = 0; c < 3; c++)
+ comp[c] = layer[c];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_luma_lighten_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+ gfloat dest_luminance =
+ GIMP_RGB_LUMINANCE(in[0], in[1], in[2]);
+ gfloat src_luminance =
+ GIMP_RGB_LUMINANCE(layer[0], layer[1], layer[2]);
+
+ if (dest_luminance >= src_luminance)
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c];
+ else
+ for (c = 0; c < 3; c++)
+ comp[c] = layer[c];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_luminance (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ gfloat layer_Y[samples], *layer_Y_p;
+ gfloat in_Y[samples], *in_Y_p;
+
+ babl_process (babl_fish ("RGBA gfloat", "Y gfloat"), layer, layer_Y, samples);
+ babl_process (babl_fish ("RGBA gfloat", "Y gfloat"), in, in_Y, samples);
+
+ layer_Y_p = &layer_Y[0];
+ in_Y_p = &in_Y[0];
+
+ while (samples--)
+ {
+ if (layer[ALPHA] != 0.0f && in[ALPHA] != 0.0f)
+ {
+ gfloat ratio = layer_Y_p[0] / MAX(in_Y_p[0], 0.0000000000000000001);
+ gint c;
+ for (c = 0; c < 3; c ++)
+ comp[c] = in[c] * ratio;
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ in += 4;
+ layer += 4;
+ in_Y_p ++;
+ layer_Y_p ++;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_multiply (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] * layer[c];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_overlay (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val;
+
+ if (in[c] < 0.5f)
+ {
+ val = 2.0f * in[c] * layer[c];
+ }
+ else
+ {
+ val = 1.0f - 2.0f * (1.0f - layer[c]) * (1.0f - in[c]);
+ }
+
+ comp[c] = val;
+ }
+ }
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+/* added according to:
+ http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html */
+void
+gimp_operation_layer_mode_blend_pin_light (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val;
+
+ if (layer[c] > 0.5f)
+ {
+ val = MAX(in[c], 2 * (layer[c] - 0.5));
+ }
+ else
+ {
+ val = MIN(in[c], 2 * layer[c]);
+ }
+ comp[c] = val;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_screen (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = 1.0f - (1.0f - in[c]) * (1.0f - layer[c]);
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_softlight (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat multiply = in[c] * layer[c];
+ gfloat screen = 1.0f - (1.0f - in[c]) * (1.0f - layer[c]);
+ gfloat val = (1.0f - in[c]) * multiply + in[c] * screen;
+
+ comp[c] = val;
+ }
+ }
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+void
+gimp_operation_layer_mode_blend_subtract (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = in[c] - layer[c];
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+/* added according to:
+ http://www.simplefilter.de/en/basics/mixmods.html */
+void
+gimp_operation_layer_mode_blend_vivid_light (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ gint c;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat val;
+
+ if (layer[c] <= 0.5f)
+ {
+ val = 1.0f - (1.0f - in[c]) / (2.0f * (layer[c]));
+ }
+ else
+ {
+ val = in[c] / (2.0f * (1.0f - layer[c]));
+ }
+ val = MIN (val, 1.0f);
+
+ comp[c] = val;
+ }
+ }
+
+ comp[ALPHA] = layer[ALPHA];
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
+
+
+/* subtractive blending functions. these functions must set comp[ALPHA] to
+ * the modified alpha of the overlapping content, as a fraction of the
+ * original overlapping content (i.e., an alpha of 1.0 specifies that no
+ * content is subtracted.) when in[ALPHA] or layer[ALPHA] are zero, the value
+ * of comp[RED..BLUE] is unconstrained (in particular, it may be NaN).
+ */
+
+
+void
+gimp_operation_layer_mode_blend_color_erase (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples)
+{
+ while (samples--)
+ {
+ if (in[ALPHA] != 0.0f && layer[ALPHA] != 0.0f)
+ {
+ const gfloat *color = in;
+ const gfloat *bgcolor = layer;
+ gfloat alpha;
+ gint c;
+
+ alpha = 0.0f;
+
+ for (c = 0; c < 3; c++)
+ {
+ gfloat col = CLAMP (color[c], 0.0f, 1.0f);
+ gfloat bgcol = CLAMP (bgcolor[c], 0.0f, 1.0f);
+
+ if (col != bgcol)
+ {
+ gfloat a;
+
+ if (col > bgcol)
+ a = (col - bgcol) / (1.0f - bgcol);
+ else
+ a = (bgcol - col) / bgcol;
+
+ alpha = MAX (alpha, a);
+ }
+ }
+
+ if (alpha > 0.0f)
+ {
+ gfloat alpha_inv = 1.0f / alpha;
+
+ for (c = 0; c < 3; c++)
+ comp[c] = (color[c] - bgcolor[c]) * alpha_inv + bgcolor[c];
+ }
+ else
+ {
+ comp[RED] = comp[GREEN] = comp[BLUE] = 0.0f;
+ }
+
+ comp[ALPHA] = alpha;
+ }
+ else
+ comp[ALPHA] = 0.0f;
+
+ comp += 4;
+ layer += 4;
+ in += 4;
+ }
+}
diff --git a/app/operations/layer-modes/gimpoperationlayermode-blend.h
b/app/operations/layer-modes/gimpoperationlayermode-blend.h
new file mode 100644
index 0000000..40e8513
--- /dev/null
+++ b/app/operations/layer-modes/gimpoperationlayermode-blend.h
@@ -0,0 +1,167 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationlayermode-blend.h
+ * Copyright (C) 2017 Michael Natterer <mitch gimp org>
+ * 2017 Øyvind Kolås <pippin gimp org>
+ * 2017 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; withcomp even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_OPERATION_LAYER_MODE_BLEND_H__
+#define __GIMP_OPERATION_LAYER_MODE_BLEND_H__
+
+
+/* nonsubtractive blend functions */
+
+void gimp_operation_layer_mode_blend_addition (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_burn (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_darken_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_difference (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_divide (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_dodge (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_exclusion (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_grain_extract (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_grain_merge (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_hard_mix (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_hardlight (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_hsl_color (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_hsv_hue (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_hsv_saturation (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_hsv_value (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_lch_chroma (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_lch_color (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_lch_hue (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_lch_lightness (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_lighten_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_linear_burn (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_linear_light (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_luma_darken_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_luma_lighten_only (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_luminance (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_multiply (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_overlay (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_pin_light (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_screen (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_softlight (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_subtract (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+void gimp_operation_layer_mode_blend_vivid_light (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+
+
+/* subtractive blend functions */
+
+void gimp_operation_layer_mode_blend_color_erase (const gfloat *in,
+ const gfloat *layer,
+ gfloat *comp,
+ gint samples);
+
+
+#endif /* __GIMP_OPERATION_LAYER_MODE_BLEND_H__ */
diff --git a/app/operations/layer-modes/gimpoperationlayermode-composite-sse2.c
b/app/operations/layer-modes/gimpoperationlayermode-composite-sse2.c
new file mode 100644
index 0000000..8f55078
--- /dev/null
+++ b/app/operations/layer-modes/gimpoperationlayermode-composite-sse2.c
@@ -0,0 +1,105 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationlayermode-composite-sse2.c
+ * Copyright (C) 2017 Michael Natterer <mitch gimp org>
+ * 2017 Øyvind Kolås <pippin gimp org>
+ * 2017 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl-plugin.h>
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "../operations-types.h"
+
+#include "gimpoperationlayermode-composite.h"
+
+
+#if COMPILE_SSE2_INTRINISICS
+
+/* SSE2 */
+#include <emmintrin.h>
+
+
+/* non-subtractive compositing functions. these functions expect comp[ALPHA]
+ * to be the same as layer[ALPHA]. when in[ALPHA] or layer[ALPHA] are zero,
+ * the value of comp[RED..BLUE] is unconstrained (in particular, it may be
+ * NaN).
+ */
+
+
+void
+gimp_operation_layer_mode_composite_src_atop_sse2 (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ if ((((uintptr_t)in) | /* alignment check */
+ ((uintptr_t)comp) |
+ ((uintptr_t)out) ) & 0x0F)
+ {
+ gimp_operation_layer_mode_composite_src_atop (in, layer, comp,
+ mask, opacity, out,
+ samples);
+ }
+ else
+ {
+ const __v4sf *v_in = (const __v4sf*) in;
+ const __v4sf *v_comp = (const __v4sf*) comp;
+ __v4sf *v_out = (__v4sf*) out;
+ const __v4sf v_one = _mm_set1_ps (1.0f);
+ const __v4sf v_opacity = _mm_set1_ps (opacity);
+
+ while (samples--)
+ {
+ __v4sf alpha, rgba_in, rgba_comp;
+
+ rgba_in = *v_in ++;
+ rgba_comp = *v_comp++;
+
+ alpha = (__v4sf)_mm_shuffle_epi32((__m128i)rgba_comp,_MM_SHUFFLE(3,3,3,3)) * v_opacity;
+
+ if (mask)
+ {
+ alpha = alpha * _mm_set1_ps (*mask++);
+ }
+
+ if (rgba_in[ALPHA] != 0.0f && _mm_ucomineq_ss (alpha, _mm_setzero_ps ()))
+ {
+ __v4sf out_pixel, out_pixel_rbaa, out_alpha;
+
+ out_alpha = (__v4sf)_mm_shuffle_epi32((__m128i)rgba_in,_MM_SHUFFLE(3,3,3,3));
+ out_pixel = rgba_comp * alpha + rgba_in * (v_one - alpha);
+ out_pixel_rbaa = _mm_shuffle_ps (out_pixel, out_alpha, _MM_SHUFFLE (3, 3, 2, 0));
+ out_pixel = _mm_shuffle_ps (out_pixel, out_pixel_rbaa, _MM_SHUFFLE (2, 1, 1, 0));
+
+ *v_out++ = out_pixel;
+ }
+ else
+ {
+ *v_out ++ = rgba_in;
+ }
+ }
+ }
+}
+
+#endif /* COMPILE_SSE2_INTRINISICS */
diff --git a/app/operations/layer-modes/gimpoperationlayermode-composite.c
b/app/operations/layer-modes/gimpoperationlayermode-composite.c
new file mode 100644
index 0000000..a4f3bad
--- /dev/null
+++ b/app/operations/layer-modes/gimpoperationlayermode-composite.c
@@ -0,0 +1,434 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationlayermode-composite.c
+ * Copyright (C) 2017 Michael Natterer <mitch gimp org>
+ * 2017 Øyvind Kolås <pippin gimp org>
+ * 2017 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl-plugin.h>
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "../operations-types.h"
+
+#include "gimpoperationlayermode-composite.h"
+
+
+/* non-subtractive compositing functions. these functions expect comp[ALPHA]
+ * to be the same as layer[ALPHA]. when in[ALPHA] or layer[ALPHA] are zero,
+ * the value of comp[RED..BLUE] is unconstrained (in particular, it may be
+ * NaN).
+ */
+
+
+void
+gimp_operation_layer_mode_composite_src_over (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat new_alpha;
+ gfloat in_alpha = in[ALPHA];
+ gfloat layer_alpha = layer[ALPHA] * opacity;
+
+ if (mask)
+ layer_alpha *= *mask;
+
+ new_alpha = layer_alpha + (1.0f - layer_alpha) * in_alpha;
+
+ if (layer_alpha == 0.0f || new_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else if (in_alpha == 0.0f)
+ {
+ out[RED] = layer[RED];
+ out[GREEN] = layer[GREEN];
+ out[BLUE] = layer[BLUE];
+ }
+ else
+ {
+ gfloat ratio = layer_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = ratio * (in_alpha * (comp[b] - layer[b]) + layer[b] - in[b]) + in[b];
+ }
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ layer += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+void
+gimp_operation_layer_mode_composite_src_atop (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat layer_alpha = comp[ALPHA] * opacity;
+
+ if (mask)
+ layer_alpha *= *mask;
+
+ if (in[ALPHA] == 0.0f || layer_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = comp[b] * layer_alpha + in[b] * (1.0f - layer_alpha);
+ }
+
+ out[ALPHA] = in[ALPHA];
+
+ in += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+void
+gimp_operation_layer_mode_composite_dst_atop (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat layer_alpha = layer[ALPHA] * opacity;
+
+ if (mask)
+ layer_alpha *= *mask;
+
+ if (layer_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else if (in[ALPHA] == 0.0f)
+ {
+ out[RED] = layer[RED];
+ out[GREEN] = layer[GREEN];
+ out[BLUE] = layer[BLUE];
+ }
+ else
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = comp[b] * in[ALPHA] + layer[b] * (1.0f - in[ALPHA]);
+ }
+
+ out[ALPHA] = layer_alpha;
+
+ in += 4;
+ layer += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+void
+gimp_operation_layer_mode_composite_src_in (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat new_alpha = in[ALPHA] * comp[ALPHA] * opacity;
+
+ if (mask)
+ new_alpha *= *mask;
+
+ if (new_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else
+ {
+ out[RED] = comp[RED];
+ out[GREEN] = comp[GREEN];
+ out[BLUE] = comp[BLUE];
+ }
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+/* subtractive compositing functions. these functions expect comp[ALPHA] to
+ * specify the modified alpha of the overlapping content, as a fraction of the
+ * original overlapping content (i.e., an alpha of 1.0 specifies that no
+ * content is subtracted.) when in[ALPHA] or layer[ALPHA] are zero, the value
+ * of comp[RED..BLUE] is unconstrained (in particular, it may be NaN).
+ */
+
+void
+gimp_operation_layer_mode_composite_src_over_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat in_alpha = in[ALPHA];
+ gfloat layer_alpha = layer[ALPHA] * opacity;
+ gfloat comp_alpha = comp[ALPHA];
+ gfloat new_alpha;
+
+ if (mask)
+ layer_alpha *= *mask;
+
+ new_alpha = in_alpha + layer_alpha -
+ (2.0f - comp_alpha) * in_alpha * layer_alpha;
+
+ if (layer_alpha == 0.0f || new_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else if (in_alpha == 0.0f)
+ {
+ out[RED] = layer[RED];
+ out[GREEN] = layer[GREEN];
+ out[BLUE] = layer[BLUE];
+ }
+ else
+ {
+ gfloat ratio = in_alpha / new_alpha;
+ gfloat layer_coeff = 1.0f / in_alpha - 1.0f;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = ratio * (layer_alpha * (comp_alpha * comp[b] + layer_coeff * layer[b] - in[b]) + in[b]);
+ }
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ layer += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+void
+gimp_operation_layer_mode_composite_src_atop_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat layer_alpha = layer[ALPHA] * opacity;
+ gfloat comp_alpha = comp[ALPHA];
+ gfloat new_alpha;
+
+ if (mask)
+ layer_alpha *= *mask;
+
+ comp_alpha *= layer_alpha;
+
+ new_alpha = 1.0f - layer_alpha + comp_alpha;
+
+ if (in[ALPHA] == 0.0f || comp_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = comp[b] * ratio + in[b] * (1.0f - ratio);
+ }
+
+ new_alpha *= in[ALPHA];
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ layer += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+void
+gimp_operation_layer_mode_composite_dst_atop_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat in_alpha = in[ALPHA];
+ gfloat layer_alpha = layer[ALPHA] * opacity;
+ gfloat comp_alpha = comp[ALPHA];
+ gfloat new_alpha;
+
+ if (mask)
+ layer_alpha *= *mask;
+
+ comp_alpha *= in_alpha;
+
+ new_alpha = 1.0f - in_alpha + comp_alpha;
+
+ if (layer_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else if (in_alpha == 0.0f)
+ {
+ out[RED] = layer[RED];
+ out[GREEN] = layer[GREEN];
+ out[BLUE] = layer[BLUE];
+ }
+ else
+ {
+ gfloat ratio = comp_alpha / new_alpha;
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = comp[b] * ratio + layer[b] * (1.0f - ratio);
+ }
+
+ new_alpha *= layer_alpha;
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ layer += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+void
+gimp_operation_layer_mode_composite_src_in_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat new_alpha = in[ALPHA] * layer[ALPHA] * comp[ALPHA] * opacity;
+
+ if (mask)
+ new_alpha *= *mask;
+
+ if (new_alpha == 0.0f)
+ {
+ out[RED] = in[RED];
+ out[GREEN] = in[GREEN];
+ out[BLUE] = in[BLUE];
+ }
+ else
+ {
+ out[RED] = comp[RED];
+ out[GREEN] = comp[GREEN];
+ out[BLUE] = comp[BLUE];
+ }
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ layer += 4;
+ comp += 4;
+ out += 4;
+
+ if (mask)
+ mask++;
+ }
+}
diff --git a/app/operations/layer-modes/gimpoperationlayermode-composite.h
b/app/operations/layer-modes/gimpoperationlayermode-composite.h
new file mode 100644
index 0000000..a6f9823
--- /dev/null
+++ b/app/operations/layer-modes/gimpoperationlayermode-composite.h
@@ -0,0 +1,98 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationlayermode-composite.h
+ * Copyright (C) 2017 Michael Natterer <mitch gimp org>
+ * 2017 Øyvind Kolås <pippin gimp org>
+ * 2017 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_OPERATION_LAYER_MODE_COMPOSITE_H__
+#define __GIMP_OPERATION_LAYER_MODE_COMPOSITE_H__
+
+
+void gimp_operation_layer_mode_composite_src_over (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+void gimp_operation_layer_mode_composite_src_atop (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+void gimp_operation_layer_mode_composite_dst_atop (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+void gimp_operation_layer_mode_composite_src_in (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+
+void gimp_operation_layer_mode_composite_src_over_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+void gimp_operation_layer_mode_composite_src_atop_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+void gimp_operation_layer_mode_composite_dst_atop_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+void gimp_operation_layer_mode_composite_src_in_sub (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+
+#if COMPILE_SSE2_INTRINISICS
+
+void gimp_operation_layer_mode_composite_src_atop_sse2 (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples);
+
+#endif /* COMPILE_SSE2_INTRINISICS */
+
+
+#endif /* __GIMP_OPERATION_LAYER_MODE_COMPOSITE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationlayermode.c
b/app/operations/layer-modes/gimpoperationlayermode.c
index 513705f..68d4eb6 100644
--- a/app/operations/layer-modes/gimpoperationlayermode.c
+++ b/app/operations/layer-modes/gimpoperationlayermode.c
@@ -25,14 +25,13 @@
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "libgimpcolor/gimpcolor.h"
#include "libgimpbase/gimpbase.h"
-#include "libgimpmath/gimpmath.h"
#include "../operations-types.h"
#include "gimp-layer-modes.h"
#include "gimpoperationlayermode.h"
+#include "gimpoperationlayermode-composite.h"
/* the maximum number of samples to process in one go. used to limit
@@ -59,120 +58,58 @@ enum
PROP_COMPOSITE_MODE
};
-typedef void (* CompositeFunc) (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- float opacity,
- gfloat *out,
- gint samples);
-
-
-static void gimp_operation_layer_mode_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_operation_layer_mode_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gimp_operation_layer_mode_prepare (GeglOperation *operation);
-static gboolean
- gimp_operation_layer_mode_parent_process (GeglOperation *operation,
- GeglOperationContext *context,
- const gchar *output_prop,
- const GeglRectangle *result,
- gint level);
-
-static gboolean gimp_operation_layer_mode_process (GeglOperation *operation,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
-
-static GimpLayerCompositeRegion
- gimp_operation_layer_mode_real_get_affected_region (GimpOperationLayerMode *layer_mode);
-
-static inline void composite_func_src_atop_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-static inline void composite_func_dst_atop_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-static inline void composite_func_src_in_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-static inline void composite_func_src_over_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-
-static inline void composite_func_src_atop_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-static inline void composite_func_dst_atop_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-static inline void composite_func_src_in_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-static inline void composite_func_src_over_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-
-#if COMPILE_SSE2_INTRINISICS
-static inline void composite_func_src_atop_sse2 (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples);
-#endif
-static gboolean process_layer_only (GeglOperation *operation,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+typedef void (* CompositeFunc) (const gfloat *in,
+ const gfloat *layer,
+ const gfloat *comp,
+ const gfloat *mask,
+ float opacity,
+ gfloat *out,
+ gint samples);
+
+
+static void gimp_operation_layer_mode_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_operation_layer_mode_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_operation_layer_mode_prepare (GeglOperation *operation);
+static gboolean gimp_operation_layer_mode_parent_process (GeglOperation *operation,
+ GeglOperationContext *context,
+ const gchar *output_prop,
+ const GeglRectangle *result,
+ gint level);
+
+static gboolean gimp_operation_layer_mode_process (GeglOperation *operation,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+static gboolean gimp_operation_layer_mode_real_process (GeglOperation *operation,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+static gboolean process_last_node (GeglOperation *operation,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
G_DEFINE_TYPE (GimpOperationLayerMode, gimp_operation_layer_mode,
@@ -183,39 +120,37 @@ G_DEFINE_TYPE (GimpOperationLayerMode, gimp_operation_layer_mode,
static const Babl *gimp_layer_color_space_fish[3 /* from */][3 /* to */];
-static CompositeFunc composite_func_src_atop = composite_func_src_atop_core;
-static CompositeFunc composite_func_dst_atop = composite_func_dst_atop_core;
-static CompositeFunc composite_func_src_in = composite_func_src_in_core;
-static CompositeFunc composite_func_src_over = composite_func_src_over_core;
+static CompositeFunc composite_src_over = gimp_operation_layer_mode_composite_src_over;
+static CompositeFunc composite_src_atop = gimp_operation_layer_mode_composite_src_atop;
+static CompositeFunc composite_dst_atop = gimp_operation_layer_mode_composite_dst_atop;
+static CompositeFunc composite_src_in = gimp_operation_layer_mode_composite_src_in;
-static CompositeFunc composite_func_src_atop_sub = composite_func_src_atop_sub_core;
-static CompositeFunc composite_func_dst_atop_sub = composite_func_dst_atop_sub_core;
-static CompositeFunc composite_func_src_in_sub = composite_func_src_in_sub_core;
-static CompositeFunc composite_func_src_over_sub = composite_func_src_over_sub_core;
+static CompositeFunc composite_src_over_sub = gimp_operation_layer_mode_composite_src_over_sub;
+static CompositeFunc composite_src_atop_sub = gimp_operation_layer_mode_composite_src_atop_sub;
+static CompositeFunc composite_dst_atop_sub = gimp_operation_layer_mode_composite_dst_atop_sub;
+static CompositeFunc composite_src_in_sub = gimp_operation_layer_mode_composite_src_in_sub;
static void
gimp_operation_layer_mode_class_init (GimpOperationLayerModeClass *klass)
{
- GObjectClass *object_class;
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_composer3_class;
-
- object_class = G_OBJECT_CLASS (klass);
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_composer3_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GeglOperationPointComposer3Class *point_composer3_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:layer-mode", NULL);
- object_class->set_property = gimp_operation_layer_mode_set_property;
- object_class->get_property = gimp_operation_layer_mode_get_property;
+ object_class->set_property = gimp_operation_layer_mode_set_property;
+ object_class->get_property = gimp_operation_layer_mode_get_property;
operation_class->prepare = gimp_operation_layer_mode_prepare;
operation_class->process = gimp_operation_layer_mode_parent_process;
+
point_composer3_class->process = gimp_operation_layer_mode_process;
- klass->get_affected_region = gimp_operation_layer_mode_real_get_affected_region;
+ klass->process = gimp_operation_layer_mode_real_process;
+ klass->get_affected_region = NULL;
g_object_class_install_property (object_class, PROP_LAYER_MODE,
g_param_spec_enum ("layer-mode",
@@ -286,7 +221,7 @@ gimp_operation_layer_mode_class_init (GimpOperationLayerModeClass *klass)
#if COMPILE_SSE2_INTRINISICS
if (gimp_cpu_accel_get_support () & GIMP_CPU_ACCEL_X86_SSE2)
- composite_func_src_atop = composite_func_src_atop_sse2;
+ composite_src_atop = gimp_operation_layer_mode_composite_src_atop_sse2;
#endif
}
@@ -375,7 +310,10 @@ gimp_operation_layer_mode_prepare (GeglOperation *operation)
const Babl *preferred_format;
const Babl *format;
- self->func = gimp_layer_mode_get_function (self->layer_mode);
+ self->real_composite_mode = self->composite_mode;
+
+ self->function = gimp_layer_mode_get_function (self->layer_mode);
+ self->blend_function = gimp_layer_mode_get_blend_function (self->layer_mode);
input_extent = gegl_operation_source_get_bounding_box (operation, "input");
@@ -396,9 +334,18 @@ gimp_operation_layer_mode_prepare (GeglOperation *operation)
/* if the layer mode doesn't affect the source, use a shortcut
* function that only applies the opacity/mask to the layer.
*/
- if (! (gimp_layer_mode_get_affected_region (self->layer_mode) &
+ if (! (gimp_operation_layer_mode_get_affected_region (self) &
GIMP_LAYER_COMPOSITE_REGION_SOURCE))
- self->func = process_layer_only;
+ {
+ self->function = process_last_node;
+ }
+ /* otherwise, use the original process function, but force the
+ * composite mode to SRC_OVER.
+ */
+ else
+ {
+ self->real_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER;
+ }
preferred_format = gegl_operation_get_source_format (operation, "aux");
}
@@ -470,13 +417,13 @@ gimp_operation_layer_mode_parent_process (GeglOperation *operation,
GimpLayerCompositeRegion affected_region;
affected_region =
- gimp_layer_mode_get_affected_region (point->layer_mode);
+ gimp_operation_layer_mode_get_affected_region (point);
/* ... and the op doesn't otherwise affect 'aux', or changes its
* alpha ...
*/
if (! (affected_region & GIMP_LAYER_COMPOSITE_REGION_SOURCE) &&
- point->opacity == 1.0 &&
+ point->opacity == 1.0 &&
! gegl_operation_context_get_object (context, "aux2"))
{
/* pass 'aux' directly as output; */
@@ -507,7 +454,7 @@ gimp_operation_layer_mode_parent_process (GeglOperation *operation,
GimpLayerCompositeRegion affected_region;
affected_region =
- gimp_layer_mode_get_affected_region (point->layer_mode);
+ gimp_operation_layer_mode_get_affected_region (point);
/* ... and the op doesn't otherwise affect 'input' ... */
if (! (affected_region & GIMP_LAYER_COMPOSITE_REGION_DESTINATION))
@@ -562,603 +509,36 @@ gimp_operation_layer_mode_process (GeglOperation *operation,
const GeglRectangle *roi,
gint level)
{
- GimpOperationLayerMode *point = GIMP_OPERATION_LAYER_MODE (operation);
-
- /* if we're not the last node, or we're using the opacity/mask shortcut
- * function, forward directly to the real process function.
- */
- if (! point->is_last_node || point->func == process_layer_only)
- {
- return point->func (operation, in, layer, mask, out, samples, roi, level);
- }
- /* otherwise, switch the composite mode temporarily to src-over, before
- * handing processing over to the real process function.
- */
- else
- {
- GimpLayerCompositeMode composite_mode = point->composite_mode;
- gboolean result;
-
- point->composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER;
-
- result = point->func (operation, in, layer, mask, out, samples, roi, level);
-
- point->composite_mode = composite_mode;
-
- return result;
- }
-}
-
-static GimpLayerCompositeRegion
-gimp_operation_layer_mode_real_get_affected_region (GimpOperationLayerMode *layer_mode)
-{
- /* most modes only affect the overlapping regions. */
- return GIMP_LAYER_COMPOSITE_REGION_INTERSECTION;
-}
-
-
-/* public functions */
-
-GimpLayerCompositeRegion
-gimp_operation_layer_mode_get_affected_region (GimpOperationLayerMode *layer_mode)
-{
- g_return_val_if_fail (GIMP_IS_OPERATION_LAYER_MODE (layer_mode),
- GIMP_LAYER_COMPOSITE_REGION_INTERSECTION);
-
- return GIMP_OPERATION_LAYER_MODE_GET_CLASS (layer_mode)->get_affected_region (layer_mode);
-}
-
-
-/* compositing and blending functions */
-
-static inline GimpBlendFunc gimp_layer_mode_get_blend_fun (GimpLayerMode mode);
-
-static inline void gimp_composite_blend (GimpOperationLayerMode *layer_mode,
- gfloat *in,
- gfloat *layer,
- gfloat *mask,
- gfloat *out,
- glong samples,
- GimpBlendFunc blend_func);
-
-
-gboolean
-gimp_operation_layer_mode_process_pixels (GeglOperation *operation,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level)
-{
- GimpOperationLayerMode *layer_mode = (gpointer) operation;
-
- gimp_composite_blend (layer_mode, in, layer, mask, out, samples,
- gimp_layer_mode_get_blend_fun (layer_mode->layer_mode));
-
- return TRUE;
+ return ((GimpOperationLayerMode *) operation)->function (
+ operation, in, layer, mask, out, samples, roi, level);
}
static gboolean
-process_layer_only (GeglOperation *operation,
- void *in_buf,
- void *layer_buf,
- void *mask_buf,
- void *out_buf,
- glong samples,
- const GeglRectangle *roi,
- gint level)
-{
- gfloat *out = out_buf;
- gfloat *layer = layer_buf;
- gfloat *mask = mask_buf;
- gfloat opacity = GIMP_OPERATION_LAYER_MODE (operation)->opacity;
-
- while (samples--)
- {
- memcpy (out, layer, 3 * sizeof (gfloat));
-
- out[ALPHA] = layer[ALPHA] * opacity;
- if (mask)
- out[ALPHA] *= *mask++;
-
- layer += 4;
- out += 4;
- }
-
- return TRUE;
-}
-
-
-/* non-subtractive compositing functions. these functions expect comp[ALPHA]
- * to be the same as layer[ALPHA]. when in[ALPHA] or layer[ALPHA] are zero,
- * the value of comp[RED..BLUE] is unconstrained (in particular, it may be
- * NaN).
- */
-
-static inline void
-composite_func_src_atop_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat layer_alpha = comp[ALPHA] * opacity;
-
- if (mask)
- layer_alpha *= *mask;
-
- if (in[ALPHA] == 0.0f || layer_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else
- {
- gint b;
-
- for (b = RED; b < ALPHA; b++)
- out[b] = comp[b] * layer_alpha + in[b] * (1.0f - layer_alpha);
- }
-
- out[ALPHA] = in[ALPHA];
-
- in += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-static inline void
-composite_func_src_over_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat new_alpha;
- gfloat in_alpha = in[ALPHA];
- gfloat layer_alpha = layer[ALPHA] * opacity;
-
- if (mask)
- layer_alpha *= *mask;
-
- new_alpha = layer_alpha + (1.0f - layer_alpha) * in_alpha;
-
- if (layer_alpha == 0.0f || new_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else if (in_alpha == 0.0f)
- {
- out[RED] = layer[RED];
- out[GREEN] = layer[GREEN];
- out[BLUE] = layer[BLUE];
- }
- else
- {
- gfloat ratio = layer_alpha / new_alpha;
- gint b;
-
- for (b = RED; b < ALPHA; b++)
- out[b] = ratio * (in_alpha * (comp[b] - layer[b]) + layer[b] - in[b]) + in[b];
- }
-
- out[ALPHA] = new_alpha;
-
- in += 4;
- layer += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-static inline void
-composite_func_dst_atop_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat layer_alpha = layer[ALPHA] * opacity;
-
- if (mask)
- layer_alpha *= *mask;
-
- if (layer_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else if (in[ALPHA] == 0.0f)
- {
- out[RED] = layer[RED];
- out[GREEN] = layer[GREEN];
- out[BLUE] = layer[BLUE];
- }
- else
- {
- gint b;
-
- for (b = RED; b < ALPHA; b++)
- out[b] = comp[b] * in[ALPHA] + layer[b] * (1.0f - in[ALPHA]);
- }
-
- out[ALPHA] = layer_alpha;
-
- in += 4;
- layer += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-static inline void
-composite_func_src_in_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat new_alpha = in[ALPHA] * comp[ALPHA] * opacity;
-
- if (mask)
- new_alpha *= *mask;
-
- if (new_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else
- {
- out[RED] = comp[RED];
- out[GREEN] = comp[GREEN];
- out[BLUE] = comp[BLUE];
- }
-
- out[ALPHA] = new_alpha;
-
- in += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-/* subtractive compositing functions. these functions expect comp[ALPHA] to
- * specify the modified alpha of the overlapping content, as a fraction of the
- * original overlapping content (i.e., an alpha of 1.0 specifies that no
- * content is subtracted.) when in[ALPHA] or layer[ALPHA] are zero, the value
- * of comp[RED..BLUE] is unconstrained (in particular, it may be NaN).
- */
-
-static inline void
-composite_func_src_atop_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat layer_alpha = layer[ALPHA] * opacity;
- gfloat comp_alpha = comp[ALPHA];
- gfloat new_alpha;
-
- if (mask)
- layer_alpha *= *mask;
-
- comp_alpha *= layer_alpha;
-
- new_alpha = 1.0f - layer_alpha + comp_alpha;
-
- if (in[ALPHA] == 0.0f || comp_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else
- {
- gfloat ratio = comp_alpha / new_alpha;
- gint b;
-
- for (b = RED; b < ALPHA; b++)
- out[b] = comp[b] * ratio + in[b] * (1.0f - ratio);
- }
-
- new_alpha *= in[ALPHA];
-
- out[ALPHA] = new_alpha;
-
- in += 4;
- layer += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-static inline void
-composite_func_src_over_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat in_alpha = in[ALPHA];
- gfloat layer_alpha = layer[ALPHA] * opacity;
- gfloat comp_alpha = comp[ALPHA];
- gfloat new_alpha;
-
- if (mask)
- layer_alpha *= *mask;
-
- new_alpha = in_alpha + layer_alpha -
- (2.0f - comp_alpha) * in_alpha * layer_alpha;
-
- if (layer_alpha == 0.0f || new_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else if (in_alpha == 0.0f)
- {
- out[RED] = layer[RED];
- out[GREEN] = layer[GREEN];
- out[BLUE] = layer[BLUE];
- }
- else
- {
- gfloat ratio = in_alpha / new_alpha;
- gfloat layer_coeff = 1.0f / in_alpha - 1.0f;
- gint b;
-
- for (b = RED; b < ALPHA; b++)
- out[b] = ratio * (layer_alpha * (comp_alpha * comp[b] + layer_coeff * layer[b] - in[b]) + in[b]);
- }
-
- out[ALPHA] = new_alpha;
-
- in += 4;
- layer += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-static inline void
-composite_func_dst_atop_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat in_alpha = in[ALPHA];
- gfloat layer_alpha = layer[ALPHA] * opacity;
- gfloat comp_alpha = comp[ALPHA];
- gfloat new_alpha;
-
- if (mask)
- layer_alpha *= *mask;
-
- comp_alpha *= in_alpha;
-
- new_alpha = 1.0f - in_alpha + comp_alpha;
-
- if (layer_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else if (in_alpha == 0.0f)
- {
- out[RED] = layer[RED];
- out[GREEN] = layer[GREEN];
- out[BLUE] = layer[BLUE];
- }
- else
- {
- gfloat ratio = comp_alpha / new_alpha;
- gint b;
-
- for (b = RED; b < ALPHA; b++)
- out[b] = comp[b] * ratio + layer[b] * (1.0f - ratio);
- }
-
- new_alpha *= layer_alpha;
-
- out[ALPHA] = new_alpha;
-
- in += 4;
- layer += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-static inline void
-composite_func_src_in_sub_core (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- while (samples--)
- {
- gfloat new_alpha = in[ALPHA] * layer[ALPHA] * comp[ALPHA] * opacity;
-
- if (mask)
- new_alpha *= *mask;
-
- if (new_alpha == 0.0f)
- {
- out[RED] = in[RED];
- out[GREEN] = in[GREEN];
- out[BLUE] = in[BLUE];
- }
- else
- {
- out[RED] = comp[RED];
- out[GREEN] = comp[GREEN];
- out[BLUE] = comp[BLUE];
- }
-
- out[ALPHA] = new_alpha;
-
- in += 4;
- layer += 4;
- comp += 4;
- out += 4;
-
- if (mask)
- mask++;
- }
-}
-
-#if COMPILE_SSE2_INTRINISICS
-
-#include <emmintrin.h>
-
-static inline void
-composite_func_src_atop_sse2 (gfloat *in,
- gfloat *layer,
- gfloat *comp,
- gfloat *mask,
- gfloat opacity,
- gfloat *out,
- gint samples)
-{
- if ((((uintptr_t)in) | /* alignment check */
- ((uintptr_t)comp) |
- ((uintptr_t)out) ) & 0x0F)
- {
- return composite_func_src_atop_core (in, layer, comp, mask, opacity,
- out, samples);
- }
- else
- {
- const __v4sf *v_in = (const __v4sf*) in;
- const __v4sf *v_comp = (const __v4sf*) comp;
- __v4sf *v_out = (__v4sf*) out;
- const __v4sf v_one = _mm_set1_ps (1.0f);
- const __v4sf v_opacity = _mm_set1_ps (opacity);
-
- while (samples--)
- {
- __v4sf alpha, rgba_in, rgba_comp;
-
- rgba_in = *v_in ++;
- rgba_comp = *v_comp++;
-
- alpha = (__v4sf)_mm_shuffle_epi32((__m128i)rgba_comp,_MM_SHUFFLE(3,3,3,3)) * v_opacity;
-
- if (mask)
- {
- alpha = alpha * _mm_set1_ps (*mask++);
- }
-
- if (rgba_in[ALPHA] != 0.0f && _mm_ucomineq_ss (alpha, _mm_setzero_ps ()))
- {
- __v4sf out_pixel, out_pixel_rbaa, out_alpha;
-
- out_alpha = (__v4sf)_mm_shuffle_epi32((__m128i)rgba_in,_MM_SHUFFLE(3,3,3,3));
- out_pixel = rgba_comp * alpha + rgba_in * (v_one - alpha);
- out_pixel_rbaa = _mm_shuffle_ps (out_pixel, out_alpha, _MM_SHUFFLE (3, 3, 2, 0));
- out_pixel = _mm_shuffle_ps (out_pixel, out_pixel_rbaa, _MM_SHUFFLE (2, 1, 1, 0));
-
- *v_out++ = out_pixel;
- }
- else
- {
- *v_out ++ = rgba_in;
- }
- }
- }
-}
-
-#endif
-
-static inline void
-gimp_composite_blend (GimpOperationLayerMode *layer_mode,
- gfloat *in,
- gfloat *layer,
- gfloat *mask,
- gfloat *out,
- glong samples,
- GimpBlendFunc blend_func)
-{
- gfloat opacity = layer_mode->opacity;
- GimpLayerColorSpace blend_space = layer_mode->blend_space;
- GimpLayerColorSpace composite_space = layer_mode->composite_space;
- GimpLayerCompositeMode composite_mode = layer_mode->composite_mode;
-
- gfloat *blend_in;
- gfloat *blend_layer;
- gfloat *blend_out;
-
- gboolean composite_needs_in_color =
- composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
- composite_mode == GIMP_LAYER_COMPOSITE_SRC_ATOP;
-
- const Babl *composite_to_blend_fish = NULL;
- const Babl *blend_to_composite_fish = NULL;
+gimp_operation_layer_mode_real_process (GeglOperation *operation,
+ void *in_p,
+ void *layer_p,
+ void *mask_p,
+ void *out_p,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level)
+{
+ GimpOperationLayerMode *layer_mode = (gpointer) operation;
+ gfloat *in = in_p;
+ gfloat *out = out_p;
+ gfloat *layer = layer_p;
+ gfloat *mask = mask_p;
+ gfloat opacity = layer_mode->opacity;
+ GimpLayerColorSpace blend_space = layer_mode->blend_space;
+ GimpLayerColorSpace composite_space = layer_mode->composite_space;
+ GimpLayerCompositeMode composite_mode = layer_mode->real_composite_mode;
+ GimpLayerModeBlendFunc blend_function = layer_mode->blend_function;
+ gboolean composite_needs_in_color;
+ gfloat *blend_in;
+ gfloat *blend_layer;
+ gfloat *blend_out;
+ const Babl *composite_to_blend_fish = NULL;
+ const Babl *blend_to_composite_fish = NULL;
/* make sure we don't process more than GIMP_COMPOSITE_BLEND_MAX_SAMPLES
* at a time, so that we don't overflow the stack if we allocate buffers
@@ -1167,10 +547,10 @@ gimp_composite_blend (GimpOperationLayerMode *layer_mode,
*/
while (samples > GIMP_COMPOSITE_BLEND_MAX_SAMPLES)
{
- gimp_composite_blend (layer_mode,
- in, layer, mask, out,
- GIMP_COMPOSITE_BLEND_MAX_SAMPLES,
- blend_func);
+ gimp_operation_layer_mode_real_process (operation,
+ in, layer, mask, out,
+ GIMP_COMPOSITE_BLEND_MAX_SAMPLES,
+ roi, level);
in += 4 * GIMP_COMPOSITE_BLEND_MAX_SAMPLES;
layer += 4 * GIMP_COMPOSITE_BLEND_MAX_SAMPLES;
@@ -1181,6 +561,10 @@ gimp_composite_blend (GimpOperationLayerMode *layer_mode,
samples -= GIMP_COMPOSITE_BLEND_MAX_SAMPLES;
}
+ composite_needs_in_color =
+ composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
+ composite_mode == GIMP_LAYER_COMPOSITE_SRC_ATOP;
+
blend_in = in;
blend_layer = layer;
blend_out = out;
@@ -1285,8 +669,8 @@ gimp_composite_blend (GimpOperationLayerMode *layer_mode,
babl_process (composite_to_blend_fish,
layer + first, blend_layer + first, count);
- blend_func (blend_in + first, blend_layer + first,
- blend_out + first, count);
+ blend_function (blend_in + first, blend_layer + first,
+ blend_out + first, count);
babl_process (blend_to_composite_fish,
blend_out + first, blend_out + first, count);
@@ -1310,7 +694,7 @@ gimp_composite_blend (GimpOperationLayerMode *layer_mode,
blend_out = g_alloca (sizeof (gfloat) * 4 * samples);
}
- blend_func (blend_in, blend_layer, blend_out, samples);
+ blend_function (blend_in, blend_layer, blend_out, samples);
}
if (! gimp_layer_mode_is_subtractive (layer_mode->layer_mode))
@@ -1319,27 +703,23 @@ gimp_composite_blend (GimpOperationLayerMode *layer_mode,
{
case GIMP_LAYER_COMPOSITE_SRC_ATOP:
default:
- composite_func_src_atop (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_src_atop (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
case GIMP_LAYER_COMPOSITE_SRC_OVER:
- composite_func_src_over (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_src_over (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
case GIMP_LAYER_COMPOSITE_DST_ATOP:
- composite_func_dst_atop (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_dst_atop (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
case GIMP_LAYER_COMPOSITE_SRC_IN:
- composite_func_src_in (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_src_in (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
}
}
@@ -1349,1276 +729,76 @@ gimp_composite_blend (GimpOperationLayerMode *layer_mode,
{
case GIMP_LAYER_COMPOSITE_SRC_ATOP:
default:
- composite_func_src_atop_sub (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_src_atop_sub (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
case GIMP_LAYER_COMPOSITE_SRC_OVER:
- composite_func_src_over_sub (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_src_over_sub (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
case GIMP_LAYER_COMPOSITE_DST_ATOP:
- composite_func_dst_atop_sub (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_dst_atop_sub (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
case GIMP_LAYER_COMPOSITE_SRC_IN:
- composite_func_src_in_sub (in, layer, blend_out,
- mask, opacity,
- out, samples);
+ composite_src_in_sub (in, layer, blend_out, mask, opacity,
+ out, samples);
break;
}
}
-}
-
-static inline void
-blendfun_screen (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
- for (c = 0; c < 3; c++)
- out[c] = 1.0f - (1.0f - dest[c]) * (1.0f - src[c]);
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void /* aka linear_dodge */
-blendfun_addition (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] + src[c];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_linear_burn (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] + src[c] - 1.0f;
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_subtract (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] - src[c];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_multiply (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] * src[c];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_normal (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = src[c];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_burn (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp = 1.0f - (1.0f - dest[c]) / src[c];
-
- /* The CLAMP macro is deliberately inlined and written
- * to map comp == NAN (0 / 0) -> 1
- */
- out[c] = comp < 0 ? 0.0f : comp < 1.0f ? comp : 1.0f;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_darken_only (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = MIN (dest[c], src[c]);
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_luminance_lighten_only (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
- float dest_luminance =
- GIMP_RGB_LUMINANCE(dest[0], dest[1], dest[2]);
- float src_luminance =
- GIMP_RGB_LUMINANCE(src[0], src[1], src[2]);
-
- if (dest_luminance >= src_luminance)
- for (c = 0; c < 3; c++)
- out[c] = dest[c];
- else
- for (c = 0; c < 3; c++)
- out[c] = src[c];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_luminance_darken_only (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
- float dest_luminance =
- GIMP_RGB_LUMINANCE(dest[0], dest[1], dest[2]);
- float src_luminance =
- GIMP_RGB_LUMINANCE(src[0], src[1], src[2]);
-
- if (dest_luminance <= src_luminance)
- for (c = 0; c < 3; c++)
- out[c] = dest[c];
- else
- for (c = 0; c < 3; c++)
- out[c] = src[c];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_lighten_only (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = MAX (dest[c], src[c]);
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_difference (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- out[c] = dest[c] - src[c];
-
- if (out[c] < 0)
- out[c] = -out[c];
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_divide (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp = dest[c] / src[c];
-
- /* make infinities(or NaN) correspond to a high number,
- * to get more predictable math, ideally higher than 5.0
- * but it seems like some babl conversions might be
- * acting up then
- */
- if (!(comp > -42949672.0f && comp < 5.0f))
- comp = 5.0f;
-
- out[c] = comp;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_dodge (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp = dest[c] / (1.0f - src[c]);
-
- comp = MIN (comp, 1.0f);
-
- out[c] = comp;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_grain_extract (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] - src[c] + 0.5f;
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_grain_merge (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] + src[c] - 0.5f;
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_hardlight (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp;
-
- if (src[c] > 0.5f)
- {
- comp = (1.0f - dest[c]) * (1.0f - (src[c] - 0.5f) * 2.0f);
- comp = MIN (1 - comp, 1);
- }
- else
- {
- comp = dest[c] * (src[c] * 2.0f);
- comp = MIN (comp, 1.0f);
- }
-
- out[c] = comp;
- }
- }
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_softlight (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat multiply = dest[c] * src[c];
- gfloat screen = 1.0f - (1.0f - dest[c]) * (1.0f - src[c]);
- gfloat comp = (1.0f - dest[c]) * multiply + dest[c] * screen;
-
- out[c] = comp;
- }
- }
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_overlay (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp;
-
- if (dest[c] < 0.5f)
- {
- comp = 2.0f * dest[c] * src[c];
- }
- else
- {
- comp = 1.0f - 2.0f * (1.0f - src[c]) * (1.0f - dest[c]);
- }
-
- out[c] = comp;
- }
- }
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_hsl_color (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gfloat dest_min, dest_max, dest_l;
- gfloat src_min, src_max, src_l;
-
- dest_min = MIN (dest[0], dest[1]);
- dest_min = MIN (dest_min, dest[2]);
- dest_max = MAX (dest[0], dest[1]);
- dest_max = MAX (dest_max, dest[2]);
- dest_l = (dest_min + dest_max) / 2.0f;
-
- src_min = MIN (src[0], src[1]);
- src_min = MIN (src_min, src[2]);
- src_max = MAX (src[0], src[1]);
- src_max = MAX (src_max, src[2]);
- src_l = (src_min + src_max) / 2.0f;
-
- if (src_l != 0.0f && src_l != 1.0f)
- {
- gboolean dest_high;
- gboolean src_high;
- gfloat ratio;
- gfloat offset;
- gint c;
-
- dest_high = dest_l > 0.5f;
- src_high = src_l > 0.5f;
-
- dest_l = MIN (dest_l, 1.0f - dest_l);
- src_l = MIN (src_l, 1.0f - src_l);
-
- ratio = dest_l / src_l;
-
- offset = 0.0f;
- if (dest_high) offset += 1.0f - 2.0f * dest_l;
- if (src_high) offset += 2.0f * dest_l - ratio;
-
- for (c = 0; c < 3; c++)
- out[c] = src[c] * ratio + offset;
- }
- else
- {
- out[RED] = dest_l;
- out[GREEN] = dest_l;
- out[BLUE] = dest_l;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_hsv_hue (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gfloat src_min, src_max, src_delta;
- gfloat dest_min, dest_max, dest_delta, dest_s;
-
- src_min = MIN (src[0], src[1]);
- src_min = MIN (src_min, src[2]);
- src_max = MAX (src[0], src[1]);
- src_max = MAX (src_max, src[2]);
- src_delta = src_max - src_min;
-
- if (src_delta != 0.0f)
- {
- gfloat ratio;
- gfloat offset;
- gint c;
-
- dest_min = MIN (dest[0], dest[1]);
- dest_min = MIN (dest_min, dest[2]);
- dest_max = MAX (dest[0], dest[1]);
- dest_max = MAX (dest_max, dest[2]);
- dest_delta = dest_max - dest_min;
- dest_s = dest_max ? dest_delta / dest_max : 0.0f;
-
- ratio = dest_s * dest_max / src_delta;
- offset = dest_max - src_max * ratio;
-
- for (c = 0; c < 3; c++)
- out[c] = src[c] * ratio + offset;
- }
- else
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c];
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_hsv_saturation (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gfloat src_min, src_max, src_delta, src_s;
- gfloat dest_min, dest_max, dest_delta;
-
- dest_min = MIN (dest[0], dest[1]);
- dest_min = MIN (dest_min, dest[2]);
- dest_max = MAX (dest[0], dest[1]);
- dest_max = MAX (dest_max, dest[2]);
- dest_delta = dest_max - dest_min;
-
- if (dest_delta != 0.0f)
- {
- gfloat ratio;
- gfloat offset;
- gint c;
-
- src_min = MIN (src[0], src[1]);
- src_min = MIN (src_min, src[2]);
- src_max = MAX (src[0], src[1]);
- src_max = MAX (src_max, src[2]);
- src_delta = src_max - src_min;
- src_s = src_max ? src_delta / src_max : 0.0f;
-
- ratio = src_s * dest_max / dest_delta;
- offset = (1.0f - ratio) * dest_max;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] * ratio + offset;
- }
- else
- {
- out[RED] = dest_max;
- out[GREEN] = dest_max;
- out[BLUE] = dest_max;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_hsv_value (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gfloat dest_v;
- gfloat src_v;
-
- dest_v = MAX (dest[0], dest[1]);
- dest_v = MAX (dest_v, dest[2]);
-
- src_v = MAX (src[0], src[1]);
- src_v = MAX (src_v, src[2]);
-
- if (dest_v != 0.0f)
- {
- gfloat ratio = src_v / dest_v;
- gint c;
-
- for (c = 0; c < 3; c++)
- out[c] = dest[c] * ratio;
- }
- else
- {
- out[RED] = src_v;
- out[GREEN] = src_v;
- out[BLUE] = src_v;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_lch_chroma (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gfloat A1 = dest[1];
- gfloat B1 = dest[2];
- gfloat c1 = hypotf (A1, B1);
-
- if (c1 != 0.0f)
- {
- gfloat A2 = src[1];
- gfloat B2 = src[2];
- gfloat c2 = hypotf (A2, B2);
- gfloat A = c2 * A1 / c1;
- gfloat B = c2 * B1 / c1;
-
- out[0] = dest[0];
- out[1] = A;
- out[2] = B;
- }
- else
- {
- out[0] = dest[0];
- out[1] = dest[1];
- out[2] = dest[2];
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_lch_color (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- out[0] = dest[0];
- out[1] = src[1];
- out[2] = src[2];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_lch_hue (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gfloat A2 = src[1];
- gfloat B2 = src[2];
- gfloat c2 = hypotf (A2, B2);
-
- if (c2 > 0.1f)
- {
- gfloat A1 = dest[1];
- gfloat B1 = dest[2];
- gfloat c1 = hypotf (A1, B1);
- gfloat A = c1 * A2 / c2;
- gfloat B = c1 * B2 / c2;
-
- out[0] = dest[0];
- out[1] = A;
- out[2] = B;
- }
- else
- {
- out[0] = dest[0];
- out[1] = dest[1];
- out[2] = dest[2];
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_lch_lightness (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- out[0] = src[0];
- out[1] = dest[1];
- out[2] = dest[2];
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
+ return TRUE;
}
-static inline void
-blendfun_luminance (const float *dest,//*in,
- const float *src,//*layer,
- float *out,
- int samples)
+static gboolean
+process_last_node (GeglOperation *operation,
+ void *in_p,
+ void *layer_p,
+ void *mask_p,
+ void *out_p,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level)
{
- gfloat layer_Y[samples], *layer;
- gfloat in_Y[samples], *in;
-
- babl_process (babl_fish ("RGBA float", "Y float"), src, layer_Y, samples);
- babl_process (babl_fish ("RGBA float", "Y float"), dest, in_Y, samples);
-
- layer = &layer_Y[0];
- in = &in_Y[0];
+ gfloat *out = out_p;
+ gfloat *layer = layer_p;
+ gfloat *mask = mask_p;
+ gfloat opacity = GIMP_OPERATION_LAYER_MODE (operation)->opacity;
while (samples--)
{
- if (src[ALPHA] != 0.0f && dest[ALPHA] != 0.0f)
- {
- gfloat ratio = layer[0] / MAX(in[0], 0.0000000000000000001);
- int c;
- for (c = 0; c < 3; c ++)
- out[c] = dest[c] * ratio;
- }
+ memcpy (out, layer, 3 * sizeof (gfloat));
- out[ALPHA] = src[ALPHA];
+ out[ALPHA] = layer[ALPHA] * opacity;
+ if (mask)
+ out[ALPHA] *= *mask++;
+ layer += 4;
out += 4;
- dest += 4;
- src += 4;
- in ++;
- layer ++;
- }
-}
-
-static inline void
-blendfun_copy (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- gint c;
-
- for (c = 0; c < 4; c++)
- out[c] = src[c];
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-/* added according to:
- http://www.simplefilter.de/en/basics/mixmods.html */
-static inline void
-blendfun_vivid_light (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp;
-
- if (src[c] <= 0.5f)
- {
- comp = 1.0f - (1.0f - dest[c]) / (2.0f * (src[c]));
- }
- else
- {
- comp = dest[c] / (2.0f * (1.0f - src[c]));
- }
- comp = MIN (comp, 1.0f);
-
- out[c] = comp;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-
-/* added according to:
- http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html */
-static inline void
-blendfun_linear_light (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp;
-
- if (src[c] <= 0.5f)
- {
- comp = dest[c] + 2.0 * src[c] - 1.0f;
- }
- else
- {
- comp = dest[c] + 2.0 * (src[c] - 0.5f);
- }
- out[c] = comp;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
}
-}
-
-
-/* added according to:
- http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html */
-static inline void
-blendfun_pin_light (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- gfloat comp;
-
- if (src[c] > 0.5f)
- {
- comp = MAX(dest[c], 2 * (src[c] - 0.5));
- }
- else
- {
- comp = MIN(dest[c], 2 * src[c]);
- }
- out[c] = comp;
- }
- }
-
- out[ALPHA] = src[ALPHA];
-
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_hard_mix (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
-
- for (c = 0; c < 3; c++)
- {
- out[c] = dest[c] + src[c] < 1.0f ? 0.0f : 1.0f;
- }
- }
-
- out[ALPHA] = src[ALPHA];
- out += 4;
- src += 4;
- dest += 4;
- }
+ return TRUE;
}
-static inline void
-blendfun_exclusion (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- gint c;
- for (c = 0; c < 3; c++)
- {
- out[c] = 0.5f - 2.0f * (dest[c] - 0.5f) * (src[c] - 0.5f);
- }
- }
+/* public functions */
- out[ALPHA] = src[ALPHA];
- out += 4;
- src += 4;
- dest += 4;
- }
-}
-
-static inline void
-blendfun_color_erase (const float *dest,
- const float *src,
- float *out,
- int samples)
+GimpLayerCompositeRegion
+gimp_operation_layer_mode_get_affected_region (GimpOperationLayerMode *layer_mode)
{
- while (samples--)
- {
- if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f)
- {
- const float *color = dest;
- const float *bgcolor = src;
- gfloat alpha;
- gint c;
-
- alpha = 0.0f;
-
- for (c = 0; c < 3; c++)
- {
- gfloat col = CLAMP (color[c], 0.0f, 1.0f);
- gfloat bgcol = CLAMP (bgcolor[c], 0.0f, 1.0f);
-
- if (col != bgcol)
- {
- gfloat a;
+ GimpOperationLayerModeClass *klass;
- if (col > bgcol)
- a = (col - bgcol) / (1.0f - bgcol);
- else
- a = (bgcol - col) / bgcol;
-
- alpha = MAX (alpha, a);
- }
- }
-
- if (alpha > 0.0f)
- {
- gfloat alpha_inv = 1.0f / alpha;
-
- for (c = 0; c < 3; c++)
- out[c] = (color[c] - bgcolor[c]) * alpha_inv + bgcolor[c];
- }
- else
- {
- out[RED] = out[GREEN] = out[BLUE] = 0.0f;
- }
-
- out[ALPHA] = alpha;
- }
- else
- out[ALPHA] = 0.0f;
+ g_return_val_if_fail (GIMP_IS_OPERATION_LAYER_MODE (layer_mode),
+ GIMP_LAYER_COMPOSITE_REGION_INTERSECTION);
- out += 4;
- src += 4;
- dest += 4;
- }
-}
+ klass = GIMP_OPERATION_LAYER_MODE_GET_CLASS (layer_mode);
-static inline void
-blendfun_dummy (const float *dest,
- const float *src,
- float *out,
- int samples)
-{
-}
+ if (klass->get_affected_region)
+ return klass->get_affected_region (layer_mode);
-static inline GimpBlendFunc
-gimp_layer_mode_get_blend_fun (GimpLayerMode mode)
-{
- switch (mode)
- {
- case GIMP_LAYER_MODE_SCREEN: return blendfun_screen;
- case GIMP_LAYER_MODE_ADDITION: return blendfun_addition;
- case GIMP_LAYER_MODE_SUBTRACT: return blendfun_subtract;
- case GIMP_LAYER_MODE_MULTIPLY: return blendfun_multiply;
- case GIMP_LAYER_MODE_NORMAL_LEGACY:
- case GIMP_LAYER_MODE_NORMAL: return blendfun_normal;
- case GIMP_LAYER_MODE_BURN: return blendfun_burn;
- case GIMP_LAYER_MODE_GRAIN_MERGE: return blendfun_grain_merge;
- case GIMP_LAYER_MODE_GRAIN_EXTRACT: return blendfun_grain_extract;
- case GIMP_LAYER_MODE_DODGE: return blendfun_dodge;
- case GIMP_LAYER_MODE_OVERLAY: return blendfun_overlay;
- case GIMP_LAYER_MODE_HSL_COLOR: return blendfun_hsl_color;
- case GIMP_LAYER_MODE_HSV_HUE: return blendfun_hsv_hue;
- case GIMP_LAYER_MODE_HSV_SATURATION: return blendfun_hsv_saturation;
- case GIMP_LAYER_MODE_HSV_VALUE: return blendfun_hsv_value;
- case GIMP_LAYER_MODE_LCH_CHROMA: return blendfun_lch_chroma;
- case GIMP_LAYER_MODE_LCH_COLOR: return blendfun_lch_color;
- case GIMP_LAYER_MODE_LCH_HUE: return blendfun_lch_hue;
- case GIMP_LAYER_MODE_LCH_LIGHTNESS: return blendfun_lch_lightness;
- case GIMP_LAYER_MODE_LUMINANCE: return blendfun_luminance;
- case GIMP_LAYER_MODE_HARDLIGHT: return blendfun_hardlight;
- case GIMP_LAYER_MODE_SOFTLIGHT: return blendfun_softlight;
- case GIMP_LAYER_MODE_DIVIDE: return blendfun_divide;
- case GIMP_LAYER_MODE_DIFFERENCE: return blendfun_difference;
- case GIMP_LAYER_MODE_DARKEN_ONLY: return blendfun_darken_only;
- case GIMP_LAYER_MODE_LIGHTEN_ONLY: return blendfun_lighten_only;
- case GIMP_LAYER_MODE_LUMA_DARKEN_ONLY: return blendfun_luminance_darken_only;
- case GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY: return blendfun_luminance_lighten_only;
- case GIMP_LAYER_MODE_VIVID_LIGHT: return blendfun_vivid_light;
- case GIMP_LAYER_MODE_PIN_LIGHT: return blendfun_pin_light;
- case GIMP_LAYER_MODE_LINEAR_LIGHT: return blendfun_linear_light;
- case GIMP_LAYER_MODE_HARD_MIX: return blendfun_hard_mix;
- case GIMP_LAYER_MODE_EXCLUSION: return blendfun_exclusion;
- case GIMP_LAYER_MODE_LINEAR_BURN: return blendfun_linear_burn;
- case GIMP_LAYER_MODE_COLOR_ERASE_LEGACY:
- case GIMP_LAYER_MODE_COLOR_ERASE: return blendfun_color_erase;
-
- case GIMP_LAYER_MODE_DISSOLVE:
- case GIMP_LAYER_MODE_BEHIND_LEGACY:
- case GIMP_LAYER_MODE_BEHIND:
- case GIMP_LAYER_MODE_MULTIPLY_LEGACY:
- case GIMP_LAYER_MODE_SCREEN_LEGACY:
- case GIMP_LAYER_MODE_OVERLAY_LEGACY:
- case GIMP_LAYER_MODE_DIFFERENCE_LEGACY:
- case GIMP_LAYER_MODE_ADDITION_LEGACY:
- case GIMP_LAYER_MODE_SUBTRACT_LEGACY:
- case GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY:
- case GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY:
- case GIMP_LAYER_MODE_HSV_HUE_LEGACY:
- case GIMP_LAYER_MODE_HSV_SATURATION_LEGACY:
- case GIMP_LAYER_MODE_HSL_COLOR_LEGACY:
- case GIMP_LAYER_MODE_HSV_VALUE_LEGACY:
- case GIMP_LAYER_MODE_DIVIDE_LEGACY:
- case GIMP_LAYER_MODE_DODGE_LEGACY:
- case GIMP_LAYER_MODE_BURN_LEGACY:
- case GIMP_LAYER_MODE_HARDLIGHT_LEGACY:
- case GIMP_LAYER_MODE_SOFTLIGHT_LEGACY:
- case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY:
- case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY:
- case GIMP_LAYER_MODE_ERASE:
- case GIMP_LAYER_MODE_MERGE:
- case GIMP_LAYER_MODE_SPLIT:
- case GIMP_LAYER_MODE_PASS_THROUGH:
- case GIMP_LAYER_MODE_REPLACE:
- case GIMP_LAYER_MODE_ANTI_ERASE:
- case GIMP_LAYER_MODE_SEPARATOR: /* to stop GCC from complaining :P */
- return blendfun_dummy;
- }
-
- return blendfun_dummy;
+ return GIMP_LAYER_COMPOSITE_REGION_INTERSECTION;
}
diff --git a/app/operations/layer-modes/gimpoperationlayermode.h
b/app/operations/layer-modes/gimpoperationlayermode.h
index c2b044f..0e8426c 100644
--- a/app/operations/layer-modes/gimpoperationlayermode.h
+++ b/app/operations/layer-modes/gimpoperationlayermode.h
@@ -35,20 +35,6 @@
typedef struct _GimpOperationLayerModeClass GimpOperationLayerModeClass;
-struct _GimpOperationLayerModeClass
-{
- GeglOperationPointComposer3Class parent_class;
-
- /* virtual functions */
-
- /* Returns the composite region (any combination of the layer and the
- * backdrop) that the layer mode affects. Most modes only affect the
- * overlapping region, which is what the function returns by default.
- */
- GimpLayerCompositeRegion (* get_affected_region) (GimpOperationLayerMode *layer_mode);
-};
-
-
struct _GimpOperationLayerMode
{
GeglOperationPointComposer3 parent_instance;
@@ -58,23 +44,38 @@ struct _GimpOperationLayerMode
GimpLayerColorSpace blend_space;
GimpLayerColorSpace composite_space;
GimpLayerCompositeMode composite_mode;
- GimpLayerModeFunc func;
+
+ GimpLayerCompositeMode real_composite_mode;
+ GimpLayerModeFunc function;
+ GimpLayerModeBlendFunc blend_function;
gboolean is_last_node;
};
+struct _GimpOperationLayerModeClass
+{
+ GeglOperationPointComposer3Class parent_class;
+
+ /* virtual functions */
+ gboolean (* process) (GeglOperation *operation,
+ void *in,
+ void *aux,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+ /* Returns the composite region (any combination of the layer and the
+ * backdrop) that the layer mode affects. Most modes only affect the
+ * overlapping region, and don't need to override this function.
+ */
+ GimpLayerCompositeRegion (* get_affected_region) (GimpOperationLayerMode *layer_mode);
+};
+
GType gimp_operation_layer_mode_get_type (void) G_GNUC_CONST;
GimpLayerCompositeRegion gimp_operation_layer_mode_get_affected_region (GimpOperationLayerMode *layer_mode);
-gboolean
-gimp_operation_layer_mode_process_pixels (GeglOperation *operation,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
#endif /* __GIMP_OPERATION_LAYER_MODE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationmerge.c b/app/operations/layer-modes/gimpoperationmerge.c
index d13e231..736d114 100644
--- a/app/operations/layer-modes/gimpoperationmerge.c
+++ b/app/operations/layer-modes/gimpoperationmerge.c
@@ -28,6 +28,16 @@
#include "gimpoperationmerge.h"
+static gboolean gimp_operation_merge_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationMerge, gimp_operation_merge,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationMerge, gimp_operation_merge,
static void
gimp_operation_merge_class_init (GimpOperationMergeClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:merge",
"description", "GIMP merge mode operation",
NULL);
- point_class->process = gimp_operation_merge_process;
+ layer_mode_class->process = gimp_operation_merge_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_merge_init (GimpOperationMerge *self)
{
}
-gboolean
+static gboolean
gimp_operation_merge_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -72,7 +79,7 @@ gimp_operation_merge_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
diff --git a/app/operations/layer-modes/gimpoperationmerge.h b/app/operations/layer-modes/gimpoperationmerge.h
index 8734e8c..8393398 100644
--- a/app/operations/layer-modes/gimpoperationmerge.h
+++ b/app/operations/layer-modes/gimpoperationmerge.h
@@ -48,16 +48,7 @@ struct _GimpOperationMergeClass
};
-GType gimp_operation_merge_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_merge_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_merge_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_MERGE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationnormal-sse2.c
b/app/operations/layer-modes/gimpoperationnormal-sse2.c
index b4396be..60bd847 100644
--- a/app/operations/layer-modes/gimpoperationnormal-sse2.c
+++ b/app/operations/layer-modes/gimpoperationnormal-sse2.c
@@ -32,55 +32,56 @@
/* SSE2 */
#include <emmintrin.h>
+
gboolean
-gimp_operation_normal_process_sse2 (GeglOperation *operation,
- void *in,
- void *aux,
+gimp_operation_normal_process_sse2 (GeglOperation *op,
+ void *in_p,
+ void *layer_p,
void *mask_p,
- void *out,
+ void *out_p,
glong samples,
const GeglRectangle *roi,
gint level)
{
/* check alignment */
- if ((((uintptr_t)in) | ((uintptr_t)aux) | ((uintptr_t)out)) & 0x0F)
+ if ((((uintptr_t)in_p) | ((uintptr_t)layer_p) | ((uintptr_t)out_p)) & 0x0F)
{
- return gimp_operation_normal_process_core (operation, in, aux, mask_p, out,
- samples,
- roi, level);
+ return gimp_operation_normal_process (op,
+ in_p, layer_p, mask_p, out_p,
+ samples, roi, level);
}
else
{
- GimpOperationLayerMode *layer_mode = (GimpOperationLayerMode *) operation;
- gfloat opacity = layer_mode->opacity;
- gfloat *mask = mask_p;
- const __v4sf *v_in = (const __v4sf*) in;
- const __v4sf *v_aux = (const __v4sf*) aux;
- __v4sf *v_out = ( __v4sf*) out;
+ GimpOperationLayerMode *layer_mode = (gpointer) op;
+ gfloat opacity = layer_mode->opacity;
+ gfloat *mask = mask_p;
+ const __v4sf *v_in = (const __v4sf*) in_p;
+ const __v4sf *v_layer = (const __v4sf*) layer_p;
+ __v4sf *v_out = ( __v4sf*) out_p;
const __v4sf one = _mm_set1_ps (1.0f);
const __v4sf v_opacity = _mm_set1_ps (opacity);
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -99,7 +100,7 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
a_term = dst_alpha * (one - alpha);
/* out(color) = src * src_a + dst * a_term */
- out_pixel = rgba_aux * alpha + rgba_in * a_term;
+ out_pixel = rgba_layer * alpha + rgba_in * a_term;
/* out(alpha) = 1.0 * src_a + 1.0 * a_term */
out_alpha = alpha + a_term;
@@ -123,20 +124,20 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
case GIMP_LAYER_COMPOSITE_SRC_ATOP:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -152,7 +153,7 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
_MM_SHUFFLE (3, 3, 3, 3));
/* out(color) = dst * (1 - src_a) + src * src_a */
- out_pixel = rgba_in + (rgba_aux - rgba_in) * alpha;
+ out_pixel = rgba_in + (rgba_layer - rgba_in) * alpha;
/* swap in the real alpha */
out_pixel_rbaa = _mm_shuffle_ps (out_pixel, dst_alpha, _MM_SHUFFLE (3, 3, 2, 0));
@@ -170,21 +171,21 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
case GIMP_LAYER_COMPOSITE_DST_ATOP:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
__v4sf out_pixel, out_pixel_rbaa;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -194,7 +195,7 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
{
/* out(color) = src */
- out_pixel = rgba_aux;
+ out_pixel = rgba_layer;
}
else
{
@@ -212,21 +213,21 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
case GIMP_LAYER_COMPOSITE_SRC_IN:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
__v4sf out_pixel, out_pixel_rbaa;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -240,7 +241,7 @@ gimp_operation_normal_process_sse2 (GeglOperation *operation,
if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
{
/* out(color) = src */
- out_pixel = rgba_aux;
+ out_pixel = rgba_layer;
}
else
{
diff --git a/app/operations/layer-modes/gimpoperationnormal-sse4.c
b/app/operations/layer-modes/gimpoperationnormal-sse4.c
index 72825cf..c52763b 100644
--- a/app/operations/layer-modes/gimpoperationnormal-sse4.c
+++ b/app/operations/layer-modes/gimpoperationnormal-sse4.c
@@ -32,56 +32,56 @@
/* SSE4 */
#include <smmintrin.h>
+
gboolean
-gimp_operation_normal_process_sse4 (GeglOperation *operation,
- void *in,
- void *aux,
+gimp_operation_normal_process_sse4 (GeglOperation *op,
+ void *in_p,
+ void *layer_p,
void *mask_p,
- void *out,
+ void *out_p,
glong samples,
const GeglRectangle *roi,
gint level)
{
/* check alignment */
- if ((((uintptr_t)in) | ((uintptr_t)aux) | ((uintptr_t)out)) & 0x0F)
+ if ((((uintptr_t)in_p) | ((uintptr_t)layer_p) | ((uintptr_t)out_p)) & 0x0F)
{
- return gimp_operation_normal_process_core (operation,
- in, aux, mask_p, out,
- samples,
- roi, level);
+ return gimp_operation_normal_process (op,
+ in_p, layer_p, mask_p, out_p,
+ samples, roi, level);
}
else
{
- GimpOperationLayerMode *layer_mode = (GimpOperationLayerMode *) operation;
- gfloat opacity = layer_mode->opacity;
- gfloat *mask = mask_p;
- const __v4sf *v_in = (const __v4sf*) in;
- const __v4sf *v_aux = (const __v4sf*) aux;
- __v4sf *v_out = ( __v4sf*) out;
+ GimpOperationLayerMode *layer_mode = (gpointer) op;
+ gfloat opacity = layer_mode->opacity;
+ gfloat *mask = mask_p;
+ const __v4sf *v_in = (const __v4sf*) in_p;
+ const __v4sf *v_layer = (const __v4sf*) layer_p;
+ __v4sf *v_out = ( __v4sf*) out_p;
const __v4sf one = _mm_set1_ps (1.0f);
const __v4sf v_opacity = _mm_set1_ps (opacity);
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -100,7 +100,7 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
a_term = dst_alpha * (one - alpha);
/* out(color) = src * src_a + dst * a_term */
- out_pixel = rgba_aux * alpha + rgba_in * a_term;
+ out_pixel = rgba_layer * alpha + rgba_in * a_term;
/* out(alpha) = 1.0 * src_a + 1.0 * a_term */
out_alpha = alpha + a_term;
@@ -123,20 +123,20 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
case GIMP_LAYER_COMPOSITE_SRC_ATOP:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -152,7 +152,7 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
_MM_SHUFFLE (3, 3, 3, 3));
/* out(color) = dst * (1 - src_a) + src * src_a */
- out_pixel = rgba_in + (rgba_aux - rgba_in) * alpha;
+ out_pixel = rgba_in + (rgba_layer - rgba_in) * alpha;
/* swap in the real alpha */
out_pixel = _mm_blend_ps (out_pixel, dst_alpha, 0x08);
@@ -169,21 +169,21 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
case GIMP_LAYER_COMPOSITE_DST_ATOP:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
__v4sf out_pixel;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -193,7 +193,7 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
{
/* out(color) = src */
- out_pixel = rgba_aux;
+ out_pixel = rgba_layer;
}
else
{
@@ -210,21 +210,21 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
case GIMP_LAYER_COMPOSITE_SRC_IN:
while (samples--)
{
- __v4sf rgba_in, rgba_aux, alpha;
+ __v4sf rgba_in, rgba_layer, alpha;
__v4sf out_pixel;
- rgba_in = *v_in++;
- rgba_aux = *v_aux++;
+ rgba_in = *v_in++;
+ rgba_layer = *v_layer++;
/* expand alpha */
- alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_aux,
+ alpha = (__v4sf)_mm_shuffle_epi32 ((__m128i)rgba_layer,
_MM_SHUFFLE (3, 3, 3, 3));
if (mask)
{
__v4sf mask_alpha;
- /* multiply aux's alpha by the mask */
+ /* multiply layer's alpha by the mask */
mask_alpha = _mm_set1_ps (*mask++);
alpha = alpha * mask_alpha;
}
@@ -238,7 +238,7 @@ gimp_operation_normal_process_sse4 (GeglOperation *operation,
if (_mm_ucomigt_ss (alpha, _mm_setzero_ps ()))
{
/* out(color) = src */
- out_pixel = rgba_aux;
+ out_pixel = rgba_layer;
}
else
{
diff --git a/app/operations/layer-modes/gimpoperationnormal.c
b/app/operations/layer-modes/gimpoperationnormal.c
index 30870a7..4caea70 100644
--- a/app/operations/layer-modes/gimpoperationnormal.c
+++ b/app/operations/layer-modes/gimpoperationnormal.c
@@ -33,8 +33,6 @@
G_DEFINE_TYPE (GimpOperationNormal, gimp_operation_normal,
GIMP_TYPE_OPERATION_LAYER_MODE)
-#define parent_class gimp_operation_normal_parent_class
-
static const gchar* reference_xml = "<?xml version='1.0' encoding='UTF-8'?>"
"<gegl>"
@@ -52,17 +50,12 @@ static const gchar* reference_xml = "<?xml version='1.0' encoding='UTF-8'?>"
"</node>"
"</gegl>";
-static GimpLayerModeFunc _gimp_operation_normal_process = NULL;
-
static void
gimp_operation_normal_class_init (GimpOperationNormalClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:normal",
@@ -71,19 +64,17 @@ gimp_operation_normal_class_init (GimpOperationNormalClass *klass)
"reference-composition", reference_xml,
NULL);
- _gimp_operation_normal_process = gimp_operation_normal_process_core;
+ layer_mode_class->process = gimp_operation_normal_process;
#if COMPILE_SSE2_INTRINISICS
if (gimp_cpu_accel_get_support() & GIMP_CPU_ACCEL_X86_SSE2)
- _gimp_operation_normal_process = gimp_operation_normal_process_sse2;
+ layer_mode_class->process = gimp_operation_normal_process_sse2;
#endif /* COMPILE_SSE2_INTRINISICS */
#if COMPILE_SSE4_1_INTRINISICS
if (gimp_cpu_accel_get_support() & GIMP_CPU_ACCEL_X86_SSE4_1)
- _gimp_operation_normal_process = gimp_operation_normal_process_sse4;
+ layer_mode_class->process = gimp_operation_normal_process_sse4;
#endif /* COMPILE_SSE4_1_INTRINISICS */
-
- point_class->process = gimp_operation_normal_process;
}
static void
@@ -93,28 +84,14 @@ gimp_operation_normal_init (GimpOperationNormal *self)
gboolean
gimp_operation_normal_process (GeglOperation *op,
- void *in,
- void *aux,
- void *mask,
- void *out,
+ void *in_p,
+ void *layer_p,
+ void *mask_p,
+ void *out_p,
glong samples,
const GeglRectangle *roi,
gint level)
{
- return _gimp_operation_normal_process (op, in, aux, mask, out,
- samples, roi, level);
-}
-
-gboolean
-gimp_operation_normal_process_core (GeglOperation *op,
- void *in_p,
- void *layer_p,
- void *mask_p,
- void *out_p,
- glong samples,
- const GeglRectangle *roi,
- gint level)
-{
GimpOperationLayerMode *layer_mode = (gpointer) op;
gfloat *in = in_p;
gfloat *out = out_p;
@@ -123,7 +100,7 @@ gimp_operation_normal_process_core (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
diff --git a/app/operations/layer-modes/gimpoperationnormal.h
b/app/operations/layer-modes/gimpoperationnormal.h
index ccd014c..4d24fb8 100644
--- a/app/operations/layer-modes/gimpoperationnormal.h
+++ b/app/operations/layer-modes/gimpoperationnormal.h
@@ -47,43 +47,45 @@ struct _GimpOperationNormalClass
};
-GType gimp_operation_normal_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_normal_process (GeglOperation *op,
- void *in,
- void *aux,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
-
-gboolean gimp_operation_normal_process_core (GeglOperation *op,
- void *in,
- void *aux,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
-
-gboolean gimp_operation_normal_process_sse2 (GeglOperation *op,
- void *in,
- void *aux,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
-
-gboolean gimp_operation_normal_process_sse4 (GeglOperation *op,
- void *in,
- void *aux,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_normal_get_type (void) G_GNUC_CONST;
+
+
+/* protected */
+
+gboolean gimp_operation_normal_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+#if COMPILE_SSE2_INTRINISICS
+
+gboolean gimp_operation_normal_process_sse2 (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+#endif /* COMPILE_SSE2_INTRINISICS */
+
+#if COMPILE_SSE4_1_INTRINISICS
+
+gboolean gimp_operation_normal_process_sse4 (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+#endif /* COMPILE_SSE4_1_INTRINISICS */
#endif /* __GIMP_OPERATION_NORMAL_H__ */
diff --git a/app/operations/layer-modes/gimpoperationreplace.c
b/app/operations/layer-modes/gimpoperationreplace.c
index f82eac5..db7e4ce 100644
--- a/app/operations/layer-modes/gimpoperationreplace.c
+++ b/app/operations/layer-modes/gimpoperationreplace.c
@@ -27,7 +27,15 @@
#include "gimpoperationreplace.h"
-static GimpLayerCompositeRegion gimp_operation_replace_get_affected_region (GimpOperationLayerMode
*layer_mode);
+static gboolean gimp_operation_replace_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong
samples,
+ const GeglRectangle *roi,
+ gint level);
+static GimpLayerCompositeRegion gimp_operation_replace_get_affected_region (GimpOperationLayerMode
*layer_mode);
G_DEFINE_TYPE (GimpOperationReplace, gimp_operation_replace,
@@ -37,21 +45,15 @@ G_DEFINE_TYPE (GimpOperationReplace, gimp_operation_replace,
static void
gimp_operation_replace_class_init (GimpOperationReplaceClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
- GimpOperationLayerModeClass *layer_mode_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
- layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:replace",
"description", "GIMP replace mode operation",
NULL);
- point_class->process = gimp_operation_replace_process;
-
+ layer_mode_class->process = gimp_operation_replace_process;
layer_mode_class->get_affected_region = gimp_operation_replace_get_affected_region;
}
@@ -60,7 +62,7 @@ gimp_operation_replace_init (GimpOperationReplace *self)
{
}
-gboolean
+static gboolean
gimp_operation_replace_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -78,7 +80,7 @@ gimp_operation_replace_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
case GIMP_LAYER_COMPOSITE_AUTO:
diff --git a/app/operations/layer-modes/gimpoperationreplace.h
b/app/operations/layer-modes/gimpoperationreplace.h
index 37d30fa..0615a3b 100644
--- a/app/operations/layer-modes/gimpoperationreplace.h
+++ b/app/operations/layer-modes/gimpoperationreplace.h
@@ -47,16 +47,7 @@ struct _GimpOperationReplaceClass
};
-GType gimp_operation_replace_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_replace_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_replace_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_REPLACE_H__ */
diff --git a/app/operations/layer-modes/gimpoperationsplit.c b/app/operations/layer-modes/gimpoperationsplit.c
index 3a22374..22f7f1a 100644
--- a/app/operations/layer-modes/gimpoperationsplit.c
+++ b/app/operations/layer-modes/gimpoperationsplit.c
@@ -28,6 +28,16 @@
#include "gimpoperationsplit.h"
+static gboolean gimp_operation_split_process (GeglOperation *op,
+ void *in,
+ void *layer,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+
G_DEFINE_TYPE (GimpOperationSplit, gimp_operation_split,
GIMP_TYPE_OPERATION_LAYER_MODE)
@@ -35,18 +45,15 @@ G_DEFINE_TYPE (GimpOperationSplit, gimp_operation_split,
static void
gimp_operation_split_class_init (GimpOperationSplitClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationPointComposer3Class *point_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GimpOperationLayerModeClass *layer_mode_class = GIMP_OPERATION_LAYER_MODE_CLASS (klass);
gegl_operation_class_set_keys (operation_class,
"name", "gimp:split",
"description", "GIMP split mode operation",
NULL);
- point_class->process = gimp_operation_split_process;
+ layer_mode_class->process = gimp_operation_split_process;
}
static void
@@ -54,7 +61,7 @@ gimp_operation_split_init (GimpOperationSplit *self)
{
}
-gboolean
+static gboolean
gimp_operation_split_process (GeglOperation *op,
void *in_p,
void *layer_p,
@@ -72,7 +79,7 @@ gimp_operation_split_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL;
- switch (layer_mode->composite_mode)
+ switch (layer_mode->real_composite_mode)
{
case GIMP_LAYER_COMPOSITE_SRC_OVER:
while (samples--)
diff --git a/app/operations/layer-modes/gimpoperationsplit.h b/app/operations/layer-modes/gimpoperationsplit.h
index 377297f..bb82130 100644
--- a/app/operations/layer-modes/gimpoperationsplit.h
+++ b/app/operations/layer-modes/gimpoperationsplit.h
@@ -48,16 +48,7 @@ struct _GimpOperationSplitClass
};
-GType gimp_operation_split_get_type (void) G_GNUC_CONST;
-
-gboolean gimp_operation_split_process (GeglOperation *op,
- void *in,
- void *layer,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
+GType gimp_operation_split_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_OPERATION_SPLIT_H__ */
diff --git a/app/operations/operations-types.h b/app/operations/operations-types.h
index b1ca7b7..911873e 100644
--- a/app/operations/operations-types.h
+++ b/app/operations/operations-types.h
@@ -55,19 +55,19 @@ typedef struct _GimpCagePoint GimpCagePoint;
/* functions */
-typedef gboolean (* GimpLayerModeFunc) (GeglOperation *operation,
- void *in,
- void *aux,
- void *mask,
- void *out,
- glong samples,
- const GeglRectangle *roi,
- gint level);
-
-typedef void (* GimpBlendFunc) (const float *dest,
- const float *src,
- float *out,
- gint samples);
+typedef gboolean (* GimpLayerModeFunc) (GeglOperation *operation,
+ void *in,
+ void *aux,
+ void *mask,
+ void *out,
+ glong samples,
+ const GeglRectangle *roi,
+ gint level);
+
+typedef void (* GimpLayerModeBlendFunc) (const gfloat *in,
+ const gfloat *layer,
+ gfloat *out,
+ gint samples);
#endif /* __OPERATIONS_TYPES_H__ */
diff --git a/app/paint/gimppaintcore-loops.c b/app/paint/gimppaintcore-loops.c
index b8e2eb7..9551b97 100644
--- a/app/paint/gimppaintcore-loops.c
+++ b/app/paint/gimppaintcore-loops.c
@@ -305,21 +305,23 @@ do_layer_blend (GeglBuffer *src_buffer,
GeglBufferIterator *iter;
guint paint_stride;
gfloat *paint_data;
- GimpLayerModeFunc apply_func;
- GimpLayerColorSpace blend_space;
- GimpLayerColorSpace composite_space;
- GimpLayerCompositeMode composite_mode;
+ GimpOperationLayerMode layer_mode;
paint_stride = gimp_temp_buf_get_width (paint_buf);
paint_data = (gfloat *) gimp_temp_buf_get_data (paint_buf);
- apply_func = gimp_layer_mode_get_function (paint_mode);
- blend_space = gimp_layer_mode_get_blend_space (paint_mode);
- composite_space = gimp_layer_mode_get_composite_space (paint_mode);
- composite_mode = gimp_layer_mode_get_paint_composite_mode (paint_mode);
+ layer_mode.layer_mode = paint_mode;
+ layer_mode.opacity = opacity;
+ layer_mode.function = gimp_layer_mode_get_function (paint_mode);
+ layer_mode.blend_function = gimp_layer_mode_get_blend_function (paint_mode);
+ layer_mode.blend_space = gimp_layer_mode_get_blend_space (paint_mode);
+ layer_mode.composite_space = gimp_layer_mode_get_composite_space (paint_mode);
+ layer_mode.composite_mode = gimp_layer_mode_get_paint_composite_mode (paint_mode);
+ layer_mode.real_composite_mode = layer_mode.composite_mode;
iterator_format = gimp_layer_mode_get_format (paint_mode,
- composite_space, blend_space,
+ layer_mode.composite_space,
+ layer_mode.blend_space,
gegl_buffer_get_format (src_buffer));
roi.x = x_offset;
@@ -351,21 +353,14 @@ do_layer_blend (GeglBuffer *src_buffer,
while (gegl_buffer_iterator_next (iter))
{
- GimpOperationLayerMode layer_data;
- gfloat *out_pixel = (gfloat *) iter->data[0];
- gfloat *in_pixel = (gfloat *) iter->data[1];
- gfloat *mask_pixel = NULL;
- gfloat *paint_pixel;
- gint iy;
+ gfloat *out_pixel = (gfloat *) iter->data[0];
+ gfloat *in_pixel = (gfloat *) iter->data[1];
+ gfloat *mask_pixel = NULL;
+ gfloat *paint_pixel;
+ gint iy;
paint_pixel = paint_data + ((iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x - roi.x) * 4;
- layer_data.layer_mode = paint_mode;
- layer_data.opacity = opacity;
- layer_data.blend_space = blend_space;
- layer_data.composite_space = composite_space;
- layer_data.composite_mode = composite_mode;
-
if (mask_buffer)
mask_pixel = (gfloat *)iter->data[2];
@@ -373,19 +368,18 @@ do_layer_blend (GeglBuffer *src_buffer,
process_roi.width = iter->roi[0].width;
process_roi.height = 1;
-
for (iy = 0; iy < iter->roi[0].height; iy++)
{
process_roi.y = iter->roi[0].y + iy;
- (*apply_func) ((GeglOperation*)&layer_data,
- in_pixel,
- paint_pixel,
- mask_pixel,
- out_pixel,
- iter->roi[0].width,
- &process_roi,
- 0);
+ layer_mode.function ((GeglOperation*) &layer_mode,
+ in_pixel,
+ paint_pixel,
+ mask_pixel,
+ out_pixel,
+ iter->roi[0].width,
+ &process_roi,
+ 0);
in_pixel += iter->roi[0].width * 4;
out_pixel += iter->roi[0].width * 4;
diff --git a/app/tests/Makefile.am b/app/tests/Makefile.am
index 9254bd3..547a3fa 100644
--- a/app/tests/Makefile.am
+++ b/app/tests/Makefile.am
@@ -103,9 +103,9 @@ LDADD = \
../config/libappconfig.a \
../libapp.a \
../gegl/libappgegl.a \
+ ../operations/libappoperations.a \
../operations/layer-modes/libapplayermodes.a \
../operations/layer-modes-legacy/libapplayermodeslegacy.a \
- ../operations/libappoperations.a \
libgimpapptestutils.a \
$(libgimpwidgets) \
$(libgimpconfig) \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]