diff --git a/app/core/core-enums.c b/app/core/core-enums.c index 392468a6b7..45a962b0ac 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -333,6 +333,10 @@ gimp_layer_mode_get_type (void) { GIMP_LAYER_MODE_HSV_VALUE, "GIMP_LAYER_MODE_HSV_VALUE", "hsv-value" }, { GIMP_LAYER_MODE_DIVIDE, "GIMP_LAYER_MODE_DIVIDE", "divide" }, { GIMP_LAYER_MODE_BURN, "GIMP_LAYER_MODE_BURN", "burn" }, + { GIMP_LAYER_MODE_HARDLIGHT, "GIMP_LAYER_MODE_HARDLIGHT", "hardlight" }, + { GIMP_LAYER_MODE_SOFTLIGHT, "GIMP_LAYER_MODE_SOFTLIGHT", "softlight" }, + { GIMP_LAYER_MODE_GRAIN_EXTRACT, "GIMP_LAYER_MODE_GRAIN_EXTRACT", "grain-extract" }, + { GIMP_LAYER_MODE_GRAIN_MERGE, "GIMP_LAYER_MODE_GRAIN_MERGE", "grain-merge" }, { 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" }, @@ -359,10 +363,10 @@ gimp_layer_mode_get_type (void) { GIMP_LAYER_MODE_DIVIDE_LEGACY, NC_("layer-mode", "Divide (legacy)"), NULL }, { GIMP_LAYER_MODE_DODGE_LEGACY, NC_("layer-mode", "Dodge (legacy)"), NULL }, { GIMP_LAYER_MODE_BURN_LEGACY, NC_("layer-mode", "Burn (legacy)"), NULL }, - { GIMP_LAYER_MODE_HARDLIGHT_LEGACY, NC_("layer-mode", "Hard light"), NULL }, - { GIMP_LAYER_MODE_SOFTLIGHT_LEGACY, NC_("layer-mode", "Soft light"), NULL }, - { GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY, NC_("layer-mode", "Grain extract"), NULL }, - { GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY, NC_("layer-mode", "Grain merge"), NULL }, + { GIMP_LAYER_MODE_HARDLIGHT_LEGACY, NC_("layer-mode", "Hard light (legacy)"), NULL }, + { GIMP_LAYER_MODE_SOFTLIGHT_LEGACY, NC_("layer-mode", "Soft light (legacy)"), NULL }, + { GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY, NC_("layer-mode", "Grain extract (legacy)"), NULL }, + { GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY, NC_("layer-mode", "Grain merge (legacy)"), NULL }, { GIMP_LAYER_MODE_COLOR_ERASE, NC_("layer-mode", "Color erase"), NULL }, { GIMP_LAYER_MODE_OVERLAY, NC_("layer-mode", "Overlay"), NULL }, { GIMP_LAYER_MODE_LCH_HUE, NC_("layer-mode", "Hue (LCH)"), NULL }, @@ -385,6 +389,10 @@ gimp_layer_mode_get_type (void) { GIMP_LAYER_MODE_HSV_VALUE, NC_("layer-mode", "Value (HSV)"), NULL }, { GIMP_LAYER_MODE_DIVIDE, NC_("layer-mode", "Divide"), NULL }, { GIMP_LAYER_MODE_BURN, NC_("layer-mode", "Burn"), NULL }, + { GIMP_LAYER_MODE_HARDLIGHT, NC_("layer-mode", "Hard light"), NULL }, + { GIMP_LAYER_MODE_SOFTLIGHT, NC_("layer-mode", "Soft light"), NULL }, + { GIMP_LAYER_MODE_GRAIN_EXTRACT, NC_("layer-mode", "Grain extract"), NULL }, + { GIMP_LAYER_MODE_GRAIN_MERGE, NC_("layer-mode", "Grain merge"), 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 66be49a16b..99eeb743c5 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -174,8 +174,8 @@ typedef enum GIMP_LAYER_MODE_BURN_LEGACY, /*< desc="Burn (legacy)" >*/ GIMP_LAYER_MODE_HARDLIGHT_LEGACY, /*< desc="Hard light (legacy)" >*/ GIMP_LAYER_MODE_SOFTLIGHT_LEGACY, /*< desc="Soft light (legacy)" >*/ - GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY, /*< desc="Grain extract" >*/ - GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY, /*< desc="Grain merge" >*/ + GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY, /*< desc="Grain extract (legacy)">*/ + GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY, /*< desc="Grain merge (legacy)" >*/ GIMP_LAYER_MODE_COLOR_ERASE, /*< desc="Color erase" >*/ GIMP_LAYER_MODE_OVERLAY, /*< desc="Overlay" >*/ GIMP_LAYER_MODE_LCH_HUE, /*< desc="Hue (LCH)" >*/ @@ -200,6 +200,8 @@ typedef enum GIMP_LAYER_MODE_BURN, /*< desc="Burn" >*/ GIMP_LAYER_MODE_HARDLIGHT, /*< desc="Hard light" >*/ GIMP_LAYER_MODE_SOFTLIGHT, /*< desc="Soft light" >*/ + GIMP_LAYER_MODE_GRAIN_EXTRACT, /*< desc="Grain extract" >*/ + GIMP_LAYER_MODE_GRAIN_MERGE, /*< desc="Grain merge" >*/ /* internal modes, not available to the PDB */ GIMP_LAYER_MODE_ERASE = 1000, /*< pdb-skip, desc="Erase" >*/ diff --git a/app/gegl/gimp-gegl-nodes.c b/app/gegl/gimp-gegl-nodes.c index af7c049478..2ce3dbacbf 100644 --- a/app/gegl/gimp-gegl-nodes.c +++ b/app/gegl/gimp-gegl-nodes.c @@ -295,12 +295,20 @@ gimp_gegl_mode_node_set_mode (GeglNode *node, operation = "gimp:softlight-legacy"; break; + case GIMP_LAYER_MODE_GRAIN_EXTRACT: + operation = "gimp:grain-extract"; + break; + case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY: - operation = "gimp:grain-extract-mode"; + operation = "gimp:grain-extract-legacy"; + break; + + case GIMP_LAYER_MODE_GRAIN_MERGE: + operation = "gimp:grain-merge"; break; case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY: - operation = "gimp:grain-merge-mode"; + operation = "gimp:grain-merge-legacy"; break; case GIMP_LAYER_MODE_COLOR_ERASE: @@ -398,7 +406,9 @@ gimp_gegl_mode_node_set_mode (GeglNode *node, case GIMP_LAYER_MODE_BURN_LEGACY: case GIMP_LAYER_MODE_HARDLIGHT_LEGACY: case GIMP_LAYER_MODE_SOFTLIGHT_LEGACY: + case GIMP_LAYER_MODE_GRAIN_EXTRACT: case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY: + case GIMP_LAYER_MODE_GRAIN_MERGE: case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY: case GIMP_LAYER_MODE_COLOR_ERASE: case GIMP_LAYER_MODE_OVERLAY: diff --git a/app/operations/Makefile.am b/app/operations/Makefile.am index 1c2b21e2f3..977ebd7a14 100644 --- a/app/operations/Makefile.am +++ b/app/operations/Makefile.am @@ -99,10 +99,6 @@ libappoperations_a_SOURCES = \ gimpoperationpointlayermode.h \ gimpoperationbehindmode.c \ gimpoperationbehindmode.h \ - gimpoperationgrainextractmode.c \ - gimpoperationgrainextractmode.h \ - gimpoperationgrainmergemode.c \ - gimpoperationgrainmergemode.h \ gimpoperationcolorerasemode.c \ gimpoperationcolorerasemode.h \ gimpoperationreplacemode.c \ diff --git a/app/operations/gimp-operations.c b/app/operations/gimp-operations.c index 77ea6211ec..444712c75f 100644 --- a/app/operations/gimp-operations.c +++ b/app/operations/gimp-operations.c @@ -102,8 +102,10 @@ #include "layer-modes-legacy/gimpoperationhardlightlegacy.h" #include "layer-modes/gimpoperationsoftlight.h" #include "layer-modes-legacy/gimpoperationsoftlightlegacy.h" -#include "gimpoperationgrainextractmode.h" -#include "gimpoperationgrainmergemode.h" +#include "layer-modes/gimpoperationgrainextract.h" +#include "layer-modes-legacy/gimpoperationgrainextractlegacy.h" +#include "layer-modes/gimpoperationgrainmerge.h" +#include "layer-modes-legacy/gimpoperationgrainmergelegacy.h" #include "gimpoperationcolorerasemode.h" #include "layer-modes/gimpoperationlchhue.h" #include "layer-modes/gimpoperationlchchroma.h" @@ -182,8 +184,10 @@ gimp_operations_init (void) 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_MODE); - g_type_class_ref (GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE); + 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_MODE); g_type_class_ref (GIMP_TYPE_OPERATION_LCH_HUE); g_type_class_ref (GIMP_TYPE_OPERATION_LCH_CHROMA); diff --git a/app/operations/gimplayermodefunctions.c b/app/operations/gimplayermodefunctions.c index 5642b1a180..7f07bd1488 100644 --- a/app/operations/gimplayermodefunctions.c +++ b/app/operations/gimplayermodefunctions.c @@ -62,8 +62,10 @@ #include "layer-modes-legacy/gimpoperationhardlightlegacy.h" #include "layer-modes/gimpoperationsoftlight.h" #include "layer-modes-legacy/gimpoperationsoftlightlegacy.h" -#include "gimpoperationgrainextractmode.h" -#include "gimpoperationgrainmergemode.h" +#include "layer-modes/gimpoperationgrainextract.h" +#include "layer-modes-legacy/gimpoperationgrainextractlegacy.h" +#include "layer-modes/gimpoperationgrainmerge.h" +#include "layer-modes-legacy/gimpoperationgrainmergelegacy.h" #include "gimpoperationcolorerasemode.h" #include "layer-modes/gimpoperationlchhue.h" #include "layer-modes/gimpoperationlchchroma.h" @@ -111,7 +113,7 @@ get_layer_mode_function (GimpLayerMode paint_mode, break; case GIMP_LAYER_MODE_OVERLAY_LEGACY: - func = gimp_operation_softlight_mode_process_pixels; + func = gimp_operation_softlight_legacy_process_pixels; break; case GIMP_LAYER_MODE_DIFFERENCE_LEGACY: @@ -226,12 +228,20 @@ get_layer_mode_function (GimpLayerMode paint_mode, func = gimp_operation_softlight_legacy_process_pixels; break; + case GIMP_LAYER_MODE_GRAIN_EXTRACT: + func = gimp_operation_grain_extract_process_pixels; + break; + case GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY: - func = gimp_operation_grain_extract_mode_process_pixels; + func = gimp_operation_grain_extract_legacy_process_pixels; + break; + + case GIMP_LAYER_MODE_GRAIN_MERGE: + func = gimp_operation_grain_merge_process_pixels; break; case GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY: - func = gimp_operation_grain_merge_mode_process_pixels; + func = gimp_operation_grain_merge_legacy_process_pixels; break; case GIMP_LAYER_MODE_COLOR_ERASE: diff --git a/app/operations/gimpoperationgrainextractmode.h b/app/operations/gimpoperationgrainextractmode.h deleted file mode 100644 index ba38525426..0000000000 --- a/app/operations/gimpoperationgrainextractmode.h +++ /dev/null @@ -1,61 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpoperationgrain_extractmode.h - * Copyright (C) 2008 Michael Natterer - * - * 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 . - */ - -#ifndef __GIMP_OPERATION_GRAIN_EXTRACT_MODE_H__ -#define __GIMP_OPERATION_GRAIN_EXTRACT_MODE_H__ - - -#include "gimpoperationpointlayermode.h" - - -#define GIMP_TYPE_OPERATION_GRAIN_EXTRACT_MODE (gimp_operation_grain_extract_mode_get_type ()) -#define GIMP_OPERATION_GRAIN_EXTRACT_MODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_GRAIN_EXTRACT_MODE, GimpOperationGrainExtractMode)) -#define GIMP_OPERATION_GRAIN_EXTRACT_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPERATION_GRAIN_EXTRACT_MODE, GimpOperationGrainExtractModeClass)) -#define GIMP_IS_OPERATION_GRAIN_EXTRACT_MODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_GRAIN_EXTRACT_MODE)) -#define GIMP_IS_OPERATION_GRAIN_EXTRACT_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OPERATION_GRAIN_EXTRACT_MODE)) -#define GIMP_OPERATION_GRAIN_EXTRACT_MODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OPERATION_GRAIN_EXTRACT_MODE, GimpOperationGrainExtractModeClass)) - - -typedef struct _GimpOperationGrainExtractMode GimpOperationGrainExtractMode; -typedef struct _GimpOperationGrainExtractModeClass GimpOperationGrainExtractModeClass; - -struct _GimpOperationGrainExtractMode -{ - GimpOperationPointLayerMode parent_instance; -}; - -struct _GimpOperationGrainExtractModeClass -{ - GimpOperationPointLayerModeClass parent_class; -}; - - -GType gimp_operation_grain_extract_mode_get_type (void) G_GNUC_CONST; - -gboolean gimp_operation_grain_extract_mode_process_pixels (gfloat *in, - gfloat *layer, - gfloat *mask, - gfloat *out, - gfloat opacity, - glong samples, - const GeglRectangle *roi, - gint level); - -#endif /* __GIMP_OPERATION_GRAIN_EXTRACT_MODE_H__ */ diff --git a/app/operations/gimpoperationgrainmergemode.h b/app/operations/gimpoperationgrainmergemode.h deleted file mode 100644 index 40b2602c3d..0000000000 --- a/app/operations/gimpoperationgrainmergemode.h +++ /dev/null @@ -1,61 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * gimpoperationgrain_mergemode.h - * Copyright (C) 2008 Michael Natterer - * - * 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 . - */ - -#ifndef __GIMP_OPERATION_GRAIN_MERGE_MODE_H__ -#define __GIMP_OPERATION_GRAIN_MERGE_MODE_H__ - - -#include "gimpoperationpointlayermode.h" - - -#define GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE (gimp_operation_grain_merge_mode_get_type ()) -#define GIMP_OPERATION_GRAIN_MERGE_MODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE, GimpOperationGrainMergeMode)) -#define GIMP_OPERATION_GRAIN_MERGE_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE, GimpOperationGrainMergeModeClass)) -#define GIMP_IS_OPERATION_GRAIN_MERGE_MODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE)) -#define GIMP_IS_OPERATION_GRAIN_MERGE_MODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE)) -#define GIMP_OPERATION_GRAIN_MERGE_MODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_OPERATION_GRAIN_MERGE_MODE, GimpOperationGrainMergeModeClass)) - - -typedef struct _GimpOperationGrainMergeMode GimpOperationGrainMergeMode; -typedef struct _GimpOperationGrainMergeModeClass GimpOperationGrainMergeModeClass; - -struct _GimpOperationGrainMergeMode -{ - GimpOperationPointLayerMode parent_instance; -}; - -struct _GimpOperationGrainMergeModeClass -{ - GimpOperationPointLayerModeClass parent_class; -}; - - -GType gimp_operation_grain_merge_mode_get_type (void) G_GNUC_CONST; - -gboolean gimp_operation_grain_merge_mode_process_pixels (gfloat *in, - gfloat *layer, - gfloat *mask, - gfloat *out, - gfloat opacity, - glong samples, - const GeglRectangle *roi, - gint level); - -#endif /* __GIMP_OPERATION_GRAIN_MERGE_MODE_H__ */ diff --git a/app/operations/layer-modes-legacy/Makefile.am b/app/operations/layer-modes-legacy/Makefile.am index 88c642444b..37675ede4a 100644 --- a/app/operations/layer-modes-legacy/Makefile.am +++ b/app/operations/layer-modes-legacy/Makefile.am @@ -46,5 +46,9 @@ libapplayermodeslegacy_a_SOURCES = \ gimpoperationhardlightlegacy.c \ gimpoperationhardlightlegacy.h \ gimpoperationsoftlightlegacy.c \ - gimpoperationsoftlightlegacy.h + gimpoperationsoftlightlegacy.h \ + gimpoperationgrainextractlegacy.c \ + gimpoperationgrainextractlegacy.h \ + gimpoperationgrainmergelegacy.c \ + gimpoperationgrainmergelegacy.h diff --git a/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c b/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c new file mode 100644 index 0000000000..1ee14de758 --- /dev/null +++ b/app/operations/layer-modes-legacy/gimpoperationgrainextractlegacy.c @@ -0,0 +1,138 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationgrainextractmode.c + * Copyright (C) 2008 Michael Natterer + * 2012 Ville Sokk + * + * 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 . + */ + +#include "config.h" + +#include + +#include "../operations-types.h" + +#include "gimpoperationgrainextractlegacy.h" + + +static gboolean gimp_operation_grain_extract_legacy_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); + + +G_DEFINE_TYPE (GimpOperationGrainExtractLegacy, gimp_operation_grain_extract_legacy, + GIMP_TYPE_OPERATION_POINT_LAYER_MODE) + + +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); + + 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; +} + +static void +gimp_operation_grain_extract_legacy_init (GimpOperationGrainExtractLegacy *self) +{ +} + +static gboolean +gimp_operation_grain_extract_legacy_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level) +{ + gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; + + return gimp_operation_grain_extract_legacy_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); +} + +gboolean +gimp_operation_grain_extract_legacy_process_pixels (gfloat *in, + gfloat *layer, + gfloat *mask, + gfloat *out, + gfloat opacity, + glong samples, + const GeglRectangle *roi, + gint level) +{ + const gboolean has_mask = mask != NULL; + + while (samples--) + { + gfloat comp_alpha, new_alpha; + + comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity; + if (has_mask) + comp_alpha *= *mask; + + new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha; + + if (comp_alpha && new_alpha) + { + gfloat ratio = comp_alpha / new_alpha; + gint b; + + for (b = RED; b < ALPHA; b++) + { + gfloat comp = in[b] - layer[b] + 0.5; + + out[b] = comp * ratio + in[b] * (1.0 - ratio); + out[b] = CLAMP (out[b], 0.0, 1.0); + } + } + else + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + out[b] = in[b]; + } + } + + out[ALPHA] = in[ALPHA]; + + in += 4; + layer += 4; + out += 4; + + if (has_mask) + mask++; + } + + return TRUE; +} diff --git a/app/operations/gimpoperationgrainextractmode.c b/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c similarity index 69% rename from app/operations/gimpoperationgrainextractmode.c rename to app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c index 9c4041db0f..9ee16909a9 100644 --- a/app/operations/gimpoperationgrainextractmode.c +++ b/app/operations/layer-modes-legacy/gimpoperationgrainmergelegacy.c @@ -1,7 +1,7 @@ /* GIMP - The GNU Image Manipulation Program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpoperationgrainextractmode.c + * gimpoperationgrainmergemode.c * Copyright (C) 2008 Michael Natterer * 2012 Ville Sokk * @@ -23,27 +23,27 @@ #include -#include "operations-types.h" +#include "../operations-types.h" -#include "gimpoperationgrainextractmode.h" +#include "gimpoperationgrainmergelegacy.h" -static gboolean gimp_operation_grain_extract_mode_process (GeglOperation *operation, - void *in_buf, - void *aux_buf, - void *aux2_buf, - void *out_buf, - glong samples, - const GeglRectangle *roi, - gint level); +static gboolean gimp_operation_grain_merge_legacy_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); -G_DEFINE_TYPE (GimpOperationGrainExtractMode, gimp_operation_grain_extract_mode, +G_DEFINE_TYPE (GimpOperationGrainMergeLegacy, gimp_operation_grain_merge_legacy, GIMP_TYPE_OPERATION_POINT_LAYER_MODE) static void -gimp_operation_grain_extract_mode_class_init (GimpOperationGrainExtractModeClass *klass) +gimp_operation_grain_merge_legacy_class_init (GimpOperationGrainMergeLegacyClass *klass) { GeglOperationClass *operation_class; GeglOperationPointComposer3Class *point_class; @@ -52,20 +52,20 @@ gimp_operation_grain_extract_mode_class_init (GimpOperationGrainExtractModeClass point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass); gegl_operation_class_set_keys (operation_class, - "name", "gimp:grain-extract-mode", - "description", "GIMP grain extract mode operation", + "name", "gimp:grain-merge-legacy", + "description", "GIMP grain merge mode operation", NULL); - point_class->process = gimp_operation_grain_extract_mode_process; + point_class->process = gimp_operation_grain_merge_legacy_process; } static void -gimp_operation_grain_extract_mode_init (GimpOperationGrainExtractMode *self) +gimp_operation_grain_merge_legacy_init (GimpOperationGrainMergeLegacy *self) { } static gboolean -gimp_operation_grain_extract_mode_process (GeglOperation *operation, +gimp_operation_grain_merge_legacy_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, @@ -76,11 +76,11 @@ gimp_operation_grain_extract_mode_process (GeglOperation *operation, { gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; - return gimp_operation_grain_extract_mode_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); + return gimp_operation_grain_merge_legacy_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); } gboolean -gimp_operation_grain_extract_mode_process_pixels (gfloat *in, +gimp_operation_grain_merge_legacy_process_pixels (gfloat *in, gfloat *layer, gfloat *mask, gfloat *out, @@ -108,7 +108,7 @@ gimp_operation_grain_extract_mode_process_pixels (gfloat *in, for (b = RED; b < ALPHA; b++) { - gfloat comp = in[b] - layer[b] + 0.5; + gfloat comp = in[b] + layer[b] - 0.5; out[b] = comp * ratio + in[b] * (1.0 - ratio); out[b] = CLAMP (out[b], 0.0, 1.0); @@ -131,7 +131,7 @@ gimp_operation_grain_extract_mode_process_pixels (gfloat *in, out += 4; if (has_mask) - mask++; + mask ++; } return TRUE; diff --git a/app/operations/gimpoperationgrainmergemode.c b/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c similarity index 77% rename from app/operations/gimpoperationgrainmergemode.c rename to app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c index e3feade0a7..826bca6f17 100644 --- a/app/operations/gimpoperationgrainmergemode.c +++ b/app/operations/layer-modes-legacy/gimpoperationhardlightlegacy.c @@ -1,7 +1,7 @@ /* GIMP - The GNU Image Manipulation Program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * - * gimpoperationgrainmergemode.c + * gimpoperationhardlightmode.c * Copyright (C) 2008 Michael Natterer * 2012 Ville Sokk * @@ -23,12 +23,12 @@ #include -#include "operations-types.h" +#include "../operations-types.h" -#include "gimpoperationgrainmergemode.h" +#include "gimpoperationhardlightlegacy.h" -static gboolean gimp_operation_grain_merge_mode_process (GeglOperation *operation, +static gboolean gimp_operation_hardlight_legacy_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, @@ -36,14 +36,14 @@ static gboolean gimp_operation_grain_merge_mode_process (GeglOperation *op glong samples, const GeglRectangle *roi, gint level); + - -G_DEFINE_TYPE (GimpOperationGrainMergeMode, gimp_operation_grain_merge_mode, +G_DEFINE_TYPE (GimpOperationHardlightLegacy, gimp_operation_hardlight_legacy, GIMP_TYPE_OPERATION_POINT_LAYER_MODE) static void -gimp_operation_grain_merge_mode_class_init (GimpOperationGrainMergeModeClass *klass) +gimp_operation_hardlight_legacy_class_init (GimpOperationHardlightLegacyClass *klass) { GeglOperationClass *operation_class; GeglOperationPointComposer3Class *point_class; @@ -52,20 +52,20 @@ gimp_operation_grain_merge_mode_class_init (GimpOperationGrainMergeModeClass *kl point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass); gegl_operation_class_set_keys (operation_class, - "name", "gimp:grain-merge-mode", - "description", "GIMP grain merge mode operation", + "name", "gimp:hardlight-legacy", + "description", "GIMP hardlight mode operation", NULL); - point_class->process = gimp_operation_grain_merge_mode_process; + point_class->process = gimp_operation_hardlight_legacy_process; } static void -gimp_operation_grain_merge_mode_init (GimpOperationGrainMergeMode *self) +gimp_operation_hardlight_legacy_init (GimpOperationHardlightLegacy *self) { } static gboolean -gimp_operation_grain_merge_mode_process (GeglOperation *operation, +gimp_operation_hardlight_legacy_process (GeglOperation *operation, void *in_buf, void *aux_buf, void *aux2_buf, @@ -76,11 +76,11 @@ gimp_operation_grain_merge_mode_process (GeglOperation *operation, { gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; - return gimp_operation_grain_merge_mode_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); + return gimp_operation_hardlight_legacy_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); } gboolean -gimp_operation_grain_merge_mode_process_pixels (gfloat *in, +gimp_operation_hardlight_legacy_process_pixels (gfloat *in, gfloat *layer, gfloat *mask, gfloat *out, @@ -108,10 +108,20 @@ gimp_operation_grain_merge_mode_process_pixels (gfloat *in, for (b = RED; b < ALPHA; b++) { - gfloat comp = in[b] + layer[b] - 0.5; + gfloat comp; + + if (layer[b] > 0.5) + { + comp = (1.0 - in[b]) * (1.0 - (layer[b] - 0.5) * 2.0); + comp = MIN (1 - comp, 1); + } + else + { + comp = in[b] * (layer[b] * 2.0); + comp = MIN (comp, 1.0); + } out[b] = comp * ratio + in[b] * (1.0 - ratio); - out[b] = CLAMP (out[b], 0.0, 1.0); } } else diff --git a/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c b/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c new file mode 100644 index 0000000000..ee1e4ed7a0 --- /dev/null +++ b/app/operations/layer-modes-legacy/gimpoperationsoftlightlegacy.c @@ -0,0 +1,169 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationsoftlightmode.c + * Copyright (C) 2008 Michael Natterer + * 2012 Ville Sokk + * + * 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 . + */ + +#include "config.h" + +#include + +#include "../operations-types.h" + +#include "gimpoperationsoftlightlegacy.h" + + +static gboolean gimp_operation_softlight_legacy_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); + + +G_DEFINE_TYPE (GimpOperationSoftlightLegacy, gimp_operation_softlight_legacy, + GIMP_TYPE_OPERATION_POINT_LAYER_MODE) + +static const gchar* reference_xml = "" +"" +"" +" " +" " +" B.png" +" " +" " +"" +"" +" " +" A.png" +" " +"" +""; + + +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); + + gegl_operation_class_set_keys (operation_class, + "name", "gimp:softlight-legacy", + "description", "GIMP softlight mode operation", + "reference-image", "soft-light-mode.png", + "reference-composition", reference_xml, + NULL); + + point_class->process = gimp_operation_softlight_legacy_process; +} + +static void +gimp_operation_softlight_legacy_init (GimpOperationSoftlightLegacy *self) +{ +} + +static gboolean +gimp_operation_softlight_legacy_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level) +{ + gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; + + return gimp_operation_softlight_legacy_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); +} + +gboolean +gimp_operation_softlight_legacy_process_pixels (gfloat *in, + gfloat *layer, + gfloat *mask, + gfloat *out, + gfloat opacity, + glong samples, + const GeglRectangle *roi, + gint level) +{ + const gboolean has_mask = mask != NULL; + + while (samples--) + { + gfloat comp_alpha, new_alpha; + + comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity; + if (has_mask) + comp_alpha *= *mask; + + new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha; + + if (comp_alpha && new_alpha) + { + gfloat ratio = comp_alpha / new_alpha; + gint b; + + for (b = RED; b < ALPHA; b++) + { +#if 0 + /* softlight is now used for what GIMP formerly called + * OVERLAY. We fixed OVERLAY to use the right math + * (under the name NEW_OVERLAY), and redirect uses of + * the old OVERLAY blend mode here. This math was + * formerly used for OVERLAY and is exactly the same as + * the multiply, screen, comp math used below. + * See bug #673501. + */ + gfloat comp = in[b] * (in[b] + (2.0 * layer[b]) * (1.0 - in[b])); +#endif + + gfloat multiply = in[b] * layer[b]; + gfloat screen = 1.0 - (1.0 - in[b]) * (1.0 - layer[b]); + gfloat comp = (1.0 - in[b]) * multiply + in[b] * screen; + + out[b] = comp * ratio + in[b] * (1.0 - ratio); + } + } + else + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + out[b] = in[b]; + } + } + + out[ALPHA] = in[ALPHA]; + + in += 4; + layer += 4; + out += 4; + + if (has_mask) + mask ++; + } + + return TRUE; +} diff --git a/app/operations/layer-modes/Makefile.am b/app/operations/layer-modes/Makefile.am index 84cee81b66..9e0d04a66a 100644 --- a/app/operations/layer-modes/Makefile.am +++ b/app/operations/layer-modes/Makefile.am @@ -68,7 +68,11 @@ libapplayermodes_generic_a_sources = \ gimpoperationhardlight.c \ gimpoperationhardlight.h \ gimpoperationsoftlight.c \ - gimpoperationsoftlight.h + gimpoperationsoftlight.h \ + gimpoperationgrainextract.c \ + gimpoperationgrainextract.h \ + gimpoperationgrainmerge.c \ + gimpoperationgrainmerge.h libapplayermodes_sse2_a_sources = \ gimpoperationnormal-sse2.c diff --git a/app/operations/layer-modes/gimpoperationgrainextract.c b/app/operations/layer-modes/gimpoperationgrainextract.c new file mode 100644 index 0000000000..733bb4624c --- /dev/null +++ b/app/operations/layer-modes/gimpoperationgrainextract.c @@ -0,0 +1,136 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationgrainextractmode.c + * Copyright (C) 2008 Michael Natterer + * 2012 Ville Sokk + * 2017 Øyvind Kolås + * + * 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 . + */ + +#include "config.h" + +#include + +#include "../operations-types.h" + +#include "gimpoperationgrainextract.h" + + +static gboolean gimp_operation_grain_extract_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); + + +G_DEFINE_TYPE (GimpOperationGrainExtract, gimp_operation_grain_extract, + GIMP_TYPE_OPERATION_POINT_LAYER_MODE) + + +static void +gimp_operation_grain_extract_class_init (GimpOperationGrainExtractClass *klass) +{ + GeglOperationClass *operation_class; + GeglOperationPointComposer3Class *point_class; + + operation_class = GEGL_OPERATION_CLASS (klass); + point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass); + + gegl_operation_class_set_keys (operation_class, + "name", "gimp:grain-extract", + "description", "GIMP grain extract mode operation", + NULL); + + point_class->process = gimp_operation_grain_extract_process; +} + +static void +gimp_operation_grain_extract_init (GimpOperationGrainExtract *self) +{ +} + +static gboolean +gimp_operation_grain_extract_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level) +{ + gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; + + return gimp_operation_grain_extract_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); +} + +gboolean +gimp_operation_grain_extract_process_pixels (gfloat *in, + gfloat *layer, + gfloat *mask, + gfloat *out, + gfloat opacity, + glong samples, + const GeglRectangle *roi, + gint level) +{ + const gboolean has_mask = mask != NULL; + + while (samples--) + { + gfloat comp_alpha; + + comp_alpha = MIN (in[ALPHA], layer[ALPHA]) * opacity; + if (has_mask) + comp_alpha *= *mask; + + if (comp_alpha != 0.0f) + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + gfloat comp = in[b] - layer[b] + 0.5; + + out[b] = comp * comp_alpha + in[b] * (1.0 - comp_alpha); + out[b] = CLAMP (out[b], 0.0, 1.0); + } + } + else + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + out[b] = in[b]; + } + } + + out[ALPHA] = in[ALPHA]; + + in += 4; + layer += 4; + out += 4; + + if (has_mask) + mask++; + } + + return TRUE; +} diff --git a/app/operations/layer-modes/gimpoperationgrainmerge.c b/app/operations/layer-modes/gimpoperationgrainmerge.c new file mode 100644 index 0000000000..cd626fbcbe --- /dev/null +++ b/app/operations/layer-modes/gimpoperationgrainmerge.c @@ -0,0 +1,136 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationgrainmergemode.c + * Copyright (C) 2008 Michael Natterer + * 2012 Ville Sokk + * 2017 Øyvind Kolås + * + * 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 . + */ + +#include "config.h" + +#include + +#include "../operations-types.h" + +#include "gimpoperationgrainmerge.h" + + +static gboolean gimp_operation_grain_merge_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); + + +G_DEFINE_TYPE (GimpOperationGrainMerge, gimp_operation_grain_merge, + GIMP_TYPE_OPERATION_POINT_LAYER_MODE) + + +static void +gimp_operation_grain_merge_class_init (GimpOperationGrainMergeClass *klass) +{ + GeglOperationClass *operation_class; + GeglOperationPointComposer3Class *point_class; + + operation_class = GEGL_OPERATION_CLASS (klass); + point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass); + + gegl_operation_class_set_keys (operation_class, + "name", "gimp:grain-merge", + "description", "GIMP grain merge mode operation", + NULL); + + point_class->process = gimp_operation_grain_merge_process; +} + +static void +gimp_operation_grain_merge_init (GimpOperationGrainMerge *self) +{ +} + +static gboolean +gimp_operation_grain_merge_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level) +{ + gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; + + return gimp_operation_grain_merge_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); +} + +gboolean +gimp_operation_grain_merge_process_pixels (gfloat *in, + gfloat *layer, + gfloat *mask, + gfloat *out, + gfloat opacity, + glong samples, + const GeglRectangle *roi, + gint level) +{ + const gboolean has_mask = mask != NULL; + + while (samples--) + { + gfloat comp_alpha; + + comp_alpha = layer[ALPHA] * opacity; + if (has_mask) + comp_alpha *= *mask; + + if (comp_alpha != 0.0) + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + gfloat comp = in[b] + layer[b] - 0.5; + + out[b] = comp * comp_alpha + in[b] * (1.0 - comp_alpha); + out[b] = CLAMP (out[b], 0.0, 1.0); + } + } + else + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + out[b] = in[b]; + } + } + + out[ALPHA] = in[ALPHA]; + + in += 4; + layer += 4; + out += 4; + + if (has_mask) + mask ++; + } + + return TRUE; +} diff --git a/app/operations/layer-modes/gimpoperationhardlight.c b/app/operations/layer-modes/gimpoperationhardlight.c new file mode 100644 index 0000000000..34b8db26c7 --- /dev/null +++ b/app/operations/layer-modes/gimpoperationhardlight.c @@ -0,0 +1,148 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationhardlightmode.c + * Copyright (C) 2008 Michael Natterer + * 2012 Ville Sokk + * + * 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 . + */ + +#include "config.h" + +#include + +#include "../operations-types.h" + +#include "gimpoperationhardlight.h" + + +static gboolean gimp_operation_hardlight_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); + + +G_DEFINE_TYPE (GimpOperationHardlight, gimp_operation_hardlight, + GIMP_TYPE_OPERATION_POINT_LAYER_MODE) + + +static void +gimp_operation_hardlight_class_init (GimpOperationHardlightClass *klass) +{ + GeglOperationClass *operation_class; + GeglOperationPointComposer3Class *point_class; + + operation_class = GEGL_OPERATION_CLASS (klass); + point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass); + + gegl_operation_class_set_keys (operation_class, + "name", "gimp:hardlight", + "description", "GIMP hardlight mode operation", + NULL); + + point_class->process = gimp_operation_hardlight_process; +} + +static void +gimp_operation_hardlight_init (GimpOperationHardlight *self) +{ +} + +static gboolean +gimp_operation_hardlight_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level) +{ + gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; + + return gimp_operation_hardlight_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); +} + +gboolean +gimp_operation_hardlight_process_pixels (gfloat *in, + gfloat *layer, + gfloat *mask, + gfloat *out, + gfloat opacity, + glong samples, + const GeglRectangle *roi, + gint level) +{ + const gboolean has_mask = mask != NULL; + + while (samples--) + { + gfloat comp_alpha, new_alpha; + + comp_alpha = layer[ALPHA] * opacity; + if (has_mask) + comp_alpha *= *mask; + + new_alpha = in[ALPHA] + (1.0 - in[ALPHA]) * comp_alpha; + + if (comp_alpha && new_alpha) + { + gfloat ratio = comp_alpha / new_alpha; + gint b; + + for (b = RED; b < ALPHA; b++) + { + gfloat comp; + + if (layer[b] > 0.5) + { + comp = (1.0 - in[b]) * (1.0 - (layer[b] - 0.5) * 2.0); + comp = MIN (1 - comp, 1); + } + else + { + comp = in[b] * (layer[b] * 2.0); + comp = MIN (comp, 1.0); + } + + out[b] = comp * ratio + in[b] * (1.0 - ratio); + } + } + else + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + out[b] = in[b]; + } + } + + out[ALPHA] = in[ALPHA]; + + in += 4; + layer += 4; + out += 4; + + if (has_mask) + mask ++; + } + + return TRUE; +} diff --git a/app/operations/layer-modes/gimpoperationsoftlight.c b/app/operations/layer-modes/gimpoperationsoftlight.c new file mode 100644 index 0000000000..74b3ea1588 --- /dev/null +++ b/app/operations/layer-modes/gimpoperationsoftlight.c @@ -0,0 +1,166 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpoperationsoftlightmode.c + * Copyright (C) 2008 Michael Natterer + * 2012 Ville Sokk + * + * 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 . + */ + +#include "config.h" + +#include + +#include "../operations-types.h" + +#include "gimpoperationsoftlight.h" + + +static gboolean gimp_operation_softlight_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level); + + +G_DEFINE_TYPE (GimpOperationSoftlight, gimp_operation_softlight, + GIMP_TYPE_OPERATION_POINT_LAYER_MODE) + +static const gchar* reference_xml = "" +"" +"" +" " +" " +" B.png" +" " +" " +"" +"" +" " +" A.png" +" " +"" +""; + + +static void +gimp_operation_softlight_class_init (GimpOperationSoftlightClass *klass) +{ + GeglOperationClass *operation_class; + GeglOperationPointComposer3Class *point_class; + + operation_class = GEGL_OPERATION_CLASS (klass); + point_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass); + + gegl_operation_class_set_keys (operation_class, + "name", "gimp:softlight", + "description", "GIMP softlight mode operation", + "reference-image", "soft-light-mode.png", + "reference-composition", reference_xml, + NULL); + + point_class->process = gimp_operation_softlight_process; +} + +static void +gimp_operation_softlight_init (GimpOperationSoftlight *self) +{ +} + +static gboolean +gimp_operation_softlight_process (GeglOperation *operation, + void *in_buf, + void *aux_buf, + void *aux2_buf, + void *out_buf, + glong samples, + const GeglRectangle *roi, + gint level) +{ + gfloat opacity = GIMP_OPERATION_POINT_LAYER_MODE (operation)->opacity; + + return gimp_operation_softlight_process_pixels (in_buf, aux_buf, aux2_buf, out_buf, opacity, samples, roi, level); +} + +gboolean +gimp_operation_softlight_process_pixels (gfloat *in, + gfloat *layer, + gfloat *mask, + gfloat *out, + gfloat opacity, + glong samples, + const GeglRectangle *roi, + gint level) +{ + const gboolean has_mask = mask != NULL; + + while (samples--) + { + gfloat comp_alpha; + + comp_alpha = layer[ALPHA] * opacity; + if (has_mask) + comp_alpha *= *mask; + + if (comp_alpha != 0.0f) + { + gint b; + + for (b = RED; b < ALPHA; b++) + { +#if 0 + /* softlight is now used for what GIMP formerly called + * OVERLAY. We fixed OVERLAY to use the right math + * (under the name NEW_OVERLAY), and redirect uses of + * the old OVERLAY blend mode here. This math was + * formerly used for OVERLAY and is exactly the same as + * the multiply, screen, comp math used below. + * See bug #673501. + */ + gfloat comp = in[b] * (in[b] + (2.0 * layer[b]) * (1.0 - in[b])); +#endif + + gfloat multiply = in[b] * layer[b]; + gfloat screen = 1.0 - (1.0 - in[b]) * (1.0 - layer[b]); + gfloat comp = (1.0 - in[b]) * multiply + in[b] * screen; + + out[b] = comp * comp_alpha + in[b] * (1.0 - comp_alpha); + } + } + else + { + gint b; + + for (b = RED; b < ALPHA; b++) + { + out[b] = in[b]; + } + } + + out[ALPHA] = in[ALPHA]; + + in += 4; + layer += 4; + out += 4; + + if (has_mask) + mask ++; + } + + return TRUE; +} diff --git a/app/widgets/gimpwidgets-constructors.c b/app/widgets/gimpwidgets-constructors.c index 9b65231582..ecf60f8e4d 100644 --- a/app/widgets/gimpwidgets-constructors.c +++ b/app/widgets/gimpwidgets-constructors.c @@ -104,7 +104,7 @@ gimp_paint_mode_menu_new (gboolean with_behind_mode, GtkWidget *combo; store = gimp_enum_store_new_with_values (GIMP_TYPE_LAYER_MODE, - 43, + 45, GIMP_LAYER_MODE_NORMAL, GIMP_LAYER_MODE_NORMAL_NON_LINEAR, GIMP_LAYER_MODE_DISSOLVE, @@ -132,7 +132,9 @@ gimp_paint_mode_menu_new (gboolean with_behind_mode, GIMP_LAYER_MODE_DIFFERENCE_LEGACY, GIMP_LAYER_MODE_SUBTRACT, GIMP_LAYER_MODE_SUBTRACT_LEGACY, + GIMP_LAYER_MODE_GRAIN_EXTRACT, GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY, + GIMP_LAYER_MODE_GRAIN_MERGE, GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY, GIMP_LAYER_MODE_DIVIDE, GIMP_LAYER_MODE_DIVIDE_LEGACY, diff --git a/libgimp/gimpenums.h b/libgimp/gimpenums.h index 61902613f0..b956c4701f 100644 --- a/libgimp/gimpenums.h +++ b/libgimp/gimpenums.h @@ -112,7 +112,11 @@ typedef enum GIMP_LAYER_MODE_HSV_COLOR, GIMP_LAYER_MODE_HSV_VALUE, GIMP_LAYER_MODE_DIVIDE, - GIMP_LAYER_MODE_BURN + GIMP_LAYER_MODE_BURN, + GIMP_LAYER_MODE_HARDLIGHT, + GIMP_LAYER_MODE_SOFTLIGHT, + GIMP_LAYER_MODE_GRAIN_EXTRACT, + GIMP_LAYER_MODE_GRAIN_MERGE } GimpLayerMode; diff --git a/tools/pdbgen/enums.pl b/tools/pdbgen/enums.pl index 28ed6a004b..3711e5b9fa 100644 --- a/tools/pdbgen/enums.pl +++ b/tools/pdbgen/enums.pl @@ -732,7 +732,10 @@ package Gimp::CodeGen::enums; GIMP_LAYER_MODE_HSV_SATURATION GIMP_LAYER_MODE_HSV_COLOR GIMP_LAYER_MODE_HSV_VALUE GIMP_LAYER_MODE_DIVIDE - GIMP_LAYER_MODE_BURN) ], + GIMP_LAYER_MODE_BURN GIMP_LAYER_MODE_HARDLIGHT + GIMP_LAYER_MODE_SOFTLIGHT + GIMP_LAYER_MODE_GRAIN_EXTRACT + GIMP_LAYER_MODE_GRAIN_MERGE) ], mapping => { GIMP_LAYER_MODE_NORMAL_NON_LINEAR => '0', GIMP_LAYER_MODE_DISSOLVE => '1', GIMP_LAYER_MODE_BEHIND => '2', @@ -776,7 +779,11 @@ package Gimp::CodeGen::enums; GIMP_LAYER_MODE_HSV_COLOR => '40', GIMP_LAYER_MODE_HSV_VALUE => '41', GIMP_LAYER_MODE_DIVIDE => '42', - GIMP_LAYER_MODE_BURN => '43' } + GIMP_LAYER_MODE_BURN => '43', + GIMP_LAYER_MODE_HARDLIGHT => '44', + GIMP_LAYER_MODE_SOFTLIGHT => '45', + GIMP_LAYER_MODE_GRAIN_EXTRACT => '46', + GIMP_LAYER_MODE_GRAIN_MERGE => '47' } }, GimpBrushApplicationMode => { contig => 1,