GIMP Chat
http://gimpchat.com/

Plugin gives non-destructive GEGL Filters in 2.99.19+ layer mask
http://gimpchat.com/viewtopic.php?f=9&t=20881
Page 1 of 1

Author:  contrast_ [ Fri Apr 26, 2024 3:49 pm ]
Post subject:  Plugin gives non-destructive GEGL Filters in 2.99.19+ layer mask

I made a new GEGL plugin that gives layer mask to individual non-destructive GEGL filters. It is going to be released soon.

It allows 3 GEGL ops and four GEGL commands in total. (Gaussian blur, Hue rotation, Lightness and Saturation) to be given a layer mask via a transparent image file upload. Soon there will be more filters to use with layer mask. This is a hack because in the future non-destructive GEGL filters will have layer mask of their own and this will be entirely deprecated. Below is an attached pic showing the Plasma filter in GIMP given a non-destructive layer mask of gaussian blur with an image file upload as the mask parameters.


Non-destructive filters Plamsa and gaussian blur
but Gaussian Blur has a layer mask of its own

Attachment:
image_file_mayer_mask.png
image_file_mayer_mask.png [ 715.04 KiB | Viewed 274 times ]


Gaussian Blur and all filters here are labelled "hack mask" unfortunately they cannot use their original names.
Attachment:
hack_mask2.png
hack_mask2.png [ 14.86 KiB | Viewed 274 times ]



If you can't wait and want to test this plugin now here is the code to compile it

/* This file is an image processing operation for GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
* 2024 Beaver, Hacky Mask

Plugin recreated as a GEGL graph here -
assumes gaussian blur is being used and you have my file path.


id=1
gaussian-blur std-dev-x=33 std-dev-y=33
dst-in aux=[ layer src=/home/USERNAME/Pictures/Magic/pattern_fills/pattern_christmas-tree-1_1_2_0-0_0_1__ffffff00_ffffff_ffec3d_f44034_53910d.png ]
dst-over aux=[ ref=1  ]


*/

#include "config.h"
#include <glib/gi18n-lib.h>


#ifdef GEGL_PROPERTIES


enum_start (invert_hackmask)
  enum_value (MASK,      "standard",
              N_("Default Mask"))
  enum_value (INVERT_MASK,      "invert",
              N_("Invert Mask"))
enum_end (inverthackmask)

property_boolean (invertmask, _("Invert Mask"), FALSE)
  description    (_("Invert Mask"))


/*
property_enum (invertmask, _("Default or inverted"),
    inverthackmask, invert_hackmask,
    MASK)
   description  (_("Optionally invert the mask"))
*/
property_file_path(imagemask, _("Image File (layer mask)"), "")
    description (_("Image file that functions as a layer mask...)"))


property_enum (filterselect, _("Select a filter"),
    maskhack, mask_hack,
    adjustments)
   description  (_("Choose a filter for the hacky layer mask."))

enum_start (mask_hack)
  enum_value (adjustments,      "adjustments",
              N_("Adjustments"))
  enum_value (blur,      "blur",
              N_("Blur"))
enum_end (maskhack)

