From c6c0899655740869ef401599e16d9c8e16853f80 Mon Sep 17 00:00:00 2001 From: Ell Date: Fri, 10 Mar 2017 16:33:14 -0500 Subject: [PATCH] app: add mono-mix layer mode Calculates the dot product of the two input colors, and uses that as the value for all the output color's components. Basically, a per-pixel mono mixer. Useful for custom desaturation, component extraction, and crazier stuff (bump mapping!) --- app/core/gimpimage.c | 1 + app/operations/layer-modes/gimp-layer-modes.c | 18 ++++++++++- .../layer-modes/gimpoperationlayermode.c | 30 +++++++++++++++++++ app/operations/operations-enums.c | 2 ++ app/operations/operations-enums.h | 1 + libgimp/gimpenums.h | 3 +- tools/pdbgen/enums.pl | 6 ++-- 7 files changed, 57 insertions(+), 4 deletions(-) diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index f936b8db03..cd2e487687 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -2464,6 +2464,7 @@ gimp_image_get_xcf_version (GimpImage *image, case GIMP_LAYER_MODE_LUMINANCE: case GIMP_LAYER_MODE_COLOR_ERASE: case GIMP_LAYER_MODE_ERASE: + case GIMP_LAYER_MODE_MONO_MIX: version = MAX (10, version); break; diff --git a/app/operations/layer-modes/gimp-layer-modes.c b/app/operations/layer-modes/gimp-layer-modes.c index fd37a7baf5..1a61e500b5 100644 --- a/app/operations/layer-modes/gimp-layer-modes.c +++ b/app/operations/layer-modes/gimp-layer-modes.c @@ -825,6 +825,17 @@ static const GimpLayerModeInfo layer_mode_infos[] = .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR }, + { GIMP_LAYER_MODE_MONO_MIX, + + .op_name = "gimp:layer-mode", + .function = gimp_operation_layer_mode_process_pixels, + .context = GIMP_LAYER_MODE_CONTEXT_ALL, + .paint_composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER, + .composite_mode = GIMP_LAYER_COMPOSITE_SRC_ATOP, + .composite_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR, + .blend_space = GIMP_LAYER_COLOR_SPACE_RGB_LINEAR + }, + { GIMP_LAYER_MODE_REPLACE, .op_name = "gimp:replace", @@ -909,7 +920,8 @@ static const GimpLayerMode layer_mode_group_default[] = GIMP_LAYER_MODE_SEPARATOR, GIMP_LAYER_MODE_EXCLUSION, - GIMP_LAYER_MODE_LINEAR_BURN + GIMP_LAYER_MODE_LINEAR_BURN, + GIMP_LAYER_MODE_MONO_MIX }; static const GimpLayerMode layer_mode_group_legacy[] = @@ -1088,6 +1100,10 @@ static const GimpLayerMode layer_mode_groups[][2] = [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1 }, + { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_MONO_MIX, + [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1 + }, + { [GIMP_LAYER_MODE_GROUP_DEFAULT] = GIMP_LAYER_MODE_REPLACE, [GIMP_LAYER_MODE_GROUP_LEGACY ] = -1 }, diff --git a/app/operations/layer-modes/gimpoperationlayermode.c b/app/operations/layer-modes/gimpoperationlayermode.c index ee2bf8a699..dd3b863887 100644 --- a/app/operations/layer-modes/gimpoperationlayermode.c +++ b/app/operations/layer-modes/gimpoperationlayermode.c @@ -2240,6 +2240,35 @@ blendfun_color_erase (const float *dest, } } +static inline void +blendfun_mono_mix (const float *dest, + const float *src, + float *out, + int samples) +{ + while (samples--) + { + if (dest[ALPHA] != 0.0f && src[ALPHA] != 0.0f) + { + gfloat value = 0.0f; + gint c; + + for (c = 0; c < 3; c++) + { + value += dest[c] * src[c]; + } + + out[RED] = out[GREEN] = out[BLUE] = value; + } + + out[ALPHA] = src[ALPHA]; + + out += 4; + src += 4; + dest += 4; + } +} + static inline void blendfun_dummy (const float *dest, const float *src, @@ -2289,6 +2318,7 @@ gimp_layer_mode_get_blend_fun (GimpLayerMode mode) 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_MONO_MIX: return blendfun_mono_mix; case GIMP_LAYER_MODE_DISSOLVE: case GIMP_LAYER_MODE_BEHIND_LEGACY: diff --git a/app/operations/operations-enums.c b/app/operations/operations-enums.c index 5dfec3a8d8..75fb2b25d6 100644 --- a/app/operations/operations-enums.c +++ b/app/operations/operations-enums.c @@ -140,6 +140,7 @@ gimp_layer_mode_get_type (void) { GIMP_LAYER_MODE_LUMINANCE, "GIMP_LAYER_MODE_LUMINANCE", "luminance" }, { GIMP_LAYER_MODE_COLOR_ERASE, "GIMP_LAYER_MODE_COLOR_ERASE", "color-erase" }, { GIMP_LAYER_MODE_ERASE, "GIMP_LAYER_MODE_ERASE", "erase" }, + { GIMP_LAYER_MODE_MONO_MIX, "GIMP_LAYER_MODE_MONO_MIX", "mono-mix" }, { GIMP_LAYER_MODE_REPLACE, "GIMP_LAYER_MODE_REPLACE", "replace" }, { GIMP_LAYER_MODE_ANTI_ERASE, "GIMP_LAYER_MODE_ANTI_ERASE", "anti-erase" }, { 0, NULL, NULL } @@ -206,6 +207,7 @@ gimp_layer_mode_get_type (void) { GIMP_LAYER_MODE_LUMINANCE, NC_("layer-mode", "Luminance"), NULL }, { GIMP_LAYER_MODE_COLOR_ERASE, NC_("layer-mode", "Color erase"), NULL }, { GIMP_LAYER_MODE_ERASE, NC_("layer-mode", "Erase"), NULL }, + { GIMP_LAYER_MODE_MONO_MIX, NC_("layer-mode", "Mono mix"), NULL }, { GIMP_LAYER_MODE_REPLACE, NC_("layer-mode", "Replace"), NULL }, { GIMP_LAYER_MODE_ANTI_ERASE, NC_("layer-mode", "Anti erase"), NULL }, { 0, NULL, NULL } diff --git a/app/operations/operations-enums.h b/app/operations/operations-enums.h index 2a80ce8797..ef863b2b7c 100644 --- a/app/operations/operations-enums.h +++ b/app/operations/operations-enums.h @@ -118,6 +118,7 @@ typedef enum GIMP_LAYER_MODE_LUMINANCE, /*< desc="Luminance" >*/ GIMP_LAYER_MODE_COLOR_ERASE, /*< desc="Color erase" >*/ GIMP_LAYER_MODE_ERASE, /*< desc="Erase" >*/ + GIMP_LAYER_MODE_MONO_MIX, /*< desc="Mono mix" >*/ /* Internal modes, not available to the PDB, must be kept at the end */ GIMP_LAYER_MODE_REPLACE, /*< pdb-skip, desc="Replace" >*/ diff --git a/libgimp/gimpenums.h b/libgimp/gimpenums.h index 85e4f11149..8a4c105199 100644 --- a/libgimp/gimpenums.h +++ b/libgimp/gimpenums.h @@ -153,7 +153,8 @@ typedef enum GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY, GIMP_LAYER_MODE_LUMINANCE, GIMP_LAYER_MODE_COLOR_ERASE, - GIMP_LAYER_MODE_ERASE + GIMP_LAYER_MODE_ERASE, + GIMP_LAYER_MODE_MONO_MIX } GimpLayerMode; diff --git a/tools/pdbgen/enums.pl b/tools/pdbgen/enums.pl index dfb361830a..93512e1f8b 100644 --- a/tools/pdbgen/enums.pl +++ b/tools/pdbgen/enums.pl @@ -747,7 +747,8 @@ package Gimp::CodeGen::enums; GIMP_LAYER_MODE_LUMA_DARKEN_ONLY GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY GIMP_LAYER_MODE_LUMINANCE - GIMP_LAYER_MODE_COLOR_ERASE GIMP_LAYER_MODE_ERASE) ], + GIMP_LAYER_MODE_COLOR_ERASE GIMP_LAYER_MODE_ERASE + GIMP_LAYER_MODE_MONO_MIX) ], mapping => { GIMP_LAYER_MODE_NORMAL_LEGACY => '0', GIMP_LAYER_MODE_DISSOLVE => '1', GIMP_LAYER_MODE_BEHIND_LEGACY => '2', @@ -806,7 +807,8 @@ package Gimp::CodeGen::enums; GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY => '55', GIMP_LAYER_MODE_LUMINANCE => '56', GIMP_LAYER_MODE_COLOR_ERASE => '57', - GIMP_LAYER_MODE_ERASE => '58' } + GIMP_LAYER_MODE_ERASE => '58', + GIMP_LAYER_MODE_MONO_MIX => '59' } }, GimpConvertDitherType => { contig => 1,