[gimp] app: implement non-legacy blend modes in GimpOperationLayerMode
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: implement non-legacy blend modes in GimpOperationLayerMode
- Date: Mon, 23 Jan 2017 22:48:59 +0000 (UTC)
commit d836d94114380c38867b071b14fdd1203f932849
Author: Øyvind Kolås <pippin gimp org>
Date: Sun Jan 22 19:48:49 2017 +0100
app: implement non-legacy blend modes in GimpOperationLayerMode
For operations needing to override default behavior sub-classes should still be
used.
This commit also enables pinligh, vividlight and linearlight blend mode modes
app/core/core-enums.c | 20 +
app/core/core-enums.h | 10 +
app/core/gimp-layer-modes.c | 122 +--
app/operations/gimp-operations.c | 48 +-
app/operations/layer-modes/Makefile.am | 49 +-
app/operations/layer-modes/gimpblendcomposite.h | 1271 ------------------
.../layer-modes/gimplayermodefunctions.c | 131 +--
app/operations/layer-modes/gimpoperationaddition.c | 73 --
app/operations/layer-modes/gimpoperationaddition.h | 63 -
app/operations/layer-modes/gimpoperationburn.c | 72 --
app/operations/layer-modes/gimpoperationburn.h | 63 -
.../layer-modes/gimpoperationdarkenonly.c | 72 --
.../layer-modes/gimpoperationdarkenonly.h | 63 -
.../layer-modes/gimpoperationdifference.c | 72 --
.../layer-modes/gimpoperationdifference.h | 63 -
app/operations/layer-modes/gimpoperationdivide.c | 72 --
app/operations/layer-modes/gimpoperationdivide.h | 63 -
app/operations/layer-modes/gimpoperationdodge.c | 72 --
app/operations/layer-modes/gimpoperationdodge.h | 63 -
.../layer-modes/gimpoperationgrainextract.c | 72 --
.../layer-modes/gimpoperationgrainextract.h | 63 -
.../layer-modes/gimpoperationgrainmerge.c | 72 --
.../layer-modes/gimpoperationgrainmerge.h | 63 -
.../layer-modes/gimpoperationhardlight.c | 71 -
.../layer-modes/gimpoperationhardlight.h | 62 -
app/operations/layer-modes/gimpoperationhsvcolor.c | 76 --
app/operations/layer-modes/gimpoperationhsvcolor.h | 63 -
app/operations/layer-modes/gimpoperationhsvhue.c | 76 --
app/operations/layer-modes/gimpoperationhsvhue.h | 63 -
.../layer-modes/gimpoperationhsvsaturation.c | 76 --
.../layer-modes/gimpoperationhsvsaturation.h | 63 -
app/operations/layer-modes/gimpoperationhsvvalue.c | 76 --
app/operations/layer-modes/gimpoperationhsvvalue.h | 63 -
.../layer-modes/gimpoperationlayermode.c | 1348 +++++++++++++++++++-
.../layer-modes/gimpoperationlayermode.h | 9 +
.../layer-modes/gimpoperationlchchroma.c | 75 --
.../layer-modes/gimpoperationlchchroma.h | 64 -
app/operations/layer-modes/gimpoperationlchcolor.c | 75 --
app/operations/layer-modes/gimpoperationlchcolor.h | 64 -
app/operations/layer-modes/gimpoperationlchhue.c | 75 --
app/operations/layer-modes/gimpoperationlchhue.h | 64 -
.../layer-modes/gimpoperationlchlightness.c | 75 --
.../layer-modes/gimpoperationlchlightness.h | 64 -
.../layer-modes/gimpoperationlightenonly.c | 72 --
.../layer-modes/gimpoperationlightenonly.h | 63 -
app/operations/layer-modes/gimpoperationmultiply.c | 72 --
app/operations/layer-modes/gimpoperationmultiply.h | 63 -
app/operations/layer-modes/gimpoperationoverlay.c | 71 -
app/operations/layer-modes/gimpoperationoverlay.h | 62 -
app/operations/layer-modes/gimpoperationscreen.c | 72 --
app/operations/layer-modes/gimpoperationscreen.h | 62 -
.../layer-modes/gimpoperationsoftlight.c | 90 --
.../layer-modes/gimpoperationsoftlight.h | 62 -
app/operations/layer-modes/gimpoperationsubtract.c | 72 --
app/operations/layer-modes/gimpoperationsubtract.h | 63 -
app/widgets/gimpwidgets-constructors.c | 9 +-
libgimp/gimpenums.h | 12 +-
tools/pdbgen/enums.pl | 24 +-
58 files changed, 1460 insertions(+), 4743 deletions(-)
---
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 3e7b530..12e2e80 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -352,6 +352,16 @@ gimp_layer_mode_get_type (void)
{ GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR, "GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR", "grain-extract-linear" },
{ GIMP_LAYER_MODE_GRAIN_MERGE, "GIMP_LAYER_MODE_GRAIN_MERGE", "grain-merge" },
{ GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR, "GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR", "grain-merge-linear" },
+ { GIMP_LAYER_MODE_VIVID_LIGHT, "GIMP_LAYER_MODE_VIVID_LIGHT", "vivid-light" },
+ { GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR, "GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR", "vivid-light-linear" },
+ { GIMP_LAYER_MODE_PIN_LIGHT, "GIMP_LAYER_MODE_PIN_LIGHT", "pin-light" },
+ { GIMP_LAYER_MODE_PIN_LIGHT_LINEAR, "GIMP_LAYER_MODE_PIN_LIGHT_LINEAR", "pin-light-linear" },
+ { GIMP_LAYER_MODE_LINEAR_LIGHT, "GIMP_LAYER_MODE_LINEAR_LIGHT", "linear-light" },
+ { GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR, "GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR", "linear-light-linear" },
+ { GIMP_LAYER_MODE_EXCLUSION, "GIMP_LAYER_MODE_EXCLUSION", "exclusion" },
+ { GIMP_LAYER_MODE_EXCLUSION_LINEAR, "GIMP_LAYER_MODE_EXCLUSION_LINEAR", "exclusion-linear" },
+ { GIMP_LAYER_MODE_LINEAR_BURN, "GIMP_LAYER_MODE_LINEAR_BURN", "linear-burn" },
+ { GIMP_LAYER_MODE_LINEAR_BURN_LINEAR, "GIMP_LAYER_MODE_LINEAR_BURN_LINEAR", "linear-burn-linear" },
{ GIMP_LAYER_MODE_ERASE, "GIMP_LAYER_MODE_ERASE", "erase" },
{ GIMP_LAYER_MODE_REPLACE, "GIMP_LAYER_MODE_REPLACE", "replace" },
{ GIMP_LAYER_MODE_ANTI_ERASE, "GIMP_LAYER_MODE_ANTI_ERASE", "anti-erase" },
@@ -423,6 +433,16 @@ gimp_layer_mode_get_type (void)
{ GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR, NC_("layer-mode", "Grain extract (linear)"), NULL },
{ GIMP_LAYER_MODE_GRAIN_MERGE, NC_("layer-mode", "Grain merge"), NULL },
{ GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR, NC_("layer-mode", "Grain merge (linear)"), NULL },
+ { GIMP_LAYER_MODE_VIVID_LIGHT, NC_("layer-mode", "Vivid light"), NULL },
+ { GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR, NC_("layer-mode", "Vivid light (linear)"), NULL },
+ { GIMP_LAYER_MODE_PIN_LIGHT, NC_("layer-mode", "Pin light"), NULL },
+ { GIMP_LAYER_MODE_PIN_LIGHT_LINEAR, NC_("layer-mode", "Pin light (linear)"), NULL },
+ { GIMP_LAYER_MODE_LINEAR_LIGHT, NC_("layer-mode", "Linear light"), NULL },
+ { GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR, NC_("layer-mode", "Linear light (linear)"), NULL },
+ { GIMP_LAYER_MODE_EXCLUSION, NC_("layer-mode", "Exclusion"), NULL },
+ { GIMP_LAYER_MODE_EXCLUSION_LINEAR, NC_("layer-mode", "Exclusion (linear)"), NULL },
+ { GIMP_LAYER_MODE_LINEAR_BURN, NC_("layer-mode", "Linear light"), NULL },
+ { GIMP_LAYER_MODE_LINEAR_BURN_LINEAR, NC_("layer-mode", "Linear burn (linear)"), NULL },
{ GIMP_LAYER_MODE_ERASE, NC_("layer-mode", "Erase"), NULL },
{ GIMP_LAYER_MODE_REPLACE, NC_("layer-mode", "Replace"), NULL },
{ GIMP_LAYER_MODE_ANTI_ERASE, NC_("layer-mode", "Anti erase"), NULL },
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 4b2ae31..acd103f 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -222,6 +222,16 @@ typedef enum
GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR, /*< desc="Grain extract (linear)" >*/
GIMP_LAYER_MODE_GRAIN_MERGE, /*< desc="Grain merge" >*/
GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR, /*< desc="Grain merge (linear)" >*/
+ GIMP_LAYER_MODE_VIVID_LIGHT, /*< desc="Vivid light" >*/
+ GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR, /*< desc="Vivid light (linear)" >*/
+ GIMP_LAYER_MODE_PIN_LIGHT, /*< desc="Pin light" >*/
+ GIMP_LAYER_MODE_PIN_LIGHT_LINEAR, /*< desc="Pin light (linear)" >*/
+ GIMP_LAYER_MODE_LINEAR_LIGHT, /*< desc="Linear light" >*/
+ GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR, /*< desc="Linear light (linear)" >*/
+ GIMP_LAYER_MODE_EXCLUSION, /*< desc="Exclusion" >*/
+ GIMP_LAYER_MODE_EXCLUSION_LINEAR, /*< desc="Exclusion (linear)" >*/
+ GIMP_LAYER_MODE_LINEAR_BURN, /*< desc="Linear light" >*/
+ GIMP_LAYER_MODE_LINEAR_BURN_LINEAR, /*< desc="Linear burn (linear)" >*/
/* Internal modes, not available to the PDB */
GIMP_LAYER_MODE_ERASE = 1000, /*< pdb-skip, desc="Erase" >*/
diff --git a/app/core/gimp-layer-modes.c b/app/core/gimp-layer-modes.c
index b4508b3..488e493 100644
--- a/app/core/gimp-layer-modes.c
+++ b/app/core/gimp-layer-modes.c
@@ -128,6 +128,11 @@ gimp_layer_mode_is_linear (GimpLayerMode mode)
case GIMP_LAYER_MODE_SOFTLIGHT:
case GIMP_LAYER_MODE_GRAIN_EXTRACT:
case GIMP_LAYER_MODE_GRAIN_MERGE:
+ case GIMP_LAYER_MODE_VIVID_LIGHT:
+ case GIMP_LAYER_MODE_PIN_LIGHT:
+ case GIMP_LAYER_MODE_LINEAR_LIGHT:
+ case GIMP_LAYER_MODE_EXCLUSION:
+ case GIMP_LAYER_MODE_LINEAR_BURN:
return TRUE;
case GIMP_LAYER_MODE_BEHIND_LINEAR:
@@ -146,6 +151,11 @@ gimp_layer_mode_is_linear (GimpLayerMode mode)
case GIMP_LAYER_MODE_SOFTLIGHT_LINEAR:
case GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR:
case GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR:
+ case GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_PIN_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_EXCLUSION_LINEAR:
+ case GIMP_LAYER_MODE_LINEAR_BURN_LINEAR:
return TRUE;
case GIMP_LAYER_MODE_ERASE:
@@ -158,7 +168,7 @@ gimp_layer_mode_is_linear (GimpLayerMode mode)
return TRUE;
}
- return FALSE;
+ return TRUE;
}
GimpLayerColorSpace
@@ -227,6 +237,11 @@ gimp_layer_mode_get_blend_space (GimpLayerMode mode)
case GIMP_LAYER_MODE_SOFTLIGHT:
case GIMP_LAYER_MODE_GRAIN_EXTRACT:
case GIMP_LAYER_MODE_GRAIN_MERGE:
+ case GIMP_LAYER_MODE_VIVID_LIGHT:
+ case GIMP_LAYER_MODE_PIN_LIGHT:
+ case GIMP_LAYER_MODE_LINEAR_LIGHT:
+ case GIMP_LAYER_MODE_EXCLUSION:
+ case GIMP_LAYER_MODE_LINEAR_BURN:
return GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL;
case GIMP_LAYER_MODE_BEHIND_LINEAR:
@@ -245,6 +260,11 @@ gimp_layer_mode_get_blend_space (GimpLayerMode mode)
case GIMP_LAYER_MODE_SOFTLIGHT_LINEAR:
case GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR:
case GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR:
+ case GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_PIN_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_EXCLUSION_LINEAR:
+ case GIMP_LAYER_MODE_LINEAR_BURN_LINEAR:
return GIMP_LAYER_COLOR_SPACE_RGB_LINEAR;
case GIMP_LAYER_MODE_ERASE:
@@ -328,6 +348,11 @@ gimp_layer_mode_get_composite_mode (GimpLayerMode mode)
case GIMP_LAYER_MODE_SOFTLIGHT:
case GIMP_LAYER_MODE_GRAIN_EXTRACT:
case GIMP_LAYER_MODE_GRAIN_MERGE:
+ case GIMP_LAYER_MODE_VIVID_LIGHT:
+ case GIMP_LAYER_MODE_PIN_LIGHT:
+ case GIMP_LAYER_MODE_LINEAR_LIGHT:
+ case GIMP_LAYER_MODE_EXCLUSION:
+ case GIMP_LAYER_MODE_LINEAR_BURN:
return GIMP_LAYER_COMPOSITE_SRC_ATOP;
case GIMP_LAYER_MODE_BEHIND_LINEAR:
@@ -346,6 +371,11 @@ gimp_layer_mode_get_composite_mode (GimpLayerMode mode)
case GIMP_LAYER_MODE_SOFTLIGHT_LINEAR:
case GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR:
case GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR:
+ case GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_PIN_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR:
+ case GIMP_LAYER_MODE_EXCLUSION_LINEAR:
+ case GIMP_LAYER_MODE_LINEAR_BURN_LINEAR:
return GIMP_LAYER_COMPOSITE_SRC_ATOP;
case GIMP_LAYER_MODE_ERASE:
@@ -376,147 +406,64 @@ gimp_layer_mode_get_operation (GimpLayerMode mode)
case GIMP_LAYER_MODE_MULTIPLY_LEGACY:
return "gimp:multiply-legacy";
- case GIMP_LAYER_MODE_MULTIPLY:
- case GIMP_LAYER_MODE_MULTIPLY_LINEAR:
- return "gimp:multiply";
-
case GIMP_LAYER_MODE_SCREEN_LEGACY:
return "gimp:screen-legacy";
- case GIMP_LAYER_MODE_SCREEN:
- case GIMP_LAYER_MODE_SCREEN_LINEAR:
- return "gimp:screen";
-
case GIMP_LAYER_MODE_OVERLAY_LEGACY:
- return "gimp:softlight-legacy";
- case GIMP_LAYER_MODE_OVERLAY:
- case GIMP_LAYER_MODE_OVERLAY_LINEAR:
- return "gimp:overlay";
+ return "gimp:softlight-legacy";
case GIMP_LAYER_MODE_DIFFERENCE_LEGACY:
return "gimp:difference-legacy";
- case GIMP_LAYER_MODE_DIFFERENCE:
- case GIMP_LAYER_MODE_DIFFERENCE_LINEAR:
- return "gimp:difference";
-
case GIMP_LAYER_MODE_ADDITION_LEGACY:
return "gimp:addition-legacy";
- case GIMP_LAYER_MODE_ADDITION:
- case GIMP_LAYER_MODE_ADDITION_LINEAR:
- return "gimp:addition";
-
case GIMP_LAYER_MODE_SUBTRACT_LEGACY:
return "gimp:subtract-legacy";
- case GIMP_LAYER_MODE_SUBTRACT:
- case GIMP_LAYER_MODE_SUBTRACT_LINEAR:
- return "gimp:subtract";
-
case GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY:
return "gimp:darken-only-legacy";
- case GIMP_LAYER_MODE_DARKEN_ONLY:
- case GIMP_LAYER_MODE_DARKEN_ONLY_LINEAR:
- return "gimp:darken-only";
-
case GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY:
return "gimp:lighten-only-legacy";
- case GIMP_LAYER_MODE_LIGHTEN_ONLY:
- case GIMP_LAYER_MODE_LIGHTEN_ONLY_LINEAR:
- return "gimp:lighten-only";
-
case GIMP_LAYER_MODE_HSV_HUE_LEGACY:
return "gimp:hsv-hue-legacy";
- case GIMP_LAYER_MODE_HSV_HUE:
- return "gimp:hsv-hue";
-
case GIMP_LAYER_MODE_HSV_SATURATION_LEGACY:
return "gimp:hsv-saturation-legacy";
- case GIMP_LAYER_MODE_HSV_SATURATION:
- return "gimp:hsv-saturation";
-
case GIMP_LAYER_MODE_HSV_COLOR_LEGACY:
return "gimp:hsv-color-legacy";
- case GIMP_LAYER_MODE_HSV_COLOR:
- return "gimp:hsv-color";
-
case GIMP_LAYER_MODE_HSV_VALUE_LEGACY:
return "gimp:hsv-value-legacy";
- case GIMP_LAYER_MODE_HSV_VALUE:
- return "gimp:hsv-value";
-
case GIMP_LAYER_MODE_DIVIDE_LEGACY:
return "gimp:divide-legacy";
- case GIMP_LAYER_MODE_DIVIDE:
- case GIMP_LAYER_MODE_DIVIDE_LINEAR:
- return "gimp:divide";
-
case GIMP_LAYER_MODE_DODGE_LEGACY:
return "gimp:dodge-legacy";
- case GIMP_LAYER_MODE_DODGE:
- case GIMP_LAYER_MODE_DODGE_LINEAR:
- return "gimp:dodge";
-
case GIMP_LAYER_MODE_BURN_LEGACY:
return "gimp:burn-legacy";
- case GIMP_LAYER_MODE_BURN:
- case GIMP_LAYER_MODE_BURN_LINEAR:
- return "gimp:burn";
-
case GIMP_LAYER_MODE_HARDLIGHT_LEGACY:
return "gimp:hardlight-legacy";
- case GIMP_LAYER_MODE_HARDLIGHT:
- case GIMP_LAYER_MODE_HARDLIGHT_LINEAR:
- return "gimp:hardlight";
-
case GIMP_LAYER_MODE_SOFTLIGHT_LEGACY:
return "gimp:softlight-legacy";
- case GIMP_LAYER_MODE_SOFTLIGHT:
- case GIMP_LAYER_MODE_SOFTLIGHT_LINEAR:
- return "gimp:softlight";
-
case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY:
return "gimp:grain-extract-legacy";
- case GIMP_LAYER_MODE_GRAIN_EXTRACT:
- case GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR:
- return "gimp:grain-extract";
-
case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY:
return "gimp:grain-merge-legacy";
- case GIMP_LAYER_MODE_GRAIN_MERGE:
- case GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR:
- return "gimp:grain-merge";
-
case GIMP_LAYER_MODE_COLOR_ERASE:
return "gimp:color-erase";
- case GIMP_LAYER_MODE_LCH_HUE:
- return "gimp:lch-hue";
-
- case GIMP_LAYER_MODE_LCH_CHROMA:
- return "gimp:lch-chroma";
-
- case GIMP_LAYER_MODE_LCH_COLOR:
- return "gimp:lch-color";
-
- case GIMP_LAYER_MODE_LCH_LIGHTNESS:
- return "gimp:lch-lightness";
-
case GIMP_LAYER_MODE_ERASE:
return "gimp:erase";
@@ -525,7 +472,8 @@ gimp_layer_mode_get_operation (GimpLayerMode mode)
case GIMP_LAYER_MODE_ANTI_ERASE:
return "gimp:anti-erase";
+ default:
+ return "gimp:layer-mode";
}
-
- return NULL;
+ return "gimp:layer-mode";
}
diff --git a/app/operations/gimp-operations.c b/app/operations/gimp-operations.c
index 4c39444..fc26091 100644
--- a/app/operations/gimp-operations.c
+++ b/app/operations/gimp-operations.c
@@ -84,36 +84,13 @@
#include "layer-modes-legacy/gimpoperationsoftlightlegacy.h"
#include "layer-modes-legacy/gimpoperationsubtractlegacy.h"
-#include "layer-modes/gimpoperationaddition.h"
#include "layer-modes/gimpoperationantierase.h"
#include "layer-modes/gimpoperationbehind.h"
-#include "layer-modes/gimpoperationburn.h"
+#include "layer-modes/gimpoperationerase.h"
#include "layer-modes/gimpoperationcolorerase.h"
-#include "layer-modes/gimpoperationdarkenonly.h"
-#include "layer-modes/gimpoperationdifference.h"
#include "layer-modes/gimpoperationdissolve.h"
-#include "layer-modes/gimpoperationdivide.h"
-#include "layer-modes/gimpoperationdodge.h"
-#include "layer-modes/gimpoperationerase.h"
-#include "layer-modes/gimpoperationgrainextract.h"
-#include "layer-modes/gimpoperationgrainmerge.h"
-#include "layer-modes/gimpoperationhardlight.h"
-#include "layer-modes/gimpoperationhsvcolor.h"
-#include "layer-modes/gimpoperationhsvhue.h"
-#include "layer-modes/gimpoperationhsvsaturation.h"
-#include "layer-modes/gimpoperationhsvvalue.h"
-#include "layer-modes/gimpoperationlchchroma.h"
-#include "layer-modes/gimpoperationlchcolor.h"
-#include "layer-modes/gimpoperationlchhue.h"
-#include "layer-modes/gimpoperationlchlightness.h"
-#include "layer-modes/gimpoperationlightenonly.h"
-#include "layer-modes/gimpoperationmultiply.h"
#include "layer-modes/gimpoperationnormal.h"
-#include "layer-modes/gimpoperationoverlay.h"
#include "layer-modes/gimpoperationreplace.h"
-#include "layer-modes/gimpoperationscreen.h"
-#include "layer-modes/gimpoperationsoftlight.h"
-#include "layer-modes/gimpoperationsubtract.h"
void
@@ -150,48 +127,25 @@ gimp_operations_init (void)
g_type_class_ref (GIMP_TYPE_OPERATION_NORMAL);
g_type_class_ref (GIMP_TYPE_OPERATION_DISSOLVE);
g_type_class_ref (GIMP_TYPE_OPERATION_BEHIND);
- g_type_class_ref (GIMP_TYPE_OPERATION_MULTIPLY);
g_type_class_ref (GIMP_TYPE_OPERATION_MULTIPLY_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_SCREEN);
g_type_class_ref (GIMP_TYPE_OPERATION_SCREEN_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_OVERLAY);
- g_type_class_ref (GIMP_TYPE_OPERATION_DIFFERENCE);
g_type_class_ref (GIMP_TYPE_OPERATION_DIFFERENCE_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_ADDITION);
g_type_class_ref (GIMP_TYPE_OPERATION_ADDITION_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_SUBTRACT);
g_type_class_ref (GIMP_TYPE_OPERATION_SUBTRACT_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_DARKEN_ONLY);
g_type_class_ref (GIMP_TYPE_OPERATION_DARKEN_ONLY_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_LIGHTEN_ONLY);
g_type_class_ref (GIMP_TYPE_OPERATION_LIGHTEN_ONLY_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_HSV_HUE);
- g_type_class_ref (GIMP_TYPE_OPERATION_HSV_SATURATION);
- g_type_class_ref (GIMP_TYPE_OPERATION_HSV_COLOR);
- g_type_class_ref (GIMP_TYPE_OPERATION_HSV_VALUE);
g_type_class_ref (GIMP_TYPE_OPERATION_HSV_HUE_LEGACY);
g_type_class_ref (GIMP_TYPE_OPERATION_HSV_SATURATION_LEGACY);
g_type_class_ref (GIMP_TYPE_OPERATION_HSV_COLOR_LEGACY);
g_type_class_ref (GIMP_TYPE_OPERATION_HSV_VALUE_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_DIVIDE);
g_type_class_ref (GIMP_TYPE_OPERATION_DIVIDE_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_DODGE);
g_type_class_ref (GIMP_TYPE_OPERATION_DODGE_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_BURN);
g_type_class_ref (GIMP_TYPE_OPERATION_BURN_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_HARDLIGHT);
g_type_class_ref (GIMP_TYPE_OPERATION_HARDLIGHT_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_SOFTLIGHT);
g_type_class_ref (GIMP_TYPE_OPERATION_SOFTLIGHT_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_GRAIN_EXTRACT);
g_type_class_ref (GIMP_TYPE_OPERATION_GRAIN_EXTRACT_LEGACY);
- g_type_class_ref (GIMP_TYPE_OPERATION_GRAIN_MERGE);
g_type_class_ref (GIMP_TYPE_OPERATION_GRAIN_MERGE_LEGACY);
g_type_class_ref (GIMP_TYPE_OPERATION_COLOR_ERASE);
- g_type_class_ref (GIMP_TYPE_OPERATION_LCH_HUE);
- g_type_class_ref (GIMP_TYPE_OPERATION_LCH_CHROMA);
- g_type_class_ref (GIMP_TYPE_OPERATION_LCH_COLOR);
- g_type_class_ref (GIMP_TYPE_OPERATION_LCH_LIGHTNESS);
g_type_class_ref (GIMP_TYPE_OPERATION_ERASE);
g_type_class_ref (GIMP_TYPE_OPERATION_REPLACE);
g_type_class_ref (GIMP_TYPE_OPERATION_ANTI_ERASE);
diff --git a/app/operations/layer-modes/Makefile.am b/app/operations/layer-modes/Makefile.am
index 5559930..cce4753 100644
--- a/app/operations/layer-modes/Makefile.am
+++ b/app/operations/layer-modes/Makefile.am
@@ -24,67 +24,20 @@ libapplayermodes_generic_a_sources = \
gimplayermodefunctions.h \
gimpblendcomposite.h \
\
- gimpoperationaddition.c \
- gimpoperationaddition.h \
gimpoperationantierase.c \
gimpoperationantierase.h \
gimpoperationbehind.c \
gimpoperationbehind.h \
- gimpoperationburn.c \
- gimpoperationburn.h \
gimpoperationcolorerase.c \
gimpoperationcolorerase.h \
- gimpoperationdarkenonly.c \
- gimpoperationdarkenonly.h \
- gimpoperationdifference.c \
- gimpoperationdifference.h \
gimpoperationdissolve.c \
gimpoperationdissolve.h \
- gimpoperationdivide.c \
- gimpoperationdivide.h \
- gimpoperationdodge.c \
- gimpoperationdodge.h \
gimpoperationerase.c \
gimpoperationerase.h \
- gimpoperationgrainextract.c \
- gimpoperationgrainextract.h \
- gimpoperationgrainmerge.c \
- gimpoperationgrainmerge.h \
- gimpoperationhardlight.c \
- gimpoperationhardlight.h \
- gimpoperationhsvcolor.c \
- gimpoperationhsvcolor.h \
- gimpoperationhsvhue.c \
- gimpoperationhsvhue.h \
- gimpoperationhsvsaturation.c \
- gimpoperationhsvsaturation.h \
- gimpoperationhsvvalue.c \
- gimpoperationhsvvalue.h \
- gimpoperationhsvvalue.h \
- gimpoperationlchchroma.c \
- gimpoperationlchchroma.h \
- gimpoperationlchcolor.c \
- gimpoperationlchcolor.h \
- gimpoperationlchhue.c \
- gimpoperationlchhue.h \
- gimpoperationlchlightness.c \
- gimpoperationlchlightness.h \
- gimpoperationlightenonly.c \
- gimpoperationlightenonly.h \
- gimpoperationmultiply.c \
- gimpoperationmultiply.h \
gimpoperationnormal.c \
gimpoperationnormal.h \
- gimpoperationoverlay.c \
- gimpoperationoverlay.h \
gimpoperationreplace.c \
- gimpoperationreplace.h \
- gimpoperationscreen.c \
- gimpoperationscreen.h \
- gimpoperationsoftlight.c \
- gimpoperationsoftlight.h \
- gimpoperationsubtract.c \
- gimpoperationsubtract.h
+ gimpoperationreplace.h
libapplayermodes_sse2_a_sources = \
gimpoperationnormal-sse2.c
diff --git a/app/operations/layer-modes/gimplayermodefunctions.c
b/app/operations/layer-modes/gimplayermodefunctions.c
index 3bc190e..2b3ac63 100644
--- a/app/operations/layer-modes/gimplayermodefunctions.c
+++ b/app/operations/layer-modes/gimplayermodefunctions.c
@@ -45,42 +45,19 @@
#include "operations/layer-modes-legacy/gimpoperationsoftlightlegacy.h"
#include "operations/layer-modes-legacy/gimpoperationsubtractlegacy.h"
-#include "gimpoperationaddition.h"
#include "gimpoperationantierase.h"
#include "gimpoperationbehind.h"
-#include "gimpoperationburn.h"
#include "gimpoperationcolorerase.h"
-#include "gimpoperationdarkenonly.h"
-#include "gimpoperationdifference.h"
#include "gimpoperationdissolve.h"
-#include "gimpoperationdivide.h"
-#include "gimpoperationdodge.h"
#include "gimpoperationerase.h"
-#include "gimpoperationgrainextract.h"
-#include "gimpoperationgrainmerge.h"
-#include "gimpoperationhardlight.h"
-#include "gimpoperationhsvcolor.h"
-#include "gimpoperationhsvhue.h"
-#include "gimpoperationhsvsaturation.h"
-#include "gimpoperationhsvvalue.h"
-#include "gimpoperationlchchroma.h"
-#include "gimpoperationlchcolor.h"
-#include "gimpoperationlchhue.h"
-#include "gimpoperationlchlightness.h"
-#include "gimpoperationlightenonly.h"
-#include "gimpoperationmultiply.h"
#include "gimpoperationnormal.h"
-#include "gimpoperationoverlay.h"
#include "gimpoperationreplace.h"
-#include "gimpoperationscreen.h"
-#include "gimpoperationsoftlight.h"
-#include "gimpoperationsubtract.h"
GimpLayerModeFunc
gimp_get_layer_mode_function (GimpLayerMode paint_mode)
{
- GimpLayerModeFunc func;
+ GimpLayerModeFunc func = gimp_operation_layer_mode_process_pixels;
switch (paint_mode)
{
@@ -102,19 +79,10 @@ gimp_get_layer_mode_function (GimpLayerMode paint_mode)
func = gimp_operation_multiply_legacy_process;
break;
- case GIMP_LAYER_MODE_MULTIPLY:
- case GIMP_LAYER_MODE_MULTIPLY_LINEAR:
- func = gimp_operation_multiply_process;
- break;
-
case GIMP_LAYER_MODE_SCREEN_LEGACY:
func = gimp_operation_screen_legacy_process;
break;
- case GIMP_LAYER_MODE_SCREEN:
- func = gimp_operation_screen_process;
- break;
-
case GIMP_LAYER_MODE_OVERLAY_LEGACY:
func = gimp_operation_softlight_legacy_process;
break;
@@ -123,75 +91,34 @@ gimp_get_layer_mode_function (GimpLayerMode paint_mode)
func = gimp_operation_difference_legacy_process;
break;
- case GIMP_LAYER_MODE_DIFFERENCE:
- case GIMP_LAYER_MODE_DIFFERENCE_LINEAR:
- func = gimp_operation_difference_process;
- break;
-
case GIMP_LAYER_MODE_ADDITION_LEGACY:
func = gimp_operation_addition_legacy_process;
break;
- case GIMP_LAYER_MODE_ADDITION:
- case GIMP_LAYER_MODE_ADDITION_LINEAR:
- func = gimp_operation_addition_process;
- break;
-
case GIMP_LAYER_MODE_SUBTRACT_LEGACY:
func = gimp_operation_subtract_legacy_process;
break;
- case GIMP_LAYER_MODE_SUBTRACT:
- case GIMP_LAYER_MODE_SUBTRACT_LINEAR:
- func = gimp_operation_subtract_process;
- break;
-
case GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY:
func = gimp_operation_darken_only_legacy_process;
break;
- case GIMP_LAYER_MODE_DARKEN_ONLY:
- case GIMP_LAYER_MODE_DARKEN_ONLY_LINEAR:
- func = gimp_operation_darken_only_process;
- break;
-
case GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY:
func = gimp_operation_lighten_only_legacy_process;
break;
- case GIMP_LAYER_MODE_LIGHTEN_ONLY:
- case GIMP_LAYER_MODE_LIGHTEN_ONLY_LINEAR:
- func = gimp_operation_lighten_only_process;
- break;
-
- case GIMP_LAYER_MODE_HSV_HUE:
- func = gimp_operation_hsv_hue_process;
- break;
-
case GIMP_LAYER_MODE_HSV_HUE_LEGACY:
func = gimp_operation_hsv_hue_legacy_process;
break;
- case GIMP_LAYER_MODE_HSV_SATURATION:
- func = gimp_operation_hsv_saturation_process;
- break;
-
case GIMP_LAYER_MODE_HSV_SATURATION_LEGACY:
func = gimp_operation_hsv_saturation_legacy_process;
break;
- case GIMP_LAYER_MODE_HSV_COLOR:
- func = gimp_operation_hsv_color_process;
- break;
-
case GIMP_LAYER_MODE_HSV_COLOR_LEGACY:
func = gimp_operation_hsv_color_legacy_process;
break;
- case GIMP_LAYER_MODE_HSV_VALUE:
- func = gimp_operation_hsv_value_process;
- break;
-
case GIMP_LAYER_MODE_HSV_VALUE_LEGACY:
func = gimp_operation_hsv_value_legacy_process;
break;
@@ -200,87 +127,34 @@ gimp_get_layer_mode_function (GimpLayerMode paint_mode)
func = gimp_operation_divide_legacy_process;
break;
- case GIMP_LAYER_MODE_DIVIDE:
- case GIMP_LAYER_MODE_DIVIDE_LINEAR:
- func = gimp_operation_divide_process;
- break;
-
case GIMP_LAYER_MODE_DODGE_LEGACY:
func = gimp_operation_dodge_legacy_process;
break;
- case GIMP_LAYER_MODE_DODGE:
- case GIMP_LAYER_MODE_DODGE_LINEAR:
- func = gimp_operation_dodge_process;
- break;
-
case GIMP_LAYER_MODE_BURN_LEGACY:
func = gimp_operation_burn_legacy_process;
break;
- case GIMP_LAYER_MODE_BURN:
- case GIMP_LAYER_MODE_BURN_LINEAR:
- func = gimp_operation_burn_process;
- break;
-
case GIMP_LAYER_MODE_HARDLIGHT_LEGACY:
func = gimp_operation_hardlight_legacy_process;
break;
- case GIMP_LAYER_MODE_HARDLIGHT:
- func = gimp_operation_hardlight_process;
- break;
-
case GIMP_LAYER_MODE_SOFTLIGHT_LEGACY:
func = gimp_operation_softlight_legacy_process;
break;
- case GIMP_LAYER_MODE_SOFTLIGHT:
- func = gimp_operation_softlight_process;
- break;
-
case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY:
func = gimp_operation_grain_extract_legacy_process;
break;
- case GIMP_LAYER_MODE_GRAIN_EXTRACT:
- case GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR:
- func = gimp_operation_grain_extract_process;
- break;
-
case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY:
func = gimp_operation_grain_merge_legacy_process;
break;
- case GIMP_LAYER_MODE_GRAIN_MERGE:
- case GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR:
- func = gimp_operation_grain_merge_process;
- break;
-
case GIMP_LAYER_MODE_COLOR_ERASE:
func = gimp_operation_color_erase_process;
break;
- case GIMP_LAYER_MODE_OVERLAY:
- func = gimp_operation_overlay_process;
- break;
-
- case GIMP_LAYER_MODE_LCH_HUE:
- func = gimp_operation_lch_hue_process;
- break;
-
- case GIMP_LAYER_MODE_LCH_CHROMA:
- func = gimp_operation_lch_chroma_process;
- break;
-
- case GIMP_LAYER_MODE_LCH_COLOR:
- func = gimp_operation_lch_color_process;
- break;
-
- case GIMP_LAYER_MODE_LCH_LIGHTNESS:
- func = gimp_operation_lch_lightness_process;
- break;
-
case GIMP_LAYER_MODE_ERASE:
func = gimp_operation_erase_process;
break;
@@ -294,9 +168,6 @@ gimp_get_layer_mode_function (GimpLayerMode paint_mode)
break;
default:
- g_warning ("No direct function for layer mode (%d), using gimp:normal",
- paint_mode);
- func = gimp_operation_normal_process;
break;
}
diff --git a/app/operations/layer-modes/gimpoperationlayermode.c
b/app/operations/layer-modes/gimpoperationlayermode.c
index e339d11..8b44c67 100644
--- a/app/operations/layer-modes/gimpoperationlayermode.c
+++ b/app/operations/layer-modes/gimpoperationlayermode.c
@@ -60,7 +60,6 @@ static gboolean gimp_operation_layer_mode_process (GeglOperation *op
const GeglRectangle *result,
gint level);
-
G_DEFINE_TYPE (GimpOperationLayerMode, gimp_operation_layer_mode,
GEGL_TYPE_OPERATION_POINT_COMPOSER3)
@@ -78,14 +77,23 @@ const Babl *_gimp_fish_laba_to_perceptual = NULL;
static void
gimp_operation_layer_mode_class_init (GimpOperationLayerModeClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (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);
+
+ 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;
- operation_class->prepare = gimp_operation_layer_mode_prepare;
- operation_class->process = gimp_operation_layer_mode_process;
+ operation_class->prepare = gimp_operation_layer_mode_prepare;
+ operation_class->process = gimp_operation_layer_mode_process;
+ point_composer3_class->process = gimp_operation_layer_mode_process_pixels;
g_object_class_install_property (object_class, PROP_LAYER_MODE,
g_param_spec_enum ("layer-mode",
@@ -276,3 +284,1333 @@ gimp_operation_layer_mode_process (GeglOperation *operation,
output_prop, result,
level);
}
+
+
+static inline GimpBlendFunc gimp_layer_mode_get_blend_fun (GimpLayerMode mode);
+
+static inline void gimp_composite_blend (gpointer op,
+ 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 = (GimpOperationLayerMode*)(operation);
+ gimp_composite_blend (operation, in, layer, mask, out, samples,
+ gimp_layer_mode_get_blend_fun (layer_mode->layer_mode));
+ return TRUE;
+}
+
+
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpmath/gimpmath.h"
+
+
+extern const Babl *_gimp_fish_rgba_to_perceptual;
+extern const Babl *_gimp_fish_perceptual_to_rgba;
+extern const Babl *_gimp_fish_perceptual_to_laba;
+extern const Babl *_gimp_fish_rgba_to_laba;
+extern const Babl *_gimp_fish_laba_to_rgba;
+extern const Babl *_gimp_fish_laba_to_perceptual;
+
+
+static inline void
+compfun_src_atop (gfloat *in,
+ gfloat *layer,
+ 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
+ {
+ gint b;
+
+ for (b = RED; b < ALPHA; b++)
+ out[b] = layer[b] * layer_alpha + in[b] * (1.0f - layer_alpha);
+ }
+
+ out[ALPHA] = in[ALPHA];
+
+ in += 4;
+ out += 4;
+ layer += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+static inline void
+compfun_src_over (gfloat *in,
+ gfloat *layer,
+ gfloat *comp,
+ gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat new_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
+ {
+ 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
+compfun_dst_atop (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
+ {
+ 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
+compfun_src_in (gfloat *in,
+ gfloat *layer,
+ gfloat *mask,
+ gfloat opacity,
+ gfloat *out,
+ gint samples)
+{
+ while (samples--)
+ {
+ gfloat new_alpha = in[ALPHA] * layer[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] = layer[RED];
+ out[GREEN] = layer[GREEN];
+ out[BLUE] = layer[BLUE];
+ }
+
+ out[ALPHA] = new_alpha;
+
+ in += 4;
+ out += 4;
+ layer += 4;
+
+ if (mask)
+ mask++;
+ }
+}
+
+static inline void
+gimp_composite_blend (gpointer op,
+ gfloat *in,
+ gfloat *layer,
+ gfloat *mask,
+ gfloat *out,
+ glong samples,
+ GimpBlendFunc blend_func)
+{
+ GimpOperationLayerMode *layer_mode = op;
+ 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 = in;
+ gfloat *blend_layer = layer;
+ gfloat *blend_out = out;
+
+ gfloat *composite_in = NULL;
+ gfloat *composite_layer = NULL;
+
+ gboolean composite_needs_in_color =
+ composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
+ composite_mode == GIMP_LAYER_COMPOSITE_SRC_ATOP;
+ gboolean composite_needs_layer_color =
+ composite_mode == GIMP_LAYER_COMPOSITE_SRC_OVER ||
+ composite_mode == GIMP_LAYER_COMPOSITE_DST_ATOP;
+
+ const Babl *fish_to_blend = NULL;
+ const Babl *fish_to_composite = NULL;
+ const Babl *fish_from_composite = NULL;
+
+ switch (blend_space)
+ {
+ default:
+ case GIMP_LAYER_COLOR_SPACE_RGB_LINEAR:
+ fish_to_blend = NULL;
+ switch (composite_space)
+ {
+ case GIMP_LAYER_COLOR_SPACE_LAB:
+ fish_to_composite = _gimp_fish_rgba_to_laba;
+ fish_from_composite = _gimp_fish_laba_to_rgba;
+ break;
+ default:
+ case GIMP_LAYER_COLOR_SPACE_RGB_LINEAR:
+ fish_to_composite = NULL;
+ fish_from_composite = NULL;
+ break;
+ case GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL:
+ fish_to_composite = _gimp_fish_rgba_to_perceptual;
+ fish_from_composite = _gimp_fish_perceptual_to_rgba;
+ break;
+ }
+ break;
+
+ case GIMP_LAYER_COLOR_SPACE_LAB:
+ fish_to_blend = _gimp_fish_rgba_to_laba;
+ switch (composite_space)
+ {
+ case GIMP_LAYER_COLOR_SPACE_LAB:
+ default:
+ fish_to_composite = NULL;
+ fish_from_composite = _gimp_fish_laba_to_rgba;
+ break;
+ case GIMP_LAYER_COLOR_SPACE_RGB_LINEAR:
+ fish_to_composite = _gimp_fish_laba_to_rgba;
+ fish_from_composite = NULL;
+ break;
+ case GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL:
+ fish_to_composite = _gimp_fish_laba_to_perceptual;
+ fish_from_composite = _gimp_fish_perceptual_to_rgba;
+ break;
+ }
+ break;
+
+ case GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL:
+ fish_to_blend = _gimp_fish_rgba_to_perceptual;
+ switch (composite_space)
+ {
+ case GIMP_LAYER_COLOR_SPACE_LAB:
+ default:
+ fish_to_composite = _gimp_fish_perceptual_to_laba;
+ fish_from_composite = NULL;
+ break;
+ case GIMP_LAYER_COLOR_SPACE_RGB_LINEAR:
+ fish_to_composite = _gimp_fish_perceptual_to_rgba;
+ fish_from_composite = NULL;
+ break;
+ case GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL:
+ fish_to_composite = NULL;
+ fish_from_composite = _gimp_fish_perceptual_to_rgba;
+ break;
+ }
+ break;
+ }
+
+ if (in == out) /* in-place detected, avoid clobbering since we need to
+ read it for the compositing stage */
+ blend_out = g_alloca (sizeof (gfloat) * 4 * samples);
+
+ if (fish_to_blend)
+ {
+ if (in != out || (composite_needs_in_color &&
+ composite_space == GIMP_LAYER_COLOR_SPACE_RGB_LINEAR))
+ {
+ /* don't convert input in-place if we're not doing in-place output,
+ * or if we're going to need the original input for compositing.
+ */
+ blend_in = g_alloca (sizeof (gfloat) * 4 * samples);
+ }
+ blend_layer = g_alloca (sizeof (gfloat) * 4 * samples);
+
+ babl_process (fish_to_blend, in, blend_in, samples);
+ babl_process (fish_to_blend, layer, blend_layer, samples);
+ }
+
+ blend_func (blend_in, blend_layer, blend_out, samples);
+
+ composite_in = blend_in;
+ composite_layer = blend_layer;
+
+ if (fish_to_composite)
+ {
+ if (composite_space == GIMP_LAYER_COLOR_SPACE_RGB_LINEAR)
+ {
+ composite_in = in;
+ composite_layer = layer;
+ }
+ else
+ {
+ if (composite_needs_in_color)
+ {
+ if (composite_in == in && in != out)
+ composite_in = g_alloca (sizeof (gfloat) * 4 * samples);
+
+ babl_process (fish_to_composite,
+ blend_in, composite_in, samples);
+ }
+
+ if (composite_needs_layer_color)
+ {
+ if (composite_layer == layer)
+ composite_layer = g_alloca (sizeof (gfloat) * 4 * samples);
+
+ babl_process (fish_to_composite,
+ blend_layer, composite_layer, samples);
+ }
+ }
+
+ babl_process (fish_to_composite, blend_out, blend_out, samples);
+ }
+
+ switch (composite_mode)
+ {
+ case GIMP_LAYER_COMPOSITE_SRC_ATOP:
+ default:
+ compfun_src_atop (composite_in, blend_out, mask, opacity, out, samples);
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_OVER:
+ compfun_src_over (composite_in, composite_layer, blend_out, mask, opacity, out, samples);
+ break;
+
+ case GIMP_LAYER_COMPOSITE_DST_ATOP:
+ compfun_dst_atop (composite_in, composite_layer, blend_out, mask, opacity, out, samples);
+ break;
+
+ case GIMP_LAYER_COMPOSITE_SRC_IN:
+ compfun_src_in (composite_in, blend_out, mask, opacity, out, samples);
+ break;
+ }
+
+ if (fish_from_composite)
+ {
+ babl_process (fish_from_composite, out, out, samples);
+ }
+}
+
+static inline void
+blendfun_screen (const float *dest,
+ const float *src,
+ float *out,
+ int samples)
+{
+ while (samples--)
+ {
+ if (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 (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 (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 (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 (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 (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 (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 (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_lighten_only (const float *dest,
+ const float *src,
+ float *out,
+ int samples)
+{
+ while (samples--)
+ {
+ if (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 (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 (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 (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 (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 (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 (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 (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 (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_hsv_color (const float *dest,
+ const float *src,
+ float *out,
+ int samples)
+{
+ while (samples--)
+ {
+ if (src[ALPHA] != 0.0f)
+ {
+ GimpRGB dest_rgb = { dest[0], dest[1], dest[2] };
+ GimpRGB src_rgb = { src[0], src[1], src[2] };
+ GimpHSL src_hsl, dest_hsl;
+
+ gimp_rgb_to_hsl (&dest_rgb, &dest_hsl);
+ gimp_rgb_to_hsl (&src_rgb, &src_hsl);
+
+ dest_hsl.h = src_hsl.h;
+ dest_hsl.s = src_hsl.s;
+
+ gimp_hsl_to_rgb (&dest_hsl, &dest_rgb);
+
+ out[RED] = dest_rgb.r;
+ out[GREEN] = dest_rgb.g;
+ out[BLUE] = dest_rgb.b;
+ }
+
+ 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 (src[ALPHA] != 0.0f)
+ {
+ GimpRGB dest_rgb = { dest[0], dest[1], dest[2] };
+ GimpRGB src_rgb = { src[0], src[1], src[2] };
+ GimpHSV src_hsv, dest_hsv;
+
+ gimp_rgb_to_hsv (&dest_rgb, &dest_hsv);
+ gimp_rgb_to_hsv (&src_rgb, &src_hsv);
+
+ dest_hsv.h = src_hsv.h;
+ gimp_hsv_to_rgb (&dest_hsv, &dest_rgb);
+
+ out[RED] = dest_rgb.r;
+ out[GREEN] = dest_rgb.g;
+ out[BLUE] = dest_rgb.b;
+ }
+
+ 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 (src[ALPHA] != 0.0f)
+ {
+ GimpRGB dest_rgb = { dest[0], dest[1], dest[2] };
+ GimpRGB src_rgb = { src[0], src[1], src[2] };
+ GimpHSV src_hsv, dest_hsv;
+
+ gimp_rgb_to_hsv (&dest_rgb, &dest_hsv);
+ gimp_rgb_to_hsv (&src_rgb, &src_hsv);
+
+ dest_hsv.s = src_hsv.s;
+ gimp_hsv_to_rgb (&dest_hsv, &dest_rgb);
+
+ out[RED] = dest_rgb.r;
+ out[GREEN] = dest_rgb.g;
+ out[BLUE] = dest_rgb.b;
+ }
+
+ 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 (src[ALPHA] != 0.0f)
+ {
+ GimpRGB dest_rgb = { dest[0], dest[1], dest[2] };
+ GimpRGB src_rgb = { src[0], src[1], src[2] };
+ GimpHSV src_hsv, dest_hsv;
+
+ gimp_rgb_to_hsv (&dest_rgb, &dest_hsv);
+ gimp_rgb_to_hsv (&src_rgb, &src_hsv);
+
+ dest_hsv.v = src_hsv.v;
+ gimp_hsv_to_rgb (&dest_hsv, &dest_rgb);
+
+ out[RED] = dest_rgb.r;
+ out[GREEN] = dest_rgb.g;
+ out[BLUE] = dest_rgb.b;
+ }
+
+ 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 (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;
+ }
+ }
+
+ 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 (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 (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 (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;
+ }
+}
+
+
+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.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html */
+static inline void
+blendfun_vivid_light (const float *dest,
+ const float *src,
+ float *out,
+ int samples)
+{
+ while (samples--)
+ {
+ if (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] / (1.0f - 2.0f * (src[c] - 0.5));
+ }
+ 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 (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] - 0.5);
+ }
+ else
+ {
+ comp = dest[c] + 2.0 * src[c] - 1.0;
+ }
+ 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 (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_exclusion (const float *dest,
+ const float *src,
+ float *out,
+ int samples)
+{
+ while (samples--)
+ {
+ if (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);
+ }
+ }
+ out[ALPHA] = src[ALPHA];
+
+ out += 4;
+ src += 4;
+ dest += 4;
+ }
+}
+
+static inline void dummy_fun(void)
+{
+}
+
+static inline GimpBlendFunc gimp_layer_mode_get_blend_fun (GimpLayerMode mode)
+{
+ switch (mode)
+ {
+ case GIMP_LAYER_MODE_SCREEN_LINEAR:
+ case GIMP_LAYER_MODE_SCREEN: return blendfun_screen;
+ case GIMP_LAYER_MODE_ADDITION_LINEAR:
+ case GIMP_LAYER_MODE_ADDITION: return blendfun_addition;
+ case GIMP_LAYER_MODE_SUBTRACT_LINEAR:
+ case GIMP_LAYER_MODE_SUBTRACT: return blendfun_subtract;
+ case GIMP_LAYER_MODE_MULTIPLY_LINEAR:
+ case GIMP_LAYER_MODE_MULTIPLY: return blendfun_multiply;
+ case GIMP_LAYER_MODE_NORMAL: return blendfun_normal;
+ case GIMP_LAYER_MODE_BURN_LINEAR:
+ case GIMP_LAYER_MODE_BURN: return blendfun_burn;
+ case GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR:
+ case GIMP_LAYER_MODE_GRAIN_MERGE: return blendfun_grain_merge;
+ case GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR:
+ case GIMP_LAYER_MODE_GRAIN_EXTRACT: return blendfun_grain_merge;
+ case GIMP_LAYER_MODE_DODGE_LINEAR:
+ case GIMP_LAYER_MODE_DODGE: return blendfun_dodge;
+ case GIMP_LAYER_MODE_OVERLAY_LINEAR:
+ case GIMP_LAYER_MODE_OVERLAY: return blendfun_overlay;
+ case GIMP_LAYER_MODE_HSV_COLOR: return blendfun_hsv_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_HARDLIGHT_LINEAR:
+ case GIMP_LAYER_MODE_HARDLIGHT: return blendfun_hardlight;
+ case GIMP_LAYER_MODE_SOFTLIGHT_LINEAR:
+ case GIMP_LAYER_MODE_SOFTLIGHT: return blendfun_softlight;
+ case GIMP_LAYER_MODE_DIVIDE:
+ case GIMP_LAYER_MODE_DIVIDE_LINEAR: return blendfun_divide;
+ case GIMP_LAYER_MODE_DIFFERENCE_LINEAR:
+ 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_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_EXCLUSION: return blendfun_exclusion;
+ case GIMP_LAYER_MODE_LINEAR_BURN: return blendfun_linear_burn;
+ default:
+ return (void*)dummy_fun;
+ }
+}
diff --git a/app/operations/layer-modes/gimpoperationlayermode.h
b/app/operations/layer-modes/gimpoperationlayermode.h
index c95790b..545203f 100644
--- a/app/operations/layer-modes/gimpoperationlayermode.h
+++ b/app/operations/layer-modes/gimpoperationlayermode.h
@@ -56,5 +56,14 @@ struct _GimpOperationLayerMode
GType gimp_operation_layer_mode_get_type (void) G_GNUC_CONST;
+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/widgets/gimpwidgets-constructors.c b/app/widgets/gimpwidgets-constructors.c
index 4c8a875..80e4fa3 100644
--- a/app/widgets/gimpwidgets-constructors.c
+++ b/app/widgets/gimpwidgets-constructors.c
@@ -123,15 +123,20 @@ gimp_paint_mode_menu_new (gboolean with_behind_mode,
GIMP_LAYER_MODE_MULTIPLY_LEGACY,
GIMP_LAYER_MODE_BURN,
GIMP_LAYER_MODE_BURN_LEGACY,
+ GIMP_LAYER_MODE_LINEAR_BURN,
GIMP_LAYER_MODE_OVERLAY,
GIMP_LAYER_MODE_SOFTLIGHT,
GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
GIMP_LAYER_MODE_HARDLIGHT,
GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
+ GIMP_LAYER_MODE_VIVID_LIGHT,
+ GIMP_LAYER_MODE_PIN_LIGHT,
+ GIMP_LAYER_MODE_LINEAR_LIGHT,
GIMP_LAYER_MODE_DIFFERENCE,
GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
GIMP_LAYER_MODE_SUBTRACT,
GIMP_LAYER_MODE_SUBTRACT_LEGACY,
+ GIMP_LAYER_MODE_EXCLUSION,
GIMP_LAYER_MODE_GRAIN_EXTRACT,
GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
GIMP_LAYER_MODE_GRAIN_MERGE,
@@ -158,10 +163,10 @@ gimp_paint_mode_menu_new (gboolean with_behind_mode,
GIMP_LAYER_MODE_ADDITION_LEGACY, -1);
gimp_int_store_insert_separator_after (GIMP_INT_STORE (store),
- GIMP_LAYER_MODE_BURN_LEGACY, -1);
+ GIMP_LAYER_MODE_LINEAR_BURN, -1);
gimp_int_store_insert_separator_after (GIMP_INT_STORE (store),
- GIMP_LAYER_MODE_HARDLIGHT_LEGACY, -1);
+ GIMP_LAYER_MODE_LINEAR_LIGHT, -1);
gimp_int_store_insert_separator_after (GIMP_INT_STORE (store),
GIMP_LAYER_MODE_DIVIDE_LEGACY, -1);
diff --git a/libgimp/gimpenums.h b/libgimp/gimpenums.h
index 47fad3a..d322eb5 100644
--- a/libgimp/gimpenums.h
+++ b/libgimp/gimpenums.h
@@ -131,7 +131,17 @@ typedef enum
GIMP_LAYER_MODE_GRAIN_EXTRACT,
GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR,
GIMP_LAYER_MODE_GRAIN_MERGE,
- GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR
+ GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR,
+ GIMP_LAYER_MODE_VIVID_LIGHT,
+ GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR,
+ GIMP_LAYER_MODE_PIN_LIGHT,
+ GIMP_LAYER_MODE_PIN_LIGHT_LINEAR,
+ GIMP_LAYER_MODE_LINEAR_LIGHT,
+ GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR,
+ GIMP_LAYER_MODE_EXCLUSION,
+ GIMP_LAYER_MODE_EXCLUSION_LINEAR,
+ GIMP_LAYER_MODE_LINEAR_BURN,
+ GIMP_LAYER_MODE_LINEAR_BURN_LINEAR
} GimpLayerMode;
diff --git a/tools/pdbgen/enums.pl b/tools/pdbgen/enums.pl
index 5e3da4d..e7dd350 100644
--- a/tools/pdbgen/enums.pl
+++ b/tools/pdbgen/enums.pl
@@ -752,7 +752,17 @@ package Gimp::CodeGen::enums;
GIMP_LAYER_MODE_GRAIN_EXTRACT
GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR
GIMP_LAYER_MODE_GRAIN_MERGE
- GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR) ],
+ GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR
+ GIMP_LAYER_MODE_VIVID_LIGHT
+ GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR
+ GIMP_LAYER_MODE_PIN_LIGHT
+ GIMP_LAYER_MODE_PIN_LIGHT_LINEAR
+ GIMP_LAYER_MODE_LINEAR_LIGHT
+ GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR
+ GIMP_LAYER_MODE_EXCLUSION
+ GIMP_LAYER_MODE_EXCLUSION_LINEAR
+ GIMP_LAYER_MODE_LINEAR_BURN
+ GIMP_LAYER_MODE_LINEAR_BURN_LINEAR) ],
mapping => { GIMP_LAYER_MODE_NORMAL_NON_LINEAR => '0',
GIMP_LAYER_MODE_DISSOLVE => '1',
GIMP_LAYER_MODE_BEHIND => '2',
@@ -815,7 +825,17 @@ package Gimp::CodeGen::enums;
GIMP_LAYER_MODE_GRAIN_EXTRACT => '59',
GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR => '60',
GIMP_LAYER_MODE_GRAIN_MERGE => '61',
- GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR => '62' }
+ GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR => '62',
+ GIMP_LAYER_MODE_VIVID_LIGHT => '63',
+ GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR => '64',
+ GIMP_LAYER_MODE_PIN_LIGHT => '65',
+ GIMP_LAYER_MODE_PIN_LIGHT_LINEAR => '66',
+ GIMP_LAYER_MODE_LINEAR_LIGHT => '67',
+ GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR => '68',
+ GIMP_LAYER_MODE_EXCLUSION => '69',
+ GIMP_LAYER_MODE_EXCLUSION_LINEAR => '70',
+ GIMP_LAYER_MODE_LINEAR_BURN => '71',
+ GIMP_LAYER_MODE_LINEAR_BURN_LINEAR => '72' }
},
GimpBrushApplicationMode =>
{ contig => 1,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]