property_double (saturation, _("Saturation"), 1)
  value_range (0.0, 4.0)
  ui_range    (0.0, 4.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Saturation filter"))
ui_meta ("visible", "!filterselect {blur }" )

property_double (lightness, _("Lightness"), 0)
  value_range (-100.0, 100.0)
  ui_range    (-100.0, 100.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Lightness filter  "))
ui_meta ("visible", "!filterselect {blur }" )

property_double (hue, _("Hue"), 0)
  value_range (-180.0, 180.0)
  ui_range    (-180.0, 180.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Hue rotation filter  "))
ui_meta ("visible", "!filterselect {blur }" )

property_double (blur, _("Blur"), 0)
  value_range (0.0, 300.0)
  ui_range    (0.0, 200.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Gaussian Blur filter"))
ui_meta ("visible", "!filterselect {adjustments }" )


#else

#define GEGL_OP_META
#define GEGL_OP_NAME     maskhack
#define GEGL_OP_C_SOURCE maskhack.c

#include "gegl-op.h"

typedef struct
{
GeglNode *input;
GeglNode *saturation;
GeglNode *lighthue;
GeglNode *eraseblendmode;
GeglNode *behindblendmode;
GeglNode *imagemask;
GeglNode *color;
GeglNode *blur;
GeglNode *output;
}State;

static void attach (GeglOperation *operation)
{
  GeglNode *gegl = operation->node;
  GeglProperties *o = GEGL_PROPERTIES (operation);

  State *state = o->user_data = g_malloc0 (sizeof (State));

  state->input    = gegl_node_get_input_proxy (gegl, "input");
  state->output   = gegl_node_get_output_proxy (gegl, "output");

  state->eraseblendmode    = gegl_node_new_child (gegl,
                                  "operation", "gegl:dst-in",
                                  NULL);

  state->behindblendmode    = gegl_node_new_child (gegl,
                                  "operation", "gegl:dst-over",
                                  NULL);

state->imagemask    = gegl_node_new_child (gegl,
                                  "operation", "gegl:layer",
                                  NULL);

  state->saturation    = gegl_node_new_child (gegl,
                                  "operation", "gegl:saturation",
                                  NULL);
  state->lighthue    = gegl_node_new_child (gegl,
                                  "operation", "gegl:hue-chroma",
                                  NULL);
  state->blur    = gegl_node_new_child (gegl,
                                  "operation", "gegl:gaussian-blur",
                                  NULL);
/*
  state->sharpen    = gegl_node_new_child (gegl,
                                  "operation", "gegl:unsharp-mask",
                                  NULL);

  state->denoise    = gegl_node_new_child (gegl,
                                  "operation", "gegl:denoise-dct", "sigma", 1,
                                  NULL);

  state->noisereduction    = gegl_node_new_child (gegl,
                                  "operation", "gegl:noise-reduction", "iterations", 1,
                                  NULL);

  state->meancurvatureblur    = gegl_node_new_child (gegl,
                                  "operation", "gegl:mean-curvature-blur", "iterations", 1,
                                  NULL);
*/
  gegl_operation_meta_redirect (operation, "imagemask",  state->imagemask, "src");
  gegl_operation_meta_redirect (operation, "saturation",  state->saturation, "scale");
  gegl_operation_meta_redirect (operation, "lightness",  state->lighthue, "lightness");
  gegl_operation_meta_redirect (operation, "hue",  state->lighthue, "hue");
  gegl_operation_meta_redirect (operation, "blur",  state->blur, "std-dev-x");
  gegl_operation_meta_redirect (operation, "blur",  state->blur, "std-dev-y");
/*
  gegl_operation_meta_redirect (operation, "sharpen",  state->sharpen, "radius");
  gegl_operation_meta_redirect (operation, "sharpen",  state->sharpen, "amount");
  gegl_operation_meta_redirect (operation, "denoise",  state->denoise, "sigma");
  gegl_operation_meta_redirect (operation, "noisereduction",  state->noisereduction, "iterations");
*/
}

static void update_graph (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  State *state = o->user_data;
  if (!state) return;

  const char *mask_op = "gegl:nop";
  switch (o->invertmask) {
    case MASK:  mask_op = "gegl:dst-in"; break;
    case INVERT_MASK:  mask_op = "gegl:dst-out"; break;
  }
  gegl_node_set (state->eraseblendmode, "operation", mask_op, NULL);

switch (o->filterselect) {
        break;
    case adjustments:
  gegl_node_link_many (state->input,  state->saturation, state->lighthue,  state->eraseblendmode, state->behindblendmode, state->output,   NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case blur:
  gegl_node_link_many (state->input, state->blur,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
    }
  }
static void
gegl_op_class_init (GeglOpClass *klass)
{
  GeglOperationClass *operation_class;
GeglOperationMetaClass *operation_meta_class = GEGL_OPERATION_META_CLASS (klass);
  operation_class = GEGL_OPERATION_CLASS (klass);

  operation_class->attach = attach;
  operation_meta_class->update = update_graph;

  gegl_operation_class_set_keys (operation_class,
    "name",        "lb:mask-hack",
    "title",       _("Mask Hack"),
    "reference-hash", "gimp29919devworld",
    "description", _("Create a layer mask for non-destructive filters in early GIMP 3 by uploading image files as a mask. "),
    "gimp:menu-path", "<Image>/Filters/Generic",
    "gimp:menu-label", _("Non-Destructive filter layer mask hack"),
    NULL);
}

#endif



Please note - in default this filter makes a glitch effect until it receives an image file. In default opacity is replaced with the filter and transparency is knocked out but it can be inverted with the checkbox

Author:  contrast_ [ Fri Apr 26, 2024 5:59 pm ]
Post subject:  Re: Layer Mask for non-destructive GEGL filters Gimp 2.99.19-3 HACK pl

code updated to include sharpen (unsharp mask) and denoise as non-destructive layer mask

/* This file is an image processing operation for GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
* 2024 Beaver, Hacky Mask

Plugin recreated as a GEGL graph here -
assumes gaussian blur is being used and you have my file path.


id=1
gaussian-blur std-dev-x=33 std-dev-y=33
dst-in aux=[ layer src=/home/USERNAME/Pictures/Magic/pattern_fills/pattern_christmas-tree-1_1_2_0-0_0_1__ffffff00_ffffff_ffec3d_f44034_53910d.png ]
dst-over aux=[ ref=1  ]


*/

#include "config.h"
#include <glib/gi18n-lib.h>


#ifdef GEGL_PROPERTIES


enum_start (invert_hackmask)
  enum_value (MASK,      "standard",
              N_("Default Mask"))
  enum_value (INVERT_MASK,      "invert",
              N_("Invert Mask"))
enum_end (inverthackmask)

property_boolean (invertmask, _("Invert Mask"), FALSE)
  description    (_("Invert Mask"))


/*
property_enum (invertmask, _("Default or inverted"),
    inverthackmask, invert_hackmask,
    MASK)
   description  (_("Optionally invert the mask"))
*/
property_file_path(imagemask, _("Image File (layer mask)"), "")
    description (_("Image file that functions as a layer mask...)"))


property_enum (filterselect, _("Select a filter"),
    maskhack, mask_hack,
    adjustments)
   description  (_("Choose a filter for the hacky layer mask."))

enum_start (mask_hack)
  enum_value (adjustments,      "adjustments",
              N_("Adjustments"))
  enum_value (blur,      "blur",
              N_("Blur"))
  enum_value (sharpen,      "sharpen",
              N_("Sharpen"))
  enum_value (denoise,      "denoise",
              N_("Denoise"))
enum_end (maskhack)

property_double (saturation, _("Saturation"), 1)
  value_range (0.0, 5.0)
  ui_range    (0.0, 4.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Saturation filter"))
ui_meta ("visible", "!filterselect {blur, sharpen, denoise }" )

property_double (lightness, _("Lightness"), 0)
  value_range (-200.0, 200.0)
  ui_range    (-100.0, 100.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Lightness filter  "))
ui_meta ("visible", "!filterselect {blur, sharpen, denoise }" )

property_double (hue, _("Hue"), 0)
  value_range (-180.0, 180.0)
  ui_range    (-180.0, 180.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Hue rotation filter  "))
ui_meta ("visible", "!filterselect {blur, sharpen, denoise }" )

property_double (blur, _("Blur"), 0)
  value_range (0.0, 300.0)
  ui_range    (0.0, 200.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Gaussian Blur filter"))
ui_meta ("visible", "!filterselect {adjustments, sharpen, denoise, }" )

property_double (sharpenradius, _("Sharpen Radius"), 0.0)
    description(_("Sharpen radius"))
    value_range (0.0, 150)
    ui_range    (0.0, 40.0)
    ui_gamma    (3.0)
    ui_meta     ("unit", "pixel-distance")
ui_meta ("visible", "!filterselect {adjustments, blur, denoise }" )

property_double (sharpenscale, _("Sharpen Amount"), 0.5)
    description(_("Scaling factor for unsharp-mask, the strength of effect"))
    value_range (0.0, 300.0)
    ui_range    (0.0, 10.0)
    ui_gamma    (3.0)
ui_meta ("visible", "!filterselect {adjustments, blur, denoise }" )

property_int (denoise, _("Denoise Strength"), 1)
    description (_("Noise standard deviation"))
    ui_range    (1, 30)
    value_range (1, 100)
ui_meta ("visible", "!filterselect {adjustments, blur, sharpen }" )
#else

#define GEGL_OP_META
#define GEGL_OP_NAME     maskhack
#define GEGL_OP_C_SOURCE maskhack.c

#include "gegl-op.h"

typedef struct
{
GeglNode *input;
GeglNode *saturation;
GeglNode *lighthue;
GeglNode *eraseblendmode;
GeglNode *behindblendmode;
GeglNode *imagemask;
GeglNode *color;
GeglNode *blur;
GeglNode *sharpen;
GeglNode *denoise;
GeglNode *output;
}State;

static void attach (GeglOperation *operation)
{
  GeglNode *gegl = operation->node;
  GeglProperties *o = GEGL_PROPERTIES (operation);

  State *state = o->user_data = g_malloc0 (sizeof (State));

  state->input    = gegl_node_get_input_proxy (gegl, "input");
  state->output   = gegl_node_get_output_proxy (gegl, "output");

  state->eraseblendmode    = gegl_node_new_child (gegl,
                                  "operation", "gegl:dst-in",
                                  NULL);

  state->behindblendmode    = gegl_node_new_child (gegl,
                                  "operation", "gegl:dst-over",
                                  NULL);

state->imagemask    = gegl_node_new_child (gegl,
                                  "operation", "gegl:layer",
                                  NULL);

  state->saturation    = gegl_node_new_child (gegl,
                                  "operation", "gegl:saturation",
                                  NULL);
  state->lighthue    = gegl_node_new_child (gegl,
                                  "operation", "gegl:hue-chroma",
                                  NULL);
  state->blur    = gegl_node_new_child (gegl,
                                  "operation", "gegl:gaussian-blur",
                                  NULL);
  state->sharpen    = gegl_node_new_child (gegl,
                                  "operation", "gegl:unsharp-mask",
                                  NULL);
  state->denoise    = gegl_node_new_child (gegl,
                                  "operation", "gegl:denoise-dct",
                                  NULL);
/*
  state->denoise    = gegl_node_new_child (gegl,
                                  "operation", "gegl:denoise-dct", "sigma", 1,
                                  NULL);

  state->noisereduction    = gegl_node_new_child (gegl,
                                  "operation", "gegl:noise-reduction", "iterations", 1,
                                  NULL);

  state->meancurvatureblur    = gegl_node_new_child (gegl,
                                  "operation", "gegl:mean-curvature-blur", "iterations", 1,
                                  NULL);
*/
  gegl_operation_meta_redirect (operation, "imagemask",  state->imagemask, "src");
  gegl_operation_meta_redirect (operation, "saturation",  state->saturation, "scale");
  gegl_operation_meta_redirect (operation, "lightness",  state->lighthue, "lightness");
  gegl_operation_meta_redirect (operation, "hue",  state->lighthue, "hue");
  gegl_operation_meta_redirect (operation, "blur",  state->blur, "std-dev-x");
  gegl_operation_meta_redirect (operation, "blur",  state->blur, "std-dev-y");
  gegl_operation_meta_redirect (operation, "sharpenradius",  state->sharpen, "std-dev");
  gegl_operation_meta_redirect (operation, "sharpenscale",  state->sharpen, "scale");
  gegl_operation_meta_redirect (operation, "denoise",  state->denoise, "sigma");
/*
  gegl_operation_meta_redirect (operation, "noisereduction",  state->noisereduction, "iterations");
*/
}

static void update_graph (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  State *state = o->user_data;
  if (!state) return;

  const char *mask_op = "gegl:nop";
  switch (o->invertmask) {
    case MASK:  mask_op = "gegl:dst-in"; break;
    case INVERT_MASK:  mask_op = "gegl:dst-out"; break;
  }
  gegl_node_set (state->eraseblendmode, "operation", mask_op, NULL);

switch (o->filterselect) {
        break;
    case adjustments:
  gegl_node_link_many (state->input,  state->saturation, state->lighthue,  state->eraseblendmode, state->behindblendmode, state->output,   NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case blur:
  gegl_node_link_many (state->input, state->blur,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case sharpen:
  gegl_node_link_many (state->input, state->sharpen,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case denoise:
  gegl_node_link_many (state->input, state->denoise,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
    }
  }
static void
gegl_op_class_init (GeglOpClass *klass)
{
  GeglOperationClass *operation_class;
GeglOperationMetaClass *operation_meta_class = GEGL_OPERATION_META_CLASS (klass);
  operation_class = GEGL_OPERATION_CLASS (klass);

  operation_class->attach = attach;
  operation_meta_class->update = update_graph;

  gegl_operation_class_set_keys (operation_class,
    "name",        "lb:mask-hack",
    "title",       _("Mask Hack"),
    "reference-hash", "gimp29919devworld",
    "description", _("Create a layer mask for non-destructive filters in early GIMP 3 by uploading image files as a mask. "),
    "gimp:menu-path", "<Image>/Filters/Generic",
    "gimp:menu-label", _("Non-Destructive filter layer mask hack"),
    NULL);
}

#endif


Preview of update with denoise filter as a mask

Attachment:
masking_zebra.png
masking_zebra.png [ 899.95 KiB | Viewed 243 times ]


It will be on Github soon

Author:  contrast_ [ Fri Apr 26, 2024 8:03 pm ]
Post subject:  Re: Plugin gives non-destructive GEGL Filters in 2.99.19+ layer mask

Layer Mask filter being used three times for the background only

1. Hue rotation
2. Gaussian Blur blended by a blend mode
3. Denoise dct

Then it is followed by a normal softglow, sharpen and black color overlay at 10% opacity that applies to everything

-
Before Effects
Attachment:
2024-04-26_20-59.png
2024-04-26_20-59.png [ 707.96 KiB | Viewed 231 times ]


After Effects
Attachment:
2024-04-26_20-59_1.png
2024-04-26_20-59_1.png [ 654.54 KiB | Viewed 231 times ]



Source code for the latest update that includes Gaussian blur with blend modes (nicked named orton) is here

/* This file is an image processing operation for GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås <pippin@gimp.org>
* 2024 Beaver, Hacky Mask

Plugin recreated as a GEGL graph here -
assumes gaussian blur is being used and you have my file path.


id=1
gaussian-blur std-dev-x=33 std-dev-y=33
dst-in aux=[ layer src=/home/USERNAME/Pictures/Magic/pattern_fills/pattern_christmas-tree-1_1_2_0-0_0_1__ffffff00_ffffff_ffec3d_f44034_53910d.png ]
dst-over aux=[ ref=1  ]


*/

#include "config.h"
#include <glib/gi18n-lib.h>


#ifdef GEGL_PROPERTIES

enum_start (orton_time)
  enum_value (HARDLIGHT,      "hardlight",
              N_("Hard Light"))
  enum_value (OVERLAY,      "overlay",
              N_("Overlay"))
  enum_value (MULTIPLY,      "multiply",
              N_("Multiply"))
  enum_value (ADD,      "add",
              N_("Add"))
enum_end (ortontime)



enum_start (invert_hackmask)
  enum_value (MASK,      "standard",
              N_("Default Mask"))
  enum_value (INVERT_MASK,      "invert",
              N_("Invert Mask"))
enum_end (inverthackmask)

property_boolean (invertmask, _("Invert Mask"), FALSE)
  description    (_("Invert Mask"))


/*
property_enum (invertmask, _("Default or inverted"),
    inverthackmask, invert_hackmask,
    MASK)
   description  (_("Optionally invert the mask"))
*/
property_file_path(imagemask, _("Image File (layer mask)"), "")
    description (_("Image file that functions as a layer mask...)"))


property_enum (filterselect, _("Select a filter"),
    maskhack, mask_hack,
    adjustments)
   description  (_("Choose a filter for the hacky layer mask."))

enum_start (mask_hack)
  enum_value (adjustments,      "adjustments",
              N_("Adjustments"))
  enum_value (blur,      "blur",
              N_("Blur"))
  enum_value (sharpen,      "sharpen",
              N_("Sharpen"))
  enum_value (denoise,      "denoise",
              N_("Denoise"))
  enum_value (orton,      "orton",
              N_("Orton (blur blended)"))
enum_end (maskhack)

property_double (saturation, _("Saturation"), 1)
  value_range (0.0, 5.0)
  ui_range    (0.0, 4.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Saturation filter"))
ui_meta ("visible", "!filterselect {blur, sharpen, denoise, orton }" )

property_double (lightness, _("Lightness"), 0)
  value_range (-200.0, 200.0)
  ui_range    (-100.0, 100.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Lightness filter  "))
ui_meta ("visible", "!filterselect {blur, sharpen, denoise, orton }" )

property_double (hue, _("Hue"), 0)
  value_range (-180.0, 180.0)
  ui_range    (-180.0, 180.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Hue rotation filter  "))
ui_meta ("visible", "!filterselect {blur, sharpen, denoise, orton }" )

property_double (blur, _("Blur"), 0)
  value_range (0.0, 300.0)
  ui_range    (0.0, 200.0)
  ui_meta     ("unit", "pixel-distance")
  description (_("Gaussian Blur filter"))
ui_meta ("visible", "!filterselect {adjustments, sharpen, denoise }" )

property_double (sharpenradius, _("Sharpen Radius"), 0.0)
    description(_("Sharpen radius"))
    value_range (0.0, 150)
    ui_range    (0.0, 40.0)
    ui_gamma    (3.0)
    ui_meta     ("unit", "pixel-distance")
ui_meta ("visible", "!filterselect {adjustments, blur, denoise, orton }" )

property_double (sharpenscale, _("Sharpen Amount"), 0.5)
    description(_("Scaling factor for unsharp-mask, the strength of effect"))
    value_range (0.0, 300.0)
    ui_range    (0.0, 10.0)
    ui_gamma    (3.0)
ui_meta ("visible", "!filterselect {adjustments, blur, denoise, orton  }" )

property_int (denoise, _("Denoise Strength"), 1)
    description (_("Noise standard deviation"))
    ui_range    (1, 30)
    value_range (1, 100)
ui_meta ("visible", "!filterselect {adjustments, blur, sharpen, orton }" )


property_enum (ortonblendmode, _("Select a blend mode for the orton (gaussian blur blended)"),
    ortontime, orton_time,
    HARDLIGHT)
   description  (_("Choose a blend mode for the gaussian blur to blend with"))
ui_meta ("visible", "!filterselect {adjustments, blur, sharpen, denoise  }" )

#else

#define GEGL_OP_META
#define GEGL_OP_NAME     maskhack
#define GEGL_OP_C_SOURCE maskhack.c

#include "gegl-op.h"

typedef struct
{
GeglNode *input;
GeglNode *saturation;
GeglNode *lighthue;
GeglNode *eraseblendmode;
GeglNode *behindblendmode;
GeglNode *imagemask;
GeglNode *color;
GeglNode *blur;
GeglNode *sharpen;
GeglNode *hardlight;
GeglNode *multiply;
GeglNode *overlay;
GeglNode *add;
GeglNode *denoise;
GeglNode *output;
}State;

static void attach (GeglOperation *operation)
{
  GeglNode *gegl = operation->node;
  GeglProperties *o = GEGL_PROPERTIES (operation);

  State *state = o->user_data = g_malloc0 (sizeof (State));

  state->input    = gegl_node_get_input_proxy (gegl, "input");
  state->output   = gegl_node_get_output_proxy (gegl, "output");

  state->eraseblendmode    = gegl_node_new_child (gegl,
                                  "operation", "gegl:dst-in",
                                  NULL);

  state->behindblendmode    = gegl_node_new_child (gegl,
                                  "operation", "gegl:dst-over",
                                  NULL);

state->imagemask    = gegl_node_new_child (gegl,
                                  "operation", "gegl:layer",
                                  NULL);

  state->saturation    = gegl_node_new_child (gegl,
                                  "operation", "gegl:saturation",
                                  NULL);
  state->hardlight    = gegl_node_new_child (gegl,
                                  "operation", "gegl:hard-light", "srgb", TRUE,
                                  NULL);

  state->overlay    = gegl_node_new_child (gegl,
                                  "operation", "gegl:overlay", "srgb", TRUE,
                                  NULL);
  state->multiply    = gegl_node_new_child (gegl,
                                  "operation", "gegl:multiply",
                                  NULL);
  state->add    = gegl_node_new_child (gegl,
                                  "operation", "gegl:add",
                                  NULL);
  state->lighthue    = gegl_node_new_child (gegl,
                                  "operation", "gegl:hue-chroma",
                                  NULL);
  state->blur    = gegl_node_new_child (gegl,
                                  "operation", "gegl:gaussian-blur",
                                  NULL);
  state->sharpen    = gegl_node_new_child (gegl,
                                  "operation", "gegl:unsharp-mask",
                                  NULL);
  state->denoise    = gegl_node_new_child (gegl,
                                  "operation", "gegl:denoise-dct",
                                  NULL);
/*
  state->denoise    = gegl_node_new_child (gegl,
                                  "operation", "gegl:denoise-dct", "sigma", 1,
                                  NULL);

  state->noisereduction    = gegl_node_new_child (gegl,
                                  "operation", "gegl:noise-reduction", "iterations", 1,
                                  NULL);

  state->meancurvatureblur    = gegl_node_new_child (gegl,
                                  "operation", "gegl:mean-curvature-blur", "iterations", 1,
                                  NULL);
*/
  gegl_operation_meta_redirect (operation, "imagemask",  state->imagemask, "src");
  gegl_operation_meta_redirect (operation, "saturation",  state->saturation, "scale");
  gegl_operation_meta_redirect (operation, "lightness",  state->lighthue, "lightness");
  gegl_operation_meta_redirect (operation, "hue",  state->lighthue, "hue");
  gegl_operation_meta_redirect (operation, "blur",  state->blur, "std-dev-x");
  gegl_operation_meta_redirect (operation, "blur",  state->blur, "std-dev-y");
  gegl_operation_meta_redirect (operation, "sharpenradius",  state->sharpen, "std-dev");
  gegl_operation_meta_redirect (operation, "sharpenscale",  state->sharpen, "scale");
  gegl_operation_meta_redirect (operation, "denoise",  state->denoise, "sigma");
/*
  gegl_operation_meta_redirect (operation, "noisereduction",  state->noisereduction, "iterations");
*/
}

static void update_graph (GeglOperation *operation)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  State *state = o->user_data;
  if (!state) return;

  const char *mask_op = "gegl:nop";
  switch (o->invertmask) {
    case MASK:  mask_op = "gegl:dst-in"; break;
    case INVERT_MASK:  mask_op = "gegl:dst-out"; break;
  }
  gegl_node_set (state->eraseblendmode, "operation", mask_op, NULL);



  GeglNode *hardlight = state->hardlight;
  switch (o->ortonblendmode) {
    case HARDLIGHT: hardlight = state->hardlight; break;
    case OVERLAY: hardlight = state->overlay; break;
    case MULTIPLY: hardlight = state->multiply; break;
    case ADD: hardlight = state->add; break;
default: hardlight = state->hardlight;
}


switch (o->filterselect) {
        break;
    case adjustments:
  gegl_node_link_many (state->input,  state->saturation, state->lighthue,  state->eraseblendmode, state->behindblendmode, state->output,   NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case blur:
  gegl_node_link_many (state->input, state->blur,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case sharpen:
  gegl_node_link_many (state->input, state->sharpen,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case denoise:
  gegl_node_link_many (state->input, state->denoise,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");
        break;
    case orton:
  gegl_node_link_many (state->input, hardlight,  state->eraseblendmode, state->behindblendmode,  state->output,  NULL);
  gegl_node_connect (hardlight, "aux", state->blur, "output");
  gegl_node_link_many (state->input, state->blur, NULL);
  gegl_node_connect (state->eraseblendmode, "aux", state->imagemask, "output");
  gegl_node_connect (state->behindblendmode, "aux", state->input, "output");

    }
  }
static void
gegl_op_class_init (GeglOpClass *klass)
{
  GeglOperationClass *operation_class;
GeglOperationMetaClass *operation_meta_class = GEGL_OPERATION_META_CLASS (klass);
  operation_class = GEGL_OPERATION_CLASS (klass);

  operation_class->attach = attach;
  operation_meta_class->update = update_graph;

  gegl_operation_class_set_keys (operation_class,
    "name",        "lb:mask-hack",
    "title",       _("Mask Hack"),
    "reference-hash", "gimp29919devworld",
    "description", _("Create a layer mask for non-destructive filters in early GIMP 3 by uploading image files as a mask. "),
    "gimp:menu-path", "<Image>/Filters/Generic",
    "gimp:menu-label", _("Non-Destructive filter layer mask hack"),
    NULL);
}

#endif


Mask image file is here
Attachment:
zebra_mask.png
zebra_mask.png [ 60.6 KiB | Viewed 231 times ]

Page 1 of 1 All times are UTC - 5 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/