It is currently Tue May 14, 2024 8:51 pm


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Plugin gives non-destructive GEGL Filters in 2.99.19+ layer mask
PostPosted: Fri Apr 26, 2024 3:49 pm  (#1) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1423
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 191 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 191 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


Last edited by contrast_ on Fri Apr 26, 2024 6:09 pm, edited 1 time in total.

Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Re: Layer Mask for non-destructive GEGL filters Gimp 2.99.19-3 HACK pl
PostPosted: Fri Apr 26, 2024 5:59 pm  (#2) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1423
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 160 times ]


It will be on Github soon


Top
 Post subject: Re: Plugin gives non-destructive GEGL Filters in 2.99.19+ layer mask
PostPosted: Fri Apr 26, 2024 8:03 pm  (#3) 
Offline
GimpChat Member
User avatar

Joined: Oct 31, 2020
Posts: 1423
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 148 times ]


After Effects
Attachment:
2024-04-26_20-59_1.png
2024-04-26_20-59_1.png [ 654.54 KiB | Viewed 148 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 148 times ]


Top
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts Attachment(s) GEGL selection modification filter to apply on layer mask

8

No new posts CMYK student is going to implement non-destructive filters soon

0

No new posts Please make a python plugin to combine my GEGL filters with GMIC

1

No new posts Attachment(s) Baby's first GEGL plugin - a very basic GEGL plugin anyone can make.

9

No new posts Help! Script-fu gegl:gegl works on only some of my third party filters

5



* Login  



Powered by phpBB3 © phpBB Group