/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
 *
 * 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 <https://www.gnu.org/licenses/>.
 */

/* NOTE: This file is auto-generated by pdbgen.pl. */

#include "config.h"

#include <cairo.h>

#include <gegl.h>

#include <gdk-pixbuf/gdk-pixbuf.h>

#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h"
#include "libgimpmath/gimpmath.h"

#include "libgimpbase/gimpbase.h"

#include "pdb-types.h"

#include "config/gimpcoreconfig.h"
#include "core/gimp.h"
#include "core/gimpchannel.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable-operation.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage-color-profile.h"
#include "core/gimpimage-crop.h"
#include "core/gimpimage-resize.h"
#include "core/gimpimage-rotate.h"
#include "core/gimpimage-undo.h"
#include "core/gimpimage.h"
#include "core/gimpparamspecs.h"
#include "core/gimppickable-auto-shrink.h"
#include "core/gimppickable.h"
#include "gegl/gimp-babl.h"
#include "gegl/gimp-gegl-utils.h"

#include "gimppdb.h"
#include "gimppdberror.h"
#include "gimppdb-utils.h"
#include "gimpprocedure.h"
#include "internal-procs.h"

#include "gimp-intl.h"


static GeglNode *
wrap_in_graph (GeglNode *node)
{
  GeglNode *new_node;
  GeglNode *input;
  GeglNode *output;

  new_node = gegl_node_new ();

  gegl_node_add_child (new_node, node);
  g_object_unref (node);

  gimp_gegl_node_set_underlying_operation (new_node, node);

  input  = gegl_node_get_input_proxy  (new_node, "input");
  output = gegl_node_get_output_proxy (new_node, "output");

  gegl_node_link_many (input,
                       node,
                       output,
                       NULL);

  return new_node;
}

static GeglNode *
wrap_in_selection_bounds (GeglNode     *node,
                          GimpDrawable *drawable)
{
  gint x, y;
  gint width, height;

  if (gimp_item_mask_intersect (GIMP_ITEM (drawable),
                                &x, &y, &width, &height))
    {
      GeglNode *new_node;
      GeglNode *input;
      GeglNode *output;
      GeglNode *translate_before;
      GeglNode *crop;
      GeglNode *translate_after;

      new_node = gegl_node_new ();

      gegl_node_add_child (new_node, node);
      g_object_unref (node);

      gimp_gegl_node_set_underlying_operation (new_node, node);

      input  = gegl_node_get_input_proxy  (new_node, "input");
      output = gegl_node_get_output_proxy (new_node, "output");

      translate_before = gegl_node_new_child (new_node,
                                              "operation", "gegl:translate",
                                              "x",         (gdouble) -x,
                                              "y",         (gdouble) -y,
                                              NULL);
      crop = gegl_node_new_child (new_node,
                                  "operation", "gegl:crop",
                                  "width",     (gdouble) width,
                                  "height",    (gdouble) height,
                                  NULL);
      translate_after = gegl_node_new_child (new_node,
                                             "operation", "gegl:translate",
                                             "x",         (gdouble) x,
                                             "y",         (gdouble) y,
                                             NULL);

      gegl_node_link_many (input,
                           translate_before,
                           crop,
                           node,
                           translate_after,
                           output,
                           NULL);

      return new_node;
    }
  else
    {
      return node;
    }
}

static GeglNode *
wrap_in_gamma_cast (GeglNode     *node,
                    GimpDrawable *drawable)
{
  if (! gimp_drawable_get_linear (drawable))
    {
      const Babl *drawable_format;
      const Babl *cast_format;
      GeglNode   *new_node;
      GeglNode   *input;
      GeglNode   *output;
      GeglNode   *cast_before;
      GeglNode   *cast_after;

      drawable_format = gimp_drawable_get_format (drawable);

      cast_format =
        gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
                          gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
                                               TRUE),
                          babl_format_has_alpha (drawable_format));

      new_node = gegl_node_new ();

      gegl_node_add_child (new_node, node);
      g_object_unref (node);

      gimp_gegl_node_set_underlying_operation (new_node, node);

      input  = gegl_node_get_input_proxy  (new_node, "input");
      output = gegl_node_get_output_proxy (new_node, "output");

      cast_before = gegl_node_new_child (new_node,
                                         "operation",     "gegl:cast-format",
                                         "input-format",  drawable_format,
                                         "output-format", cast_format,
                                         NULL);
      cast_after  = gegl_node_new_child (new_node,
                                         "operation",     "gegl:cast-format",
                                         "input-format",  cast_format,
                                         "output-format", drawable_format,
                                         NULL);

      gegl_node_link_many (input,
                           cast_before,
                           node,
                           cast_after,
                           output,
                           NULL);

      return new_node;
    }
  else
    {
      return node;
    }
}

static GeglNode *
create_buffer_source_node (GeglNode     *parent,
                           GimpDrawable *drawable)
{
  GeglNode   *new_node;
  GeglBuffer *buffer;

  buffer = gimp_drawable_get_buffer (drawable);
  g_object_ref (buffer);
  new_node = gegl_node_new_child (parent,
                                  "operation", "gegl:buffer-source",
                                  "buffer", buffer,
                                  NULL);
  g_object_unref (buffer);
  return new_node;
}

static gboolean
bump_map (GimpDrawable *drawable,
          GimpDrawable *bump_map,
          gdouble       azimuth,
          gdouble       elevation,
          gint          depth,
          gint          offset_x,
          gint          offset_y,
          gdouble       waterlevel,
          gdouble       ambient,
          gboolean      compensate,
          gboolean      invert,
          gint          type,
          gboolean      tiled,
          GimpProgress  *progress,
          GError       **error)
{
  if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                 GIMP_PDB_ITEM_CONTENT, error) &&
      gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
    {
      GeglNode *graph;
      GeglNode *node;
      GeglNode *src_node;

      node = gegl_node_new_child (NULL,
                                  "operation", "gegl:bump-map",
                                  "tiled",      tiled,
                                  "type",       type,
                                  "compensate", compensate,
                                  "invert",     invert,
                                  "azimuth",    azimuth,
                                  "elevation",  elevation,
                                  "depth",      depth,
                                  "offset_x",   offset_x,
                                  "offset_y",   offset_y,
                                  "waterlevel", waterlevel,
                                  "ambient",    ambient,
                                  NULL);

      graph = wrap_in_graph (node);

      src_node = create_buffer_source_node (graph, bump_map);

      gegl_node_connect_to (src_node, "output", node, "aux");

      gimp_drawable_apply_operation (drawable, progress,
                                     C_("undo-type", "Bump Map"),
                                     graph);
      g_object_unref (graph);

      return TRUE;
    }
    else
      return FALSE;
}

static gboolean
displace (GimpDrawable  *drawable,
          gdouble        amount_x,
          gdouble        amount_y,
          gboolean       do_x,
          gboolean       do_y,
          GimpDrawable  *displace_map_x,
          GimpDrawable  *displace_map_y,
          gint           displace_type,
          gint           displace_mode,
          GimpProgress  *progress,
          GError       **error)
{
  if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                 GIMP_PDB_ITEM_CONTENT, error) &&
      gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
    {
      if (do_x || do_y)
        {
          GeglNode *graph;
          GeglNode *node;
          GeglAbyssPolicy abyss_policy = GEGL_ABYSS_NONE;

          switch (displace_type)
            {
              case 1:
                abyss_policy = GEGL_ABYSS_LOOP;
                break;
              case 2:
                abyss_policy = GEGL_ABYSS_CLAMP;
                break;
              case 3:
                abyss_policy = GEGL_ABYSS_BLACK;
                break;
            }

          node = gegl_node_new_child (NULL,
                                      "operation",     "gegl:displace",
                                      "displace_mode", displace_mode,
                                      "sampler_type",  GEGL_SAMPLER_CUBIC,
                                      "abyss_policy",  abyss_policy,
                                      "amount_x",      amount_x,
                                      "amount_y",      amount_y,
                                      NULL);

          graph = wrap_in_graph (node);

          if (do_x)
            {
              GeglNode *src_node;
              src_node = create_buffer_source_node (graph, displace_map_x);
              gegl_node_connect_to (src_node, "output", node, "aux");
            }

          if (do_y)
            {
              GeglNode *src_node;
              src_node = create_buffer_source_node (graph, displace_map_y);
              gegl_node_connect_to (src_node, "output", node, "aux2");
            }

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Displace"),
                                         graph);
          g_object_unref (graph);
        }

      return TRUE;
    }
  else
    return FALSE;
}

static gboolean
gaussian_blur (GimpDrawable  *drawable,
               gdouble        horizontal,
               gdouble        vertical,
               GimpProgress  *progress,
               GError       **error)
{
  if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                 GIMP_PDB_ITEM_CONTENT, error) &&
      gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
    {
      GeglNode *node;

      node = gegl_node_new_child (NULL,
                                  "operation",    "gegl:gaussian-blur",
                                  "std-dev-x",    horizontal * 0.32,
                                  "std-dev-y",    vertical   * 0.32,
                                  "abyss-policy", 1,
                                  NULL);

      node = wrap_in_gamma_cast (node, drawable);

      gimp_drawable_apply_operation (drawable, progress,
                                     C_("undo-type", "Gaussian Blur"),
                                     node);
      g_object_unref (node);

      return TRUE;
    }

  return FALSE;
}

static gint
newsprint_color_model (gint colorspace)
{
  switch (colorspace)
    {
    case 0: return 1; /* black on white */
    case 1: return 2; /* rgb */
    case 2: return 3; /* cmyk */
    case 3: return 1; /* black on white */
    }

  return 2;
}

static gint
newsprint_pattern (gint spotfn)
{
  switch (spotfn)
    {
    case 0: return 1; /* circle */
    case 1: return 0; /* line */
    case 2: return 2; /* diamond */
    case 3: return 4; /* ps circle */
    case 4: return 2; /* FIXME postscript diamond */
    }

  return 1;
}

static gdouble
newsprint_angle (gdouble angle)
{
  while (angle > 180.0)
    angle -= 360.0;

  while (angle < -180.0)
    angle += 360.0;

  return angle;
}

static GimpValueArray *
plug_in_alienmap2_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble redfrequency;
  gdouble redangle;
  gdouble greenfrequency;
  gdouble greenangle;
  gdouble bluefrequency;
  gdouble blueangle;
  guint8 colormodel;
  guint8 redmode;
  guint8 greenmode;
  guint8 bluemode;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  redfrequency = g_value_get_double (gimp_value_array_index (args, 3));
  redangle = g_value_get_double (gimp_value_array_index (args, 4));
  greenfrequency = g_value_get_double (gimp_value_array_index (args, 5));
  greenangle = g_value_get_double (gimp_value_array_index (args, 6));
  bluefrequency = g_value_get_double (gimp_value_array_index (args, 7));
  blueangle = g_value_get_double (gimp_value_array_index (args, 8));
  colormodel = g_value_get_uint (gimp_value_array_index (args, 9));
  redmode = g_value_get_uint (gimp_value_array_index (args, 10));
  greenmode = g_value_get_uint (gimp_value_array_index (args, 11));
  bluemode = g_value_get_uint (gimp_value_array_index (args, 12));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:alien-map",
                                 "color-model",      (gint)     colormodel,
                                 "cpn-1-frequency",  (gdouble)  redfrequency,
                                 "cpn-2-frequency",  (gdouble)  greenfrequency,
                                 "cpn-3-frequency",  (gdouble)  bluefrequency,
                                 "cpn-1-phaseshift", (gdouble)  redangle,
                                 "cpn-2-phaseshift", (gdouble)  greenangle,
                                 "cpn-3-phaseshift", (gdouble)  blueangle,
                                 "cpn-1-keep",       (gboolean) !redmode,
                                 "cpn-2-keep",       (gboolean) !greenmode,
                                 "cpn-3-keep",       (gboolean) !bluemode,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Alien Map"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_antialias_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:antialias",
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Antialias"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_apply_canvas_invoker (GimpProcedure         *procedure,
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 direction;
  gint32 depth;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  direction = g_value_get_int (gimp_value_array_index (args, 3));
  depth = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:texturize-canvas",
                                 "direction", direction,
                                 "depth",     depth,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Apply Canvas"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_applylens_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble refraction;
  gboolean keep_surroundings;
  gboolean set_background;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  refraction = g_value_get_double (gimp_value_array_index (args, 3));
  keep_surroundings = g_value_get_boolean (gimp_value_array_index (args, 4));
  set_background = g_value_get_boolean (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GimpRGB    color;
          GeglColor *gegl_color;
          GeglNode  *node;

          if (set_background)
            gimp_context_get_background (context, &color);
          else
            gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0);

          gegl_color = gimp_gegl_color_new (&color);

          node = gegl_node_new_child (NULL,
                                     "operation",         "gegl:apply-lens",
                                     "refraction-index",  refraction,
                                     "keep-surroundings", keep_surroundings,
                                     "background-color",  gegl_color,
                                     NULL);

          g_object_unref (gegl_color);

          node = wrap_in_selection_bounds (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Apply Lens"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_autocrop_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  GimpDrawable *drawable;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error))
        {
          gint x, y, width, height;
          gint off_x, off_y;

          gimp_pickable_auto_shrink (GIMP_PICKABLE (drawable),
                                     0, 0,
                                     gimp_item_get_width  (GIMP_ITEM (drawable)),
                                     gimp_item_get_height (GIMP_ITEM (drawable)),
                                     &x, &y, &width, &height);

          gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
          x += off_x;
          y += off_y;

          gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
                                       _("Autocrop image"));

          if (x          < 0                             ||
              y          < 0                             ||
              x + width  > gimp_image_get_width  (image) ||
              y + height > gimp_image_get_height (image))
            {
              /*
               * partially outside the image area, we need to
               * resize the image to be able to crop properly.
               */
              gimp_image_resize (image, context, width, height, -x, -y, NULL);

              x = y = 0;
            }

          gimp_image_crop (image, context, GIMP_FILL_TRANSPARENT,
                           x, y, width, height, TRUE);

          gimp_image_undo_group_end (image);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_autocrop_layer_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  GimpDrawable *drawable;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error))
        {
          GimpLayer *layer = gimp_image_get_active_layer (image);
          gint       x, y, width, height;

          if (layer)
            {
              switch (gimp_pickable_auto_shrink (GIMP_PICKABLE (drawable),
                                                 0, 0,
                                                 gimp_item_get_width  (GIMP_ITEM (drawable)),
                                                 gimp_item_get_height (GIMP_ITEM (drawable)),
                                                 &x, &y, &width, &height))
                {
                case GIMP_AUTO_SHRINK_SHRINK:
                  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE,
                                               _("Autocrop layer"));

                  gimp_item_resize (GIMP_ITEM (layer),
                                    context, GIMP_FILL_TRANSPARENT,
                                    width, height, -x, -y);

                  gimp_image_undo_group_end (image);
                  break;

                default:
                  break;
                }
            }
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_autostretch_hsv_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation",   "gegl:stretch-contrast-hsv",
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Stretch Contrast HSV"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_bump_map_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  GimpDrawable *bumpmap;
  gdouble azimuth;
  gdouble elevation;
  gint32 depth;
  gint32 xofs;
  gint32 yofs;
  gdouble waterlevel;
  gdouble ambient;
  gboolean compensate;
  gboolean invert;
  gint32 type;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  bumpmap = gimp_value_get_drawable (gimp_value_array_index (args, 3), gimp);
  azimuth = g_value_get_double (gimp_value_array_index (args, 4));
  elevation = g_value_get_double (gimp_value_array_index (args, 5));
  depth = g_value_get_int (gimp_value_array_index (args, 6));
  xofs = g_value_get_int (gimp_value_array_index (args, 7));
  yofs = g_value_get_int (gimp_value_array_index (args, 8));
  waterlevel = g_value_get_double (gimp_value_array_index (args, 9));
  ambient = g_value_get_double (gimp_value_array_index (args, 10));
  compensate = g_value_get_boolean (gimp_value_array_index (args, 11));
  invert = g_value_get_boolean (gimp_value_array_index (args, 12));
  type = g_value_get_int (gimp_value_array_index (args, 13));

  if (success)
    {
      success = bump_map (drawable,
                          bumpmap,
                          azimuth,
                          elevation,
                          depth,
                          xofs,
                          yofs,
                          waterlevel,
                          ambient,
                          compensate,
                          invert,
                          type,
                          FALSE,
                          progress,
                          error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_bump_map_tiled_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  GimpDrawable *bumpmap;
  gdouble azimuth;
  gdouble elevation;
  gint32 depth;
  gint32 xofs;
  gint32 yofs;
  gdouble waterlevel;
  gdouble ambient;
  gboolean compensate;
  gboolean invert;
  gint32 type;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  bumpmap = gimp_value_get_drawable (gimp_value_array_index (args, 3), gimp);
  azimuth = g_value_get_double (gimp_value_array_index (args, 4));
  elevation = g_value_get_double (gimp_value_array_index (args, 5));
  depth = g_value_get_int (gimp_value_array_index (args, 6));
  xofs = g_value_get_int (gimp_value_array_index (args, 7));
  yofs = g_value_get_int (gimp_value_array_index (args, 8));
  waterlevel = g_value_get_double (gimp_value_array_index (args, 9));
  ambient = g_value_get_double (gimp_value_array_index (args, 10));
  compensate = g_value_get_boolean (gimp_value_array_index (args, 11));
  invert = g_value_get_boolean (gimp_value_array_index (args, 12));
  type = g_value_get_int (gimp_value_array_index (args, 13));

  if (success)
    {
      success = bump_map (drawable,
                          bumpmap,
                          azimuth,
                          elevation,
                          depth,
                          xofs,
                          yofs,
                          waterlevel,
                          ambient,
                          compensate,
                          invert,
                          type,
                          TRUE,
                          progress,
                          error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_c_astretch_invoker (GimpProcedure         *procedure,
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation",   "gegl:stretch-contrast",
                                 "keep-colors", (gboolean) FALSE,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Stretch Contrast"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_colors_channel_mixer_invoker (GimpProcedure         *procedure,
                                      Gimp                  *gimp,
                                      GimpContext           *context,
                                      GimpProgress          *progress,
                                      const GimpValueArray  *args,
                                      GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 monochrome;
  gdouble rr_gain;
  gdouble rg_gain;
  gdouble rb_gain;
  gdouble gr_gain;
  gdouble gg_gain;
  gdouble gb_gain;
  gdouble br_gain;
  gdouble bg_gain;
  gdouble bb_gain;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  monochrome = g_value_get_int (gimp_value_array_index (args, 3));
  rr_gain = g_value_get_double (gimp_value_array_index (args, 4));
  rg_gain = g_value_get_double (gimp_value_array_index (args, 5));
  rb_gain = g_value_get_double (gimp_value_array_index (args, 6));
  gr_gain = g_value_get_double (gimp_value_array_index (args, 7));
  gg_gain = g_value_get_double (gimp_value_array_index (args, 8));
  gb_gain = g_value_get_double (gimp_value_array_index (args, 9));
  br_gain = g_value_get_double (gimp_value_array_index (args, 10));
  bg_gain = g_value_get_double (gimp_value_array_index (args, 11));
  bb_gain = g_value_get_double (gimp_value_array_index (args, 12));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node = NULL;

          if (monochrome)
            {
              node = gegl_node_new_child (NULL,
                                          "operation", "gegl:mono-mixer",
                                          "red",       rr_gain,
                                          "green",     rg_gain,
                                          "blue",      rb_gain,
                                          NULL);
             }
           else
             {
               node = gegl_node_new_child (NULL,
                                           "operation", "gegl:channel-mixer",
                                           "rr-gain",   rr_gain,
                                           "rg-gain",   rg_gain,
                                           "rb-gain",   rb_gain,
                                           "gr-gain",   gr_gain,
                                           "gg-gain",   gg_gain,
                                           "gb-gain",   gb_gain,
                                           "br-gain",   br_gain,
                                           "bg-gain",   bg_gain,
                                           "bb-gain",   bb_gain,
                                            NULL);
             }

           gimp_drawable_apply_operation (drawable, progress,
                                          C_("undo-type", "Channel Mixer"),
                                          node);
           g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_colortoalpha_invoker (GimpProcedure         *procedure,
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  GimpRGB color;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  gimp_value_get_rgb (gimp_value_array_index (args, 3), &color);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglColor *gegl_color = gimp_gegl_color_new (&color);
          GeglNode  *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:color-to-alpha",
                                 "color",     gegl_color,
                                 NULL);
          g_object_unref (gegl_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Color to Alpha"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_convmatrix_invoker (GimpProcedure         *procedure,
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 argc_matrix;
  const gdouble *matrix;
  gboolean alpha_alg;
  gdouble divisor;
  gdouble offset;
  gint32 argc_channels;
  const gint32 *channels;
  gint32 bmode;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  argc_matrix = g_value_get_int (gimp_value_array_index (args, 3));
  matrix = gimp_value_get_floatarray (gimp_value_array_index (args, 4));
  alpha_alg = g_value_get_boolean (gimp_value_array_index (args, 5));
  divisor = g_value_get_double (gimp_value_array_index (args, 6));
  offset = g_value_get_double (gimp_value_array_index (args, 7));
  argc_channels = g_value_get_int (gimp_value_array_index (args, 8));
  channels = gimp_value_get_int32array (gimp_value_array_index (args, 9));
  bmode = g_value_get_int (gimp_value_array_index (args, 10));

  if (success)
    {
      if (argc_matrix != 25)
        {
          g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
                       _("Array 'matrix' has only %d members, must have 25"),
                       argc_matrix);
          success = FALSE;
        }

      if (success && argc_channels != 5)
        {
          g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
                       _("Array 'channels' has only %d members, must have 5"),
                       argc_channels);
          success = FALSE;
        }

      if (success &&
          gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode        *node;
          GeglAbyssPolicy  border = GEGL_ABYSS_CLAMP;
          gboolean         r      = channels[1];
          gboolean         g      = channels[2];
          gboolean         b      = channels[3];
          gboolean         a      = channels[4];

          if (gimp_drawable_is_gray (drawable))
            {
              r = channels[0];
              g = channels[0];
              b = channels[0];
            }

          switch (bmode)
            {
            case 0: border = GEGL_ABYSS_CLAMP; break;
            case 1: border = GEGL_ABYSS_LOOP; break;
            case 2: border = GEGL_ABYSS_NONE; break;
            }

          node = gegl_node_new_child (NULL,
                                      "operation",    "gegl:convolution-matrix",
                                      "a1",           matrix[0],
                                      "a2",           matrix[1],
                                      "a3",           matrix[2],
                                      "a4",           matrix[3],
                                      "a5",           matrix[4],
                                      "b1",           matrix[5],
                                      "b2",           matrix[6],
                                      "b3",           matrix[7],
                                      "b4",           matrix[8],
                                      "b5",           matrix[9],
                                      "c1",           matrix[10],
                                      "c2",           matrix[11],
                                      "c3",           matrix[12],
                                      "c4",           matrix[13],
                                      "c5",           matrix[14],
                                      "d1",           matrix[15],
                                      "d2",           matrix[16],
                                      "d3",           matrix[17],
                                      "d4",           matrix[18],
                                      "d5",           matrix[19],
                                      "e1",           matrix[20],
                                      "e2",           matrix[21],
                                      "e3",           matrix[22],
                                      "e4",           matrix[23],
                                      "e5",           matrix[24],
                                      "divisor",      divisor,
                                      "offset",       offset,
                                      "red",          r,
                                      "green",        g,
                                      "blue",         b,
                                      "alpha",        a,
                                      "normalize",    FALSE,
                                      "alpha-weight", alpha_alg,
                                      "border",       border,
                                      NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Convolution Matrix"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_cubism_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble tile_size;
  gdouble tile_saturation;
  gint32 bg_color;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  tile_size = g_value_get_double (gimp_value_array_index (args, 3));
  tile_saturation = g_value_get_double (gimp_value_array_index (args, 4));
  bg_color = g_value_get_int (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GimpRGB    color;
          GeglColor *gegl_color;
          GeglNode  *node;

          if (bg_color)
            {
              gimp_context_get_background (context, &color);
              gimp_rgb_set_alpha (&color, 0.0);
            }
          else
            {
              gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0);
            }

          gegl_color = gimp_gegl_color_new (&color);

          node = gegl_node_new_child (NULL,
                                      "operation",       "gegl:cubism",
                                      "tile-size",       tile_size,
                                      "tile-saturation", tile_saturation,
                                      "bg-color",        gegl_color,
                                      NULL);
          g_object_unref (gegl_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Cubism"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_deinterlace_invoker (GimpProcedure         *procedure,
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 evenodd;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  evenodd = g_value_get_int (gimp_value_array_index (args, 3));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:deinterlace",
                                      "keep",        evenodd ? 0 : 1,
                                      "orientation", 0, /* HORIZONTAL */
                                      "size",        1,
                                      NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Deinterlace"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_diffraction_invoker (GimpProcedure         *procedure,
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble lam_r;
  gdouble lam_g;
  gdouble lam_b;
  gdouble contour_r;
  gdouble contour_g;
  gdouble contour_b;
  gdouble edges_r;
  gdouble edges_g;
  gdouble edges_b;
  gdouble brightness;
  gdouble scattering;
  gdouble polarization;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  lam_r = g_value_get_double (gimp_value_array_index (args, 3));
  lam_g = g_value_get_double (gimp_value_array_index (args, 4));
  lam_b = g_value_get_double (gimp_value_array_index (args, 5));
  contour_r = g_value_get_double (gimp_value_array_index (args, 6));
  contour_g = g_value_get_double (gimp_value_array_index (args, 7));
  contour_b = g_value_get_double (gimp_value_array_index (args, 8));
  edges_r = g_value_get_double (gimp_value_array_index (args, 9));
  edges_g = g_value_get_double (gimp_value_array_index (args, 10));
  edges_b = g_value_get_double (gimp_value_array_index (args, 11));
  brightness = g_value_get_double (gimp_value_array_index (args, 12));
  scattering = g_value_get_double (gimp_value_array_index (args, 13));
  polarization = g_value_get_double (gimp_value_array_index (args, 14));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gint      x, y, width, height;

          gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);

          node = gegl_node_new_child (NULL,
                                      "operation",       "gegl:diffraction-patterns",
                                      "red-frequency",   lam_r,
                                      "green-frequency", lam_g,
                                      "blue-frequency",  lam_b,
                                      "red-contours",    contour_r,
                                      "green-contours",  contour_g,
                                      "blue-contours",   contour_b,
                                      "red-sedges",      edges_r,
                                      "green-sedges",    edges_g,
                                      "blue-sedges",     edges_b,
                                      "brightness",      brightness,
                                      "scattering",      scattering,
                                      "polarization",    polarization,
                                      "width",           width,
                                      "height",          height,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Diffraction Patterns"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_displace_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble amount_x;
  gdouble amount_y;
  gboolean do_x;
  gboolean do_y;
  GimpDrawable *displace_map_x;
  GimpDrawable *displace_map_y;
  gint32 displace_type;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  amount_x = g_value_get_double (gimp_value_array_index (args, 3));
  amount_y = g_value_get_double (gimp_value_array_index (args, 4));
  do_x = g_value_get_boolean (gimp_value_array_index (args, 5));
  do_y = g_value_get_boolean (gimp_value_array_index (args, 6));
  displace_map_x = gimp_value_get_drawable (gimp_value_array_index (args, 7), gimp);
  displace_map_y = gimp_value_get_drawable (gimp_value_array_index (args, 8), gimp);
  displace_type = g_value_get_int (gimp_value_array_index (args, 9));

  if (success)
    {
      success = displace (drawable,
                          amount_x,
                          amount_y,
                          do_x,
                          do_y,
                          displace_map_x,
                          displace_map_y,
                          displace_type,
                          0,
                          progress,
                          error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_displace_polar_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble amount_x;
  gdouble amount_y;
  gboolean do_x;
  gboolean do_y;
  GimpDrawable *displace_map_x;
  GimpDrawable *displace_map_y;
  gint32 displace_type;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  amount_x = g_value_get_double (gimp_value_array_index (args, 3));
  amount_y = g_value_get_double (gimp_value_array_index (args, 4));
  do_x = g_value_get_boolean (gimp_value_array_index (args, 5));
  do_y = g_value_get_boolean (gimp_value_array_index (args, 6));
  displace_map_x = gimp_value_get_drawable (gimp_value_array_index (args, 7), gimp);
  displace_map_y = gimp_value_get_drawable (gimp_value_array_index (args, 8), gimp);
  displace_type = g_value_get_int (gimp_value_array_index (args, 9));

  if (success)
    {
      success = displace (drawable,
                          amount_x,
                          amount_y,
                          do_x,
                          do_y,
                          displace_map_x,
                          displace_map_y,
                          displace_type,
                          1,
                          progress,
                          error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_edge_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble amount;
  gint32 warpmode;
  gint32 edgemode;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  amount = g_value_get_double (gimp_value_array_index (args, 3));
  warpmode = g_value_get_int (gimp_value_array_index (args, 4));
  edgemode = g_value_get_int (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode        *node;
          GeglAbyssPolicy  border_behavior = GEGL_ABYSS_NONE;

          switch (warpmode)
            {
            case 0:
              border_behavior = GEGL_ABYSS_NONE;
              break;

            case 1:
              border_behavior = GEGL_ABYSS_LOOP;
              break;

            case 2:
              border_behavior = GEGL_ABYSS_CLAMP;
              break;

            case 3:
              border_behavior = GEGL_ABYSS_BLACK;
              break;
            }

          node = gegl_node_new_child (NULL,
                                      "operation",       "gegl:edge",
                                      "algorithm",       edgemode,
                                      "amount",          amount,
                                      "border-behavior", border_behavior,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Edge"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_engrave_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 height;
  gboolean limit;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  height = g_value_get_int (gimp_value_array_index (args, 3));
  limit = g_value_get_boolean (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:engrave",
                                      "row-height",  height,
                                      "limit",       limit,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Engrave"),
                                         node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_exchange_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  guint8 from_red;
  guint8 from_green;
  guint8 from_blue;
  guint8 to_red;
  guint8 to_green;
  guint8 to_blue;
  guint8 red_threshold;
  guint8 green_threshold;
  guint8 blue_threshold;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  from_red = g_value_get_uint (gimp_value_array_index (args, 3));
  from_green = g_value_get_uint (gimp_value_array_index (args, 4));
  from_blue = g_value_get_uint (gimp_value_array_index (args, 5));
  to_red = g_value_get_uint (gimp_value_array_index (args, 6));
  to_green = g_value_get_uint (gimp_value_array_index (args, 7));
  to_blue = g_value_get_uint (gimp_value_array_index (args, 8));
  red_threshold = g_value_get_uint (gimp_value_array_index (args, 9));
  green_threshold = g_value_get_uint (gimp_value_array_index (args, 10));
  blue_threshold = g_value_get_uint (gimp_value_array_index (args, 11));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GimpRGB    from;
          GimpRGB    to;
          GeglColor *gegl_from;
          GeglColor *gegl_to;
          GeglNode  *node;

          gimp_rgb_set_uchar (&from, from_red, from_green, from_blue);
          gimp_rgb_set_uchar (&to,   to_red,   to_green,   to_blue);

          gegl_from = gimp_gegl_color_new (&from);
          gegl_to   = gimp_gegl_color_new (&to);

          node = gegl_node_new_child (NULL,
                                      "operation",       "gegl:color-exchange",
                                      "from-color",      gegl_from,
                                      "to-color",        gegl_to,
                                      "red-threshold",   red_threshold   / 255.0,
                                      "green-threshold", green_threshold / 255.0,
                                      "blue-threshold",  blue_threshold  / 255.0,
                                      NULL);

          g_object_unref (gegl_from);
          g_object_unref (gegl_to);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Color Exchange"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_flarefx_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 pos_x;
  gint32 pos_y;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  pos_x = g_value_get_int (gimp_value_array_index (args, 3));
  pos_y = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gint      width  = gimp_item_get_width  (GIMP_ITEM (drawable));
          gint      height = gimp_item_get_height (GIMP_ITEM (drawable));
          gdouble   x      = (gdouble) pos_x / (gdouble) width;
          gdouble   y      = (gdouble) pos_y / (gdouble) height;

          node = gegl_node_new_child (NULL,
                                      "operation", "gegl:lens-flare",
                                      "pos-x",     x,
                                      "pos-y",     y,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Lens Flare"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_gauss_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble horizontal;
  gdouble vertical;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  horizontal = g_value_get_double (gimp_value_array_index (args, 3));
  vertical = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      success = gaussian_blur (drawable, horizontal, vertical, progress, error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_gauss_iir_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble radius;
  gboolean horizontal;
  gboolean vertical;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  radius = g_value_get_double (gimp_value_array_index (args, 3));
  horizontal = g_value_get_boolean (gimp_value_array_index (args, 4));
  vertical = g_value_get_boolean (gimp_value_array_index (args, 5));

  if (success)
    {
      success = gaussian_blur (drawable,
                               horizontal ? radius : 0.0,
                               vertical   ? radius : 0.0,
                               progress, error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_gauss_iir2_invoker (GimpProcedure         *procedure,
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble horizontal;
  gdouble vertical;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  horizontal = g_value_get_double (gimp_value_array_index (args, 3));
  vertical = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      success = gaussian_blur (drawable, horizontal, vertical, progress, error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_gauss_rle_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble radius;
  gboolean horizontal;
  gboolean vertical;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  radius = g_value_get_double (gimp_value_array_index (args, 3));
  horizontal = g_value_get_boolean (gimp_value_array_index (args, 4));
  vertical = g_value_get_boolean (gimp_value_array_index (args, 5));

  if (success)
    {
      success = gaussian_blur (drawable,
                               horizontal ? radius : 0.0,
                               vertical   ? radius : 0.0,
                               progress, error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_gauss_rle2_invoker (GimpProcedure         *procedure,
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble horizontal;
  gdouble vertical;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  horizontal = g_value_get_double (gimp_value_array_index (args, 3));
  vertical = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      success = gaussian_blur (drawable, horizontal, vertical, progress, error);
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_glasstile_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 tilex;
  gint32 tiley;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  tilex = g_value_get_int (gimp_value_array_index (args, 3));
  tiley = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:tile-glass",
                                      "tile-width",  tilex,
                                      "tile-height", tiley,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Glass Tile"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_hsv_noise_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 holdness;
  gint32 hue_distance;
  gint32 saturation_distance;
  gint32 value_distance;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  holdness = g_value_get_int (gimp_value_array_index (args, 3));
  hue_distance = g_value_get_int (gimp_value_array_index (args, 4));
  saturation_distance = g_value_get_int (gimp_value_array_index (args, 5));
  value_distance = g_value_get_int (gimp_value_array_index (args, 6));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node;

          gdouble saturation = saturation_distance / 255.0;
          gdouble value = value_distance / 255.0;

          node = gegl_node_new_child (NULL,
                                      "operation",           "gegl:noise-hsv",
                                      "holdness",            (gint)    holdness,
                                      "hue-distance",        (gdouble) hue_distance,
                                      "saturation-distance", (gdouble) saturation,
                                      "value-distance",      (gdouble) value,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Noise HSV"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_icc_profile_info_invoker (GimpProcedure         *procedure,
                                  Gimp                  *gimp,
                                  GimpContext           *context,
                                  GimpProgress          *progress,
                                  const GimpValueArray  *args,
                                  GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpImage *image;
  gchar *profile_name = NULL;
  gchar *profile_desc = NULL;
  gchar *profile_info = NULL;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);

  if (success)
    {
      GimpColorProfile *profile;

      profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image));

      if (profile)
        {
          profile_name = g_strdup (gimp_color_profile_get_model (profile));
          profile_desc = g_strdup (gimp_color_profile_get_description (profile));
          profile_info = g_strdup (gimp_color_profile_get_summary (profile));
        }
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      g_value_take_string (gimp_value_array_index (return_vals, 1), profile_name);
      g_value_take_string (gimp_value_array_index (return_vals, 2), profile_desc);
      g_value_take_string (gimp_value_array_index (return_vals, 3), profile_info);
    }

  return return_vals;
}

static GimpValueArray *
plug_in_icc_profile_file_info_invoker (GimpProcedure         *procedure,
                                       Gimp                  *gimp,
                                       GimpContext           *context,
                                       GimpProgress          *progress,
                                       const GimpValueArray  *args,
                                       GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *profile;
  gchar *profile_name = NULL;
  gchar *profile_desc = NULL;
  gchar *profile_info = NULL;

  profile = g_value_get_string (gimp_value_array_index (args, 0));

  if (success)
    {
      GFile *file = g_file_new_for_path (profile);

      if (file)
        {
          GimpColorProfile *p;

          p = gimp_color_profile_new_from_file (file, error);
          g_object_unref (file);

          if (p)
            {
              profile_name = g_strdup (gimp_color_profile_get_model (p));
              profile_desc = g_strdup (gimp_color_profile_get_description (p));
              profile_info = g_strdup (gimp_color_profile_get_summary (p));

              g_object_unref (p);
            }
          else
            success = FALSE;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      g_value_take_string (gimp_value_array_index (return_vals, 1), profile_name);
      g_value_take_string (gimp_value_array_index (return_vals, 2), profile_desc);
      g_value_take_string (gimp_value_array_index (return_vals, 3), profile_info);
    }

  return return_vals;
}

static GimpValueArray *
plug_in_icc_profile_apply_invoker (GimpProcedure         *procedure,
                                   Gimp                  *gimp,
                                   GimpContext           *context,
                                   GimpProgress          *progress,
                                   const GimpValueArray  *args,
                                   GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  const gchar *profile;
  gint32 intent;
  gboolean bpc;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  profile = g_value_get_string (gimp_value_array_index (args, 2));
  intent = g_value_get_enum (gimp_value_array_index (args, 3));
  bpc = g_value_get_boolean (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error))
        {
          GimpColorProfile *p = NULL;

          if (profile)
            {
              GFile *file = g_file_new_for_path (profile);

              if (file)
                {
                  p = gimp_color_profile_new_from_file (file, error);

                  if (! p)
                    success = FALSE;

                  g_object_unref (file);
                }
              else
                {
                  success = FALSE;
                }
            }
          else if (image->gimp->config->color_management->rgb_profile)
            {
              p = gimp_color_config_get_rgb_color_profile (image->gimp->config->color_management,
                                                           error);

              if (! p)
                success = FALSE;
            }

          if (success)
            {
              if (! p)
                p = gimp_image_get_builtin_color_profile (image);

              success = gimp_image_convert_color_profile (image, p, intent, bpc,
                                                          progress, error);
            }
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_icc_profile_apply_rgb_invoker (GimpProcedure         *procedure,
                                       Gimp                  *gimp,
                                       GimpContext           *context,
                                       GimpProgress          *progress,
                                       const GimpValueArray  *args,
                                       GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  gint32 intent;
  gboolean bpc;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  intent = g_value_get_enum (gimp_value_array_index (args, 2));
  bpc = g_value_get_boolean (gimp_value_array_index (args, 3));

  if (success)
    {
      if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error))
        {
          GimpColorProfile *p = NULL;

          if (image->gimp->config->color_management->rgb_profile)
            {
              p = gimp_color_config_get_rgb_color_profile (image->gimp->config->color_management,
                                                           error);

              if (! p)
                success = FALSE;
            }

          if (success)
            {
              if (! p)
                p = gimp_image_get_builtin_color_profile (image);

              success = gimp_image_convert_color_profile (image, p, intent, bpc,
                                                          progress, error);
            }
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_icc_profile_set_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  const gchar *profile;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  profile = g_value_get_string (gimp_value_array_index (args, 2));

  if (success)
    {
      if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error))
        {
          GimpColorProfile *p = NULL;

          if (profile)
            {
              GFile *file = g_file_new_for_path (profile);

              if (file)
                {
                  p = gimp_color_profile_new_from_file (file, error);

                  if (! p)
                    success = FALSE;

                  g_object_unref (file);
                }
              else
                success = FALSE;
            }
          else if (image->gimp->config->color_management->rgb_profile)
            {
              p = gimp_color_config_get_rgb_color_profile (image->gimp->config->color_management,
                                                           error);

              if (! p)
                success = FALSE;
            }

          if (success)
            {
              gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_MISC,
                                           _("Set color profile"));

              if (gimp_image_set_color_profile (image, p, error))
                gimp_image_parasite_detach (image, "icc-profile-name", TRUE);
              else
                success = FALSE;

              gimp_image_undo_group_end (image);

              if (! success)
                gimp_image_undo (image);

              if (p)
                g_object_unref (p);
            }
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_icc_profile_set_rgb_invoker (GimpProcedure         *procedure,
                                     Gimp                  *gimp,
                                     GimpContext           *context,
                                     GimpProgress          *progress,
                                     const GimpValueArray  *args,
                                     GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);

  if (success)
    {
      if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error))
        {
          GimpColorProfile *p = NULL;

          if (image->gimp->config->color_management->rgb_profile)
            {
              p = gimp_color_config_get_rgb_color_profile (image->gimp->config->color_management,
                                                           error);

              if (! p)
                success = FALSE;
            }

          if (success)
            {
              gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_MISC,
                                           _("Set color profile"));

              if (gimp_image_set_color_profile (image, p, error))
                gimp_image_parasite_detach (image, "icc-profile-name", TRUE);
              else
                success = FALSE;

              gimp_image_undo_group_end (image);

              if (! success)
                gimp_image_undo (image);

              if (p)
                g_object_unref (p);
            }
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_illusion_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 division;
  gint32 type;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  division = g_value_get_int (gimp_value_array_index (args, 3));
  type = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation",     "gegl:illusion",
                                 "division",      (gint) division,
                                 "illusion-type", (gint) type,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Illusion"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_laplace_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:edge-laplace",
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Laplace"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_lens_distortion_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble offset_x;
  gdouble offset_y;
  gdouble main_adjust;
  gdouble edge_adjust;
  gdouble rescale;
  gdouble brighten;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  offset_x = g_value_get_double (gimp_value_array_index (args, 3));
  offset_y = g_value_get_double (gimp_value_array_index (args, 4));
  main_adjust = g_value_get_double (gimp_value_array_index (args, 5));
  edge_adjust = g_value_get_double (gimp_value_array_index (args, 6));
  rescale = g_value_get_double (gimp_value_array_index (args, 7));
  brighten = g_value_get_double (gimp_value_array_index (args, 8));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node = NULL;
          GimpRGB    color;
          GeglColor *gegl_color;

          gimp_context_get_background (context, &color);

          if (gimp_drawable_has_alpha (drawable))
            {
              gimp_rgb_set_alpha (&color, 0.0);
            }
          else
            {
              gimp_rgb_set_alpha (&color, 1.0);
            }

          gegl_color = gimp_gegl_color_new (&color);

          node =  gegl_node_new_child (NULL,
                                       "operation", "gegl:lens-distortion",
                                       "main",       (gdouble) main_adjust,
                                       "edge",       (gdouble) edge_adjust,
                                       "zoom",       (gdouble) rescale,
                                       "x-shift",    (gdouble) offset_x,
                                       "y-shift",    (gdouble) offset_y,
                                       "brighten",   (gdouble) brighten,
                                       "background", gegl_color,
                                       NULL);

          g_object_unref (gegl_color);

          node = wrap_in_selection_bounds (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                        C_("undo-type", "Lens Distortion"),
                                        node);
          g_object_unref (node);

        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_make_seamless_invoker (GimpProcedure         *procedure,
                               Gimp                  *gimp,
                               GimpContext           *context,
                               GimpProgress          *progress,
                               const GimpValueArray  *args,
                               GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:tile-seamless",
                                 NULL);

          node = wrap_in_selection_bounds (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Tile Seamless"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_maze_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint16 width;
  gint16 height;
  guint8 tileable;
  guint8 algorithm;
  gint32 seed;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  width = g_value_get_int (gimp_value_array_index (args, 3));
  height = g_value_get_int (gimp_value_array_index (args, 4));
  tileable = g_value_get_uint (gimp_value_array_index (args, 5));
  algorithm = g_value_get_uint (gimp_value_array_index (args, 6));
  seed = g_value_get_int (gimp_value_array_index (args, 7));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node;
          GeglColor *fg_color;
          GeglColor *bg_color;
          GimpRGB    color;

          gimp_context_get_foreground (context, &color);
          fg_color = gimp_gegl_color_new (&color);

          gimp_context_get_background (context, &color);
          bg_color = gimp_gegl_color_new (&color);

          node =  gegl_node_new_child (NULL,
                                       "operation",      "gegl:maze",
                                       "x",              width,
                                       "y",              height,
                                       "algorithm-type", algorithm,
                                       "tileable",       tileable,
                                       "seed",           seed,
                                       "fg-color",       fg_color,
                                       "bg-color",       bg_color,
                                       NULL);

          g_object_unref (fg_color);
          g_object_unref (bg_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Maze"),
                                        node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_mblur_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 type;
  gdouble length;
  gdouble angle;
  gdouble center_x;
  gdouble center_y;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  type = g_value_get_int (gimp_value_array_index (args, 3));
  length = g_value_get_double (gimp_value_array_index (args, 4));
  angle = g_value_get_double (gimp_value_array_index (args, 5));
  center_x = g_value_get_double (gimp_value_array_index (args, 6));
  center_y = g_value_get_double (gimp_value_array_index (args, 7));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node   = NULL;
          gint      width  = gimp_item_get_width  (GIMP_ITEM (drawable));
          gint      height = gimp_item_get_height (GIMP_ITEM (drawable));

          center_x /= (gdouble) width;
          center_y /= (gdouble) height;

          if (angle > 180.0)
            angle -= 360.0;

          if (type == 0)
            {
              node =  gegl_node_new_child (NULL,
                                           "operation", "gegl:motion-blur-linear",
                                           "length",    length,
                                           "angle",     angle,
                                            NULL);
            }
          else if (type == 1)
            {
              node =  gegl_node_new_child (NULL,
                                           "operation", "gegl:motion-blur-circular",
                                           "center-x",  center_x,
                                           "center-y",  center_y,
                                           "angle",     angle,
                                            NULL);
            }
          else if (type == 2)
            {
              gdouble factor = CLAMP (length / 256.0, 0.0, 1.0);

              node =  gegl_node_new_child (NULL,
                                           "operation", "gegl:motion-blur-zoom",
                                           "center-x",  center_x,
                                           "center-y",  center_y,
                                           "factor",    factor,
                                            NULL);
            }

          if (node != NULL)
            {
              gimp_drawable_apply_operation (drawable, progress,
                                             C_("undo-type", "Motion Blur"),
                                             node);
              g_object_unref (node);
            }
          else
            success = FALSE;

        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_mblur_inward_invoker (GimpProcedure         *procedure,
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 type;
  gdouble length;
  gdouble angle;
  gdouble center_x;
  gdouble center_y;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  type = g_value_get_int (gimp_value_array_index (args, 3));
  length = g_value_get_double (gimp_value_array_index (args, 4));
  angle = g_value_get_double (gimp_value_array_index (args, 5));
  center_x = g_value_get_double (gimp_value_array_index (args, 6));
  center_y = g_value_get_double (gimp_value_array_index (args, 7));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node   = NULL;
          gint      width  = gimp_item_get_width  (GIMP_ITEM (drawable));
          gint      height = gimp_item_get_height (GIMP_ITEM (drawable));

          center_x /= (gdouble) width;
          center_y /= (gdouble) height;

          if (type == 0)
            {
              node =  gegl_node_new_child (NULL,
                                           "operation", "gegl:motion-blur-linear",
                                           "length",    length,
                                           "angle",     angle,
                                            NULL);
            }
          else if (type == 1)
            {
              node =  gegl_node_new_child (NULL,
                                           "operation", "gegl:motion-blur-circular",
                                           "center-x",  center_x,
                                           "center-y",  center_y,
                                           "angle",     angle,
                                            NULL);
            }
          else if (type == 2)
            {
              gdouble factor = CLAMP (-length / (256.0 - length), -10.0, 0.0);

              node =  gegl_node_new_child (NULL,
                                           "operation", "gegl:motion-blur-zoom",
                                           "center-x",  center_x,
                                           "center-y",  center_y,
                                           "factor",    factor,
                                            NULL);
            }

          if (node != NULL)
            {
              gimp_drawable_apply_operation (drawable, progress,
                                             C_("undo-type", "Motion Blur"),
                                             node);
              g_object_unref (node);
            }
          else
            success = FALSE;

        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_median_blur_invoker (GimpProcedure         *procedure,
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 radius;
  gdouble percentile;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  radius = g_value_get_int (gimp_value_array_index (args, 3));
  percentile = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:median-blur",
                                 "radius",     radius,
                                 "percentile", percentile,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Median Blur"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_mosaic_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble tile_size;
  gdouble tile_height;
  gdouble tile_spacing;
  gdouble tile_neatness;
  gint32 tile_allow_split;
  gdouble light_dir;
  gdouble color_variation;
  gint32 antialiasing;
  gint32 color_averaging;
  gint32 tile_type;
  gint32 tile_surface;
  gint32 grout_color;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  tile_size = g_value_get_double (gimp_value_array_index (args, 3));
  tile_height = g_value_get_double (gimp_value_array_index (args, 4));
  tile_spacing = g_value_get_double (gimp_value_array_index (args, 5));
  tile_neatness = g_value_get_double (gimp_value_array_index (args, 6));
  tile_allow_split = g_value_get_int (gimp_value_array_index (args, 7));
  light_dir = g_value_get_double (gimp_value_array_index (args, 8));
  color_variation = g_value_get_double (gimp_value_array_index (args, 9));
  antialiasing = g_value_get_int (gimp_value_array_index (args, 10));
  color_averaging = g_value_get_int (gimp_value_array_index (args, 11));
  tile_type = g_value_get_int (gimp_value_array_index (args, 12));
  tile_surface = g_value_get_int (gimp_value_array_index (args, 13));
  grout_color = g_value_get_int (gimp_value_array_index (args, 14));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglColor *fg_color;
          GeglColor *bg_color;
          GeglNode  *node;

          if (grout_color)
            {
              GimpRGB fgcolor, bgcolor;

              gimp_context_get_background (context, &bgcolor);
              bg_color = gimp_gegl_color_new (&bgcolor);

              gimp_context_get_foreground (context, &fgcolor);
              fg_color = gimp_gegl_color_new (&fgcolor);
            }
          else
            {
              /* sic */
              fg_color = gegl_color_new ("white");
              bg_color = gegl_color_new ("black");
            }

          node = gegl_node_new_child (NULL,
                     "operation",        "gegl:mosaic",
                     "tile-size",        (gdouble)  tile_size,
                     "tile-height",      (gdouble)  tile_height,
                     "tile-spacing",     (gdouble)  tile_spacing,
                     "tile-neatness",    (gdouble)  tile_neatness,
                     "tile-allow-split", (gboolean) tile_allow_split,
                     "light-dir",        (gdouble)  light_dir,
                     "color-variation",  (gfloat)   color_variation,
                     "antialiasing",     (gboolean) antialiasing,
                     "color-averaging",  (gboolean) color_averaging,
                     "tile-type",        (gint)     tile_type,
                     "tile-surface",     (gboolean) tile_surface,
                     "light-color",      fg_color,
                     "joints-color",     bg_color,
                     NULL);

          g_object_unref (fg_color);
          g_object_unref (bg_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Mosaic"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_neon_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble radius;
  gdouble amount;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  radius = g_value_get_double (gimp_value_array_index (args, 3));
  amount = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation", "gegl:edge-neon",
                                      "radius",    radius,
                                      "amount",    amount,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Neon"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_newsprint_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 cell_width;
  gint32 colorspace;
  gint32 k_pullout;
  gdouble gry_ang;
  gint32 gry_spotfn;
  gdouble red_ang;
  gint32 red_spotfn;
  gdouble grn_ang;
  gint32 grn_spotfn;
  gdouble blu_ang;
  gint32 blu_spotfn;
  gint32 oversample;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  cell_width = g_value_get_int (gimp_value_array_index (args, 3));
  colorspace = g_value_get_int (gimp_value_array_index (args, 4));
  k_pullout = g_value_get_int (gimp_value_array_index (args, 5));
  gry_ang = g_value_get_double (gimp_value_array_index (args, 6));
  gry_spotfn = g_value_get_int (gimp_value_array_index (args, 7));
  red_ang = g_value_get_double (gimp_value_array_index (args, 8));
  red_spotfn = g_value_get_int (gimp_value_array_index (args, 9));
  grn_ang = g_value_get_double (gimp_value_array_index (args, 10));
  grn_spotfn = g_value_get_int (gimp_value_array_index (args, 11));
  blu_ang = g_value_get_double (gimp_value_array_index (args, 12));
  blu_spotfn = g_value_get_int (gimp_value_array_index (args, 13));
  oversample = g_value_get_int (gimp_value_array_index (args, 14));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gint      color_model = newsprint_color_model (colorspace);
          gint      pattern     = newsprint_pattern (gry_spotfn);
          gint      pattern2    = newsprint_pattern (red_spotfn);
          gint      pattern3    = newsprint_pattern (grn_spotfn);
          gint      pattern4    = newsprint_pattern (blu_spotfn);
          gdouble   angle       = newsprint_angle (gry_ang);
          gdouble   angle2      = newsprint_angle (red_ang);
          gdouble   angle3      = newsprint_angle (grn_ang);
          gdouble   angle4      = newsprint_angle (blu_ang);

          node = gegl_node_new_child (NULL,
                                      "operation",     "gegl:newsprint",
                                      "color-model",   color_model,
                                      "black-pullout", (gdouble) k_pullout / 100.0,
                                      "period",        (gdouble) cell_width,
                                      "angle",         angle,
                                      "pattern",       pattern,
                                      "period2",       (gdouble) cell_width,
                                      "angle2",        angle2,
                                      "pattern2",      pattern2,
                                      "period3",       (gdouble) cell_width,
                                      "angle3",        angle3,
                                      "pattern3",      pattern3,
                                      "period4",       (gdouble) cell_width,
                                      "angle4",        angle4,
                                      "pattern4",      pattern4,
                                      "aa-samples",    oversample,
                                      NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Newsprint"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_normalize_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:stretch-contrast",
                                      "keep-colors", TRUE,
                                      "perceptual",  TRUE,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Normalize"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_nova_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 xcenter;
  gint32 ycenter;
  GimpRGB color;
  gint32 radius;
  gint32 nspoke;
  gint32 randomhue;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  xcenter = g_value_get_int (gimp_value_array_index (args, 3));
  ycenter = g_value_get_int (gimp_value_array_index (args, 4));
  gimp_value_get_rgb (gimp_value_array_index (args, 5), &color);
  radius = g_value_get_int (gimp_value_array_index (args, 6));
  nspoke = g_value_get_int (gimp_value_array_index (args, 7));
  randomhue = g_value_get_int (gimp_value_array_index (args, 8));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node;
          GeglColor *gegl_color = gimp_gegl_color_new (&color);
          gdouble    center_x   = (gdouble) xcenter / (gdouble) gimp_item_get_width (GIMP_ITEM (drawable));
          gdouble    center_y   = (gdouble) ycenter / (gdouble) gimp_item_get_height (GIMP_ITEM (drawable));

          node = gegl_node_new_child (NULL,
                                      "operation",    "gegl:supernova",
                                      "center-x",     center_x,
                                      "center-y",     center_y,
                                      "radius",       radius,
                                      "spokes-count", nspoke,
                                      "random-hue",   randomhue,
                                      "color",        gegl_color,
                                      "seed",         g_random_int (),
                                      NULL);

          g_object_unref (gegl_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Supernova"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_oilify_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 mask_size;
  gint32 mode;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  mask_size = g_value_get_int (gimp_value_array_index (args, 3));
  mode = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",       "gegl:oilify",
                                      "mask-radius",     MAX (1, mask_size / 2),
                                      "use-inten",       mode ? TRUE : FALSE,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Oilify"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_oilify_enhanced_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 mode;
  gint32 mask_size;
  GimpDrawable *mask_size_map;
  gint32 exponent;
  GimpDrawable *exponent_map;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  mode = g_value_get_int (gimp_value_array_index (args, 3));
  mask_size = g_value_get_int (gimp_value_array_index (args, 4));
  mask_size_map = gimp_value_get_drawable (gimp_value_array_index (args, 5), gimp);
  exponent = g_value_get_int (gimp_value_array_index (args, 6));
  exponent_map = gimp_value_get_drawable (gimp_value_array_index (args, 7), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *graph;
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:oilify",
                                      "mask-radius", MAX (1, mask_size / 2),
                                      "use-inten",   mode ? TRUE : FALSE,
                                      "exponent",    exponent,
                                      NULL);

          graph = wrap_in_graph (node);

          if (mask_size_map)
            {
              GeglNode *src_node;
              src_node = create_buffer_source_node (graph, mask_size_map);
              gegl_node_connect_to (src_node, "output", node, "aux");
            }

          if (exponent_map)
            {
              GeglNode *src_node;
              src_node = create_buffer_source_node (graph, exponent_map);
              gegl_node_connect_to (src_node, "output", node, "aux2");
            }

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Oilify"),
                                         graph);
          g_object_unref (graph);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_papertile_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 tile_size;
  gdouble move_max;
  gint32 fractional_type;
  gboolean wrap_around;
  gboolean centering;
  gint32 background_type;
  GimpRGB background_color;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  tile_size = g_value_get_int (gimp_value_array_index (args, 3));
  move_max = g_value_get_double (gimp_value_array_index (args, 4));
  fractional_type = g_value_get_int (gimp_value_array_index (args, 5));
  wrap_around = g_value_get_boolean (gimp_value_array_index (args, 6));
  centering = g_value_get_boolean (gimp_value_array_index (args, 7));
  background_type = g_value_get_int (gimp_value_array_index (args, 8));
  gimp_value_get_rgb (gimp_value_array_index (args, 9), &background_color);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node;
          GimpRGB    color;
          GeglColor *gegl_color;
          gint       bg_type;

          switch (background_type)
            {
            default:
              bg_type = background_type;
              gimp_rgba_set (&color, 0.0, 0.0, 1.0, 1.0);
              break;

            case 3:
              bg_type = 3;
              gimp_context_get_foreground (context, &color);
              break;

            case 4:
              bg_type = 3;
              gimp_context_get_background (context, &color);
              break;

            case 5:
              bg_type = 3;
              color = background_color;
              break;
            }

          gegl_color = gimp_gegl_color_new (&color);

          node = gegl_node_new_child (NULL,
                                      "operation",       "gegl:tile-paper",
                                      "tile-width",      tile_size,
                                      "tile-height",     tile_size,
                                      "move-rate",       move_max,
                                      "bg-color",        gegl_color,
                                      "centering",       centering,
                                      "wrap-around",     wrap_around,
                                      "background-type", bg_type,
                                      "fractional-type", fractional_type,
                                      NULL);

          g_object_unref (gegl_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Paper Tile"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_pixelize_invoker (GimpProcedure         *procedure,
                          Gimp                  *gimp,
                          GimpContext           *context,
                          GimpProgress          *progress,
                          const GimpValueArray  *args,
                          GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 pixel_width;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  pixel_width = g_value_get_int (gimp_value_array_index (args, 3));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:pixelize",
                                 "size-x",    pixel_width,
                                 "size-y",    pixel_width,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Pixelize"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_pixelize2_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 pixel_width;
  gint32 pixel_height;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  pixel_width = g_value_get_int (gimp_value_array_index (args, 3));
  pixel_height = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:pixelize",
                                 "size-x",    pixel_width,
                                 "size-y",    pixel_height,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Pixelize"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_plasma_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 seed;
  gdouble turbulence;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  seed = g_value_get_int (gimp_value_array_index (args, 3));
  turbulence = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gint      x, y, width, height;

          gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);

          node = gegl_node_new_child (NULL,
                                      "operation",  "gegl:plasma",
                                      "seed",       seed,
                                      "turbulence", turbulence,
                                      "x",          x,
                                      "y",          y,
                                      "width",      width,
                                      "height",     height,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Plasma"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_polar_coords_invoker (GimpProcedure         *procedure,
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble circle;
  gdouble angle;
  gboolean backwards;
  gboolean inverse;
  gboolean polrec;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  circle = g_value_get_double (gimp_value_array_index (args, 3));
  angle = g_value_get_double (gimp_value_array_index (args, 4));
  backwards = g_value_get_boolean (gimp_value_array_index (args, 5));
  inverse = g_value_get_boolean (gimp_value_array_index (args, 6));
  polrec = g_value_get_boolean (gimp_value_array_index (args, 7));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:polar-coordinates",
                                 "depth",     circle,
                                 "angle",     angle,
                                 "bw",        backwards, /* XXX name */
                                 "top",       inverse,
                                 "polar",     polrec,
                                 NULL);

          node = wrap_in_selection_bounds (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Polar Coordinates"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_red_eye_removal_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 threshold;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  threshold = g_value_get_int (gimp_value_array_index (args, 3));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:red-eye-removal",
                                 "threshold", (gdouble) (threshold - 50) / 50.0 * 0.2 + 0.4,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Red Eye Removal"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_randomize_hurl_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble rndm_pct;
  gdouble rndm_rcount;
  gboolean randomize;
  gint32 seed;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  rndm_pct = g_value_get_double (gimp_value_array_index (args, 3));
  rndm_rcount = g_value_get_double (gimp_value_array_index (args, 4));
  randomize = g_value_get_boolean (gimp_value_array_index (args, 5));
  seed = g_value_get_int (gimp_value_array_index (args, 6));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          if (randomize)
            seed = (gint32) g_random_int ();

          node =
            gegl_node_new_child (NULL,
                                 "operation",  "gegl:noise-hurl",
                                 "seed",       seed,
                                 "pct-random", rndm_pct,
                                 "repeat",     (gint) rndm_rcount,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Random Hurl"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_randomize_pick_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble rndm_pct;
  gdouble rndm_rcount;
  gboolean randomize;
  gint32 seed;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  rndm_pct = g_value_get_double (gimp_value_array_index (args, 3));
  rndm_rcount = g_value_get_double (gimp_value_array_index (args, 4));
  randomize = g_value_get_boolean (gimp_value_array_index (args, 5));
  seed = g_value_get_int (gimp_value_array_index (args, 6));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          if (randomize)
            seed = (gint32) g_random_int ();

          node =
            gegl_node_new_child (NULL,
                                 "operation",  "gegl:noise-pick",
                                 "seed",       seed,
                                 "pct-random", rndm_pct,
                                 "repeat",     (gint) rndm_rcount,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Random Pick"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_randomize_slur_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
                                GimpContext           *context,
                                GimpProgress          *progress,
                                const GimpValueArray  *args,
                                GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble rndm_pct;
  gdouble rndm_rcount;
  gboolean randomize;
  gint32 seed;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  rndm_pct = g_value_get_double (gimp_value_array_index (args, 3));
  rndm_rcount = g_value_get_double (gimp_value_array_index (args, 4));
  randomize = g_value_get_boolean (gimp_value_array_index (args, 5));
  seed = g_value_get_int (gimp_value_array_index (args, 6));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          if (randomize)
            seed = (gint32) g_random_int ();

          node =
            gegl_node_new_child (NULL,
                                 "operation",  "gegl:noise-slur",
                                 "seed",       seed,
                                 "pct-random", rndm_pct,
                                 "repeat",     (gint) rndm_rcount,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Random Slur"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_rgb_noise_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gboolean independent;
  gboolean correlated;
  gdouble noise_1;
  gdouble noise_2;
  gdouble noise_3;
  gdouble noise_4;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  independent = g_value_get_boolean (gimp_value_array_index (args, 3));
  correlated = g_value_get_boolean (gimp_value_array_index (args, 4));
  noise_1 = g_value_get_double (gimp_value_array_index (args, 5));
  noise_2 = g_value_get_double (gimp_value_array_index (args, 6));
  noise_3 = g_value_get_double (gimp_value_array_index (args, 7));
  noise_4 = g_value_get_double (gimp_value_array_index (args, 8));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gdouble   r, g, b, a;

          if (gimp_drawable_is_gray (drawable))
            {
              r = noise_1;
              g = noise_1;
              b = noise_1;
              a = noise_2;
            }
          else
            {
              r = noise_1;
              g = noise_2;
              b = noise_3;
              a = noise_4;
            }

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:noise-rgb",
                                      "correlated",  correlated,
                                      "independent", independent,
                                      "red",         r,
                                      "green",       g,
                                      "blue",        b,
                                      "alpha",       a,
                                      "seed",        g_random_int (),
                                      NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "RGB Noise"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_ripple_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 period;
  gint32 amplitude;
  gint32 orientation;
  gint32 edges;
  gint32 waveform;
  gboolean antialias;
  gboolean tile;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  period = g_value_get_int (gimp_value_array_index (args, 3));
  amplitude = g_value_get_int (gimp_value_array_index (args, 4));
  orientation = g_value_get_int (gimp_value_array_index (args, 5));
  edges = g_value_get_int (gimp_value_array_index (args, 6));
  waveform = g_value_get_int (gimp_value_array_index (args, 7));
  antialias = g_value_get_boolean (gimp_value_array_index (args, 8));
  tile = g_value_get_boolean (gimp_value_array_index (args, 9));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gdouble angle, phi;

          angle = orientation ? 0.0 : 90.0;
          phi = waveform ? 0.0 : 0.75;
          if (orientation == 0 && waveform == 1)
            phi = 0.5;

          node = gegl_node_new_child (NULL,
                                      "operation",    "gegl:ripple",
                                      "amplitude",    (gdouble) amplitude,
                                      "period",       (gdouble) period,
                                      "phi",          phi,
                                      "angle",        angle,
                                      "sampler_type", antialias ? GEGL_SAMPLER_CUBIC : GEGL_SAMPLER_NEAREST,
                                      "wave_type",    waveform ? 0 : 1,
                                      "abyss_policy", edges == 0 ? GEGL_ABYSS_CLAMP :
                                                      edges == 1 ? GEGL_ABYSS_LOOP :
                                                      GEGL_ABYSS_NONE,
                                      "tileable",     tile ? TRUE : FALSE,
                                      NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Ripple"),
                                         node);
          g_object_unref (node);
        }
      else
        {
          success = FALSE;
        }
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_rotate_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  GimpDrawable *drawable;
  gint32 angle;
  gboolean everything;

  image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp);
  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  angle = g_value_get_int (gimp_value_array_index (args, 3));
  everything = g_value_get_boolean (gimp_value_array_index (args, 4));

  if (success)
    {
      GimpRotationType rotate_type = angle - 1;

      if (everything)
        {
          gimp_image_rotate (image, context, rotate_type, progress);
        }
      else if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                          GIMP_PDB_ITEM_CONTENT, error))
        {
          GimpItem *item = GIMP_ITEM (drawable);
          gint      off_x, off_y;
          gdouble   center_x, center_y;

          gimp_item_get_offset (item, &off_x, &off_y);

          center_x = ((gdouble) off_x + (gdouble) gimp_item_get_width  (item) / 2.0);
          center_y = ((gdouble) off_y + (gdouble) gimp_item_get_height (item) / 2.0);

          gimp_item_rotate (item, context, rotate_type, center_x, center_y,
                            GIMP_IS_CHANNEL (drawable));
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_noisify_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gboolean independent;
  gdouble noise_1;
  gdouble noise_2;
  gdouble noise_3;
  gdouble noise_4;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  independent = g_value_get_boolean (gimp_value_array_index (args, 3));
  noise_1 = g_value_get_double (gimp_value_array_index (args, 4));
  noise_2 = g_value_get_double (gimp_value_array_index (args, 5));
  noise_3 = g_value_get_double (gimp_value_array_index (args, 6));
  noise_4 = g_value_get_double (gimp_value_array_index (args, 7));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gdouble   r, g, b, a;

          if (gimp_drawable_is_gray (drawable))
            {
              r = noise_1;
              g = noise_1;
              b = noise_1;
              a = noise_2;
            }
          else
            {
              r = noise_1;
              g = noise_2;
              b = noise_3;
              a = noise_4;
            }

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:noise-rgb",
                                      "correlated",  FALSE,
                                      "independent", independent,
                                      "red",         r,
                                      "green",       g,
                                      "blue",        b,
                                      "alpha",       a,
                                      "seed",        g_random_int (),
                                      NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Noisify"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_sel_gauss_invoker (GimpProcedure         *procedure,
                           Gimp                  *gimp,
                           GimpContext           *context,
                           GimpProgress          *progress,
                           const GimpValueArray  *args,
                           GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble radius;
  gint32 max_delta;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  radius = g_value_get_double (gimp_value_array_index (args, 3));
  max_delta = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;

          node = gegl_node_new_child (NULL,
                                      "operation",   "gegl:gaussian-blur-selective",
                                      "blur-radius", radius,
                                      "max-delta",   (gdouble) max_delta / 255.0,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Selective Gaussian Blur"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_semiflatten_invoker (GimpProcedure         *procedure,
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
          gimp_drawable_has_alpha (drawable))
        {
          GeglNode *node;
          GimpRGB   color;

          gimp_context_get_background (context, &color);

          node =
            gegl_node_new_child (NULL,
                                 "operation", "gimp:semi-flatten",
                                 "color",     &color,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Semi-Flatten"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_shift_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 shift_amount;
  gint32 orientation;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  shift_amount = g_value_get_int (gimp_value_array_index (args, 3));
  orientation = g_value_get_int (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:shift",
                                 "shift",     shift_amount / 2,
                                 "direction", orientation ? 0 : 1,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Shift"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_sinus_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble xscale;
  gdouble yscale;
  gdouble complex;
  gint32 seed;
  gboolean tiling;
  gboolean perturb;
  gint32 colors;
  GimpRGB col1;
  GimpRGB col2;
  gdouble alpha1;
  gdouble alpha2;
  gint32 blend;
  gdouble blend_power;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  xscale = g_value_get_double (gimp_value_array_index (args, 3));
  yscale = g_value_get_double (gimp_value_array_index (args, 4));
  complex = g_value_get_double (gimp_value_array_index (args, 5));
  seed = g_value_get_int (gimp_value_array_index (args, 6));
  tiling = g_value_get_boolean (gimp_value_array_index (args, 7));
  perturb = g_value_get_boolean (gimp_value_array_index (args, 8));
  colors = g_value_get_int (gimp_value_array_index (args, 9));
  gimp_value_get_rgb (gimp_value_array_index (args, 10), &col1);
  gimp_value_get_rgb (gimp_value_array_index (args, 11), &col2);
  alpha1 = g_value_get_double (gimp_value_array_index (args, 12));
  alpha2 = g_value_get_double (gimp_value_array_index (args, 13));
  blend = g_value_get_int (gimp_value_array_index (args, 14));
  blend_power = g_value_get_double (gimp_value_array_index (args, 15));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node;
          GeglColor *gegl_color1;
          GeglColor *gegl_color2;
          gint      x, y, width, height;

          switch (colors)
            {
            case 0:
              gimp_rgb_set (&col1, 0.0, 0.0, 0.0);
              gimp_rgb_set (&col2, 1.0, 1.0, 1.0);
              break;

            case 1:
              gimp_context_get_foreground (context, &col1);
              gimp_context_get_background (context, &col2);
              break;
            }

          gimp_rgb_set_alpha (&col1, alpha1);
          gimp_rgb_set_alpha (&col2, alpha2);

          gegl_color1 = gimp_gegl_color_new (&col1);
          gegl_color2 = gimp_gegl_color_new (&col2);

          gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);

          node = gegl_node_new_child (NULL,
                                      "operation",    "gegl:sinus",
                                      "x_scale",      xscale,
                                      "y-scale",      yscale,
                                      "complexity",   complex,
                                      "seed",         seed,
                                      "tiling",       tiling,
                                      "perturbation", perturb,
                                      "color1",       gegl_color1,
                                      "color2",       gegl_color2,
                                      "blend-mode",   blend,
                                      "blend-power",  blend_power,
                                      "width",        width,
                                      "height",       height,
                                      NULL);

          g_object_unref (gegl_color1);
          g_object_unref (gegl_color2);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Sinus"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_sobel_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gboolean horizontal;
  gboolean vertical;
  gboolean keep_sign;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  horizontal = g_value_get_boolean (gimp_value_array_index (args, 3));
  vertical = g_value_get_boolean (gimp_value_array_index (args, 4));
  keep_sign = g_value_get_boolean (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation",  "gegl:edge-sobel",
                                 "horizontal", horizontal,
                                 "vertical",   vertical,
                                 "keep-sign",  keep_sign,
                                 NULL);

          node = wrap_in_gamma_cast (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Sobel"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_solid_noise_invoker (GimpProcedure         *procedure,
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gboolean tileable;
  gboolean turbulent;
  gint32 seed;
  gint32 detail;
  gdouble xsize;
  gdouble ysize;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  tileable = g_value_get_boolean (gimp_value_array_index (args, 3));
  turbulent = g_value_get_boolean (gimp_value_array_index (args, 4));
  seed = g_value_get_int (gimp_value_array_index (args, 5));
  detail = g_value_get_int (gimp_value_array_index (args, 6));
  xsize = g_value_get_double (gimp_value_array_index (args, 7));
  ysize = g_value_get_double (gimp_value_array_index (args, 8));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gint      x, y, width, height;

          gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);

          node = gegl_node_new_child (NULL,
                                      "operation", "gegl:noise-solid",
                                      "x-size",    xsize,
                                      "y-size",    ysize,
                                      "detail",    detail,
                                      "tileable",  tileable,
                                      "turbulent", turbulent,
                                      "seed",      seed,
                                      "width",     width,
                                      "height",    height,
                                      NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Solid Noise"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_spread_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble spread_amount_x;
  gdouble spread_amount_y;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  spread_amount_x = g_value_get_double (gimp_value_array_index (args, 3));
  spread_amount_y = g_value_get_double (gimp_value_array_index (args, 4));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:noise-spread",
                                 "amount-x",  (gint) spread_amount_x,
                                 "amount-y",  (gint) spread_amount_y,
                                 "seed",      g_random_int (),
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Spread"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_threshold_alpha_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 threshold;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  threshold = g_value_get_int (gimp_value_array_index (args, 3));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
          gimp_drawable_has_alpha (drawable))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gimp:threshold-alpha",
                                 "value",     threshold / 255.0,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Threshold Alpha"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_unsharp_mask_invoker (GimpProcedure         *procedure,
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble radius;
  gdouble amount;
  gint32 threshold;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  radius = g_value_get_double (gimp_value_array_index (args, 3));
  amount = g_value_get_double (gimp_value_array_index (args, 4));
  threshold = g_value_get_int (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:unsharp-mask",
                                 "std-dev",   radius,
                                 "scale",     amount,
                                 "threshold", threshold / 255.0,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Sharpen (Unsharp Mask)"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_video_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 pattern_number;
  gboolean additive;
  gboolean rotated;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  pattern_number = g_value_get_int (gimp_value_array_index (args, 3));
  additive = g_value_get_boolean (gimp_value_array_index (args, 4));
  rotated = g_value_get_boolean (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:video-degradation",
                                 "pattern",   pattern_number,
                                 "additive",  additive,
                                 "rotated",   rotated,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Video"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_vinvert_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:value-invert",
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Value Invert"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_vpropagate_invoker (GimpProcedure         *procedure,
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 propagate_mode;
  gint32 propagating_channel;
  gdouble propagating_rate;
  gint32 direction_mask;
  gint32 lower_limit;
  gint32 upper_limit;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  propagate_mode = g_value_get_int (gimp_value_array_index (args, 3));
  propagating_channel = g_value_get_int (gimp_value_array_index (args, 4));
  propagating_rate = g_value_get_double (gimp_value_array_index (args, 5));
  direction_mask = g_value_get_int (gimp_value_array_index (args, 6));
  lower_limit = g_value_get_int (gimp_value_array_index (args, 7));
  upper_limit = g_value_get_int (gimp_value_array_index (args, 8));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode  *node;
          GimpRGB    color;
          GeglColor *gegl_color = NULL;
          gint       gegl_mode  = 0;
          gboolean   to_left    = (direction_mask & (0x1 << 0)) != 0;
          gboolean   to_top     = (direction_mask & (0x1 << 1)) != 0;
          gboolean   to_right   = (direction_mask & (0x1 << 2)) != 0;
          gboolean   to_bottom  = (direction_mask & (0x1 << 3)) != 0;
          gboolean   value      = (propagating_channel & (0x1 << 0)) != 0;
          gboolean   alpha      = (propagating_channel & (0x1 << 1)) != 0;

          switch (propagate_mode)
            {
            case 0:
            case 1:
            case 2:
              gegl_mode = propagate_mode;
              break;

            case 3:
            case 4:
            case 5:
              if (propagate_mode == 3 || propagate_mode == 4)
                {
                  gegl_mode = propagate_mode;

                  gimp_context_get_foreground (context, &color);
                }
              else
                {
                  gegl_mode = 4;

                  gimp_context_get_background (context, &color);
                }

              gegl_color = gimp_gegl_color_new (&color);
              break;

            case 6:
            case 7:
              gegl_mode = propagate_mode - 1;
              break;
            }

          node =
            gegl_node_new_child (NULL,
                                 "operation",        "gegl:value-propagate",
                                 "mode",             gegl_mode,
                                 "lower-threshold",  (gdouble) lower_limit / 255.0,
                                 "upper-threshold",  (gdouble) upper_limit / 255.0,
                                 "rate",             propagating_rate,
                                 "color",            gegl_color,
                                 "top",              to_top,
                                 "left",             to_left,
                                 "right",            to_right,
                                 "bottom",           to_bottom,
                                 "value",            value,
                                 "alpha",            alpha,
                                 NULL);

          if (gegl_color)
            g_object_unref (gegl_color);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Value Propagate"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_dilate_invoker (GimpProcedure         *procedure,
                        Gimp                  *gimp,
                        GimpContext           *context,
                        GimpProgress          *progress,
                        const GimpValueArray  *args,
                        GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation",       "gegl:value-propagate",
                                 "mode",            0, /* GEGL_VALUE_PROPAGATE_MODE_WHITE */
                                 "lower-threshold", 0.0,
                                 "upper-threshold", 1.0,
                                 "rate",            1.0,
                                 "top",             TRUE,
                                 "left",            TRUE,
                                 "right",           TRUE,
                                 "bottom",          TRUE,
                                 "value",           TRUE,
                                 "alpha",           FALSE,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Dilate"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_erode_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation",       "gegl:value-propagate",
                                 "mode",            1, /* GEGL_VALUE_PROPAGATE_MODE_BLACK */
                                 "lower-threshold", 0.0,
                                 "upper-threshold", 1.0,
                                 "rate",            1.0,
                                 "top",             TRUE,
                                 "left",            TRUE,
                                 "right",           TRUE,
                                 "bottom",          TRUE,
                                 "value",           TRUE,
                                 "alpha",           FALSE,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Erode"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_waves_invoker (GimpProcedure         *procedure,
                       Gimp                  *gimp,
                       GimpContext           *context,
                       GimpProgress          *progress,
                       const GimpValueArray  *args,
                       GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble amplitude;
  gdouble phase;
  gdouble wavelength;
  gboolean type;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  amplitude = g_value_get_double (gimp_value_array_index (args, 3));
  phase = g_value_get_double (gimp_value_array_index (args, 4));
  wavelength = g_value_get_double (gimp_value_array_index (args, 5));
  type = g_value_get_boolean (gimp_value_array_index (args, 6));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node;
          gdouble   width  = gimp_item_get_width  (GIMP_ITEM (drawable));
          gdouble   height = gimp_item_get_height (GIMP_ITEM (drawable));
          gdouble   aspect;

          while (phase < 0)
            phase += 360.0;

          phase = fmod (phase, 360.0);

          aspect = CLAMP (width / height, 0.1, 10.0);

          node = gegl_node_new_child (NULL,
                                     "operation", "gegl:waves",
                                     "x",         0.5,
                                     "y",         0.5,
                                     "amplitude", amplitude,
                                     "phi",       (phase - 180.0) / 180.0,
                                     "period",    wavelength * 2.0,
                                     "aspect",    aspect,
                                     "clamp",     ! type,
                                     NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Waves"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_whirl_pinch_invoker (GimpProcedure         *procedure,
                             Gimp                  *gimp,
                             GimpContext           *context,
                             GimpProgress          *progress,
                             const GimpValueArray  *args,
                             GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gdouble whirl;
  gdouble pinch;
  gdouble radius;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  whirl = g_value_get_double (gimp_value_array_index (args, 3));
  pinch = g_value_get_double (gimp_value_array_index (args, 4));
  radius = g_value_get_double (gimp_value_array_index (args, 5));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:whirl-pinch",
                                 "whirl",     whirl,
                                 "pinch",     pinch,
                                 "radius",    radius,
                                 NULL);

          node = wrap_in_selection_bounds (node, drawable);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Whirl and Pinch"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
plug_in_wind_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpDrawable *drawable;
  gint32 threshold;
  gint32 direction;
  gint32 strength;
  gint32 algorithm;
  gint32 edge;

  drawable = gimp_value_get_drawable (gimp_value_array_index (args, 2), gimp);
  threshold = g_value_get_int (gimp_value_array_index (args, 3));
  direction = g_value_get_int (gimp_value_array_index (args, 4));
  strength = g_value_get_int (gimp_value_array_index (args, 5));
  algorithm = g_value_get_int (gimp_value_array_index (args, 6));
  edge = g_value_get_int (gimp_value_array_index (args, 7));

  if (success)
    {
      if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
                                     GIMP_PDB_ITEM_CONTENT, error) &&
          gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
        {
          GeglNode *node =
            gegl_node_new_child (NULL,
                                 "operation", "gegl:wind",
                                 "threshold", threshold,
                                 "direction", direction,
                                 "strength",  strength,
                                 "style",     algorithm,
                                 "edge",      edge,
                                 NULL);

          gimp_drawable_apply_operation (drawable, progress,
                                         C_("undo-type", "Wind"),
                                         node);
          g_object_unref (node);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

void
register_plug_in_compat_procs (GimpPDB *pdb)
{
  GimpProcedure *procedure;

  /*
   * gimp-plug-in-alienmap2
   */
  procedure = gimp_procedure_new (plug_in_alienmap2_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-alienmap2");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-alienmap2",
                                     "Alter colors in various psychedelic ways",
                                     "No help yet. Just try it and you'll see!",
                                     "Compatibility procedure. Please see 'gegl:alien-map' for credits.",
                                     "Compatibility procedure. Please see 'gegl:alien-map' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("redfrequency",
                                                    "redfrequency",
                                                    "Red/hue component frequency factor",
                                                    0, 20, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("redangle",
                                                    "redangle",
                                                    "Red/hue component angle factor (0-360)",
                                                    0, 360, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("greenfrequency",
                                                    "greenfrequency",
                                                    "Green/saturation component frequency factor",
                                                    0, 20, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("greenangle",
                                                    "greenangle",
                                                    "Green/saturation component angle factor (0-360)",
                                                    0, 360, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("bluefrequency",
                                                    "bluefrequency",
                                                    "Blue/luminance component frequency factor",
                                                    0, 20, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("blueangle",
                                                    "blueangle",
                                                    "Blue/luminance component angle factor (0-360)",
                                                    0, 360, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("colormodel",
                                                     "colormodel",
                                                     "Color model { RGB-MODEL (0), HSL-MODEL (1) }",
                                                     0, 1, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("redmode",
                                                     "redmode",
                                                     "Red/hue application mode { TRUE, FALSE }",
                                                     0, 1, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("greenmode",
                                                     "greenmode",
                                                     "Green/saturation application mode { TRUE, FALSE }",
                                                     0, 1, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("bluemode",
                                                     "bluemode",
                                                     "Blue/luminance application mode { TRUE, FALSE }",
                                                     0, 1, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-antialias
   */
  procedure = gimp_procedure_new (plug_in_antialias_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-antialias");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-antialias",
                                     "Antialias using the Scale3X edge-extrapolation algorithm",
                                     "No more help.",
                                     "Compatibility procedure. Please see 'gegl:antialias' for credits.",
                                     "Compatibility procedure. Please see 'gegl:antialias' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-apply-canvas
   */
  procedure = gimp_procedure_new (plug_in_apply_canvas_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-apply-canvas");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-apply-canvas",
                                     "Add a canvas texture to the image",
                                     "This function applies a canvas texture map to the drawable.",
                                     "Compatibility procedure. Please see 'gegl:texturize-canvas' for credits.",
                                     "Compatibility procedure. Please see 'gegl:texturize-canvas' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("direction",
                                                      "direction",
                                                      "Light direction (0 - 3)",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("depth",
                                                      "depth",
                                                      "Texture depth (1 - 50)",
                                                      1, 50, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-applylens
   */
  procedure = gimp_procedure_new (plug_in_applylens_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-applylens");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-applylens",
                                     "Simulate an elliptical lens over the image",
                                     "This plug-in uses Snell's law to draw an ellipsoid lens over the image.",
                                     "Compatibility procedure. Please see 'gegl:apply-lens' for credits.",
                                     "Compatibility procedure. Please see 'gegl:apply-lens' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("refraction",
                                                    "refraction",
                                                    "Lens refraction index",
                                                    1.0, 100.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("keep-surroundings",
                                                     "keep surroundings",
                                                     "Keep lens surroundings",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("set-background",
                                                     "set background",
                                                     "Set lens surroundings to BG value",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("set-transparent",
                                                     "set transparent",
                                                     "Set lens surroundings transparent",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-autocrop
   */
  procedure = gimp_procedure_new (plug_in_autocrop_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-autocrop");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-autocrop",
                                     "Remove empty borders from the image",
                                     "Remove empty borders from the image.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-autocrop-layer
   */
  procedure = gimp_procedure_new (plug_in_autocrop_layer_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-autocrop-layer");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-autocrop-layer",
                                     "Crop the active layer based on empty borders of the input drawable",
                                     "Crop the active layer of the input \"image\" based on empty borders of the input \"drawable\". \n\nThe input drawable serves as a base for detecting cropping extents (transparency or background color), and is not necessarily the cropped layer (the current active layer).",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-autostretch-hsv
   */
  procedure = gimp_procedure_new (plug_in_autostretch_hsv_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-autostretch-hsv");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-autostretch-hsv",
                                     "Stretch contrast to cover the maximum possible range",
                                     "This simple plug-in does an automatic contrast stretch. For each channel in the image, it finds the minimum and maximum values... it uses those values to stretch the individual histograms to the full contrast range. For some images it may do just what you want; for others it may be total crap :). This version differs from Contrast Autostretch in that it works in HSV space, and preserves hue.",
                                     "Compatibility procedure. Please see 'gegl:stretch-contrast-hsv' for credits.",
                                     "Compatibility procedure. Please see 'gegl:stretch-contrast-hsv' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-bump-map
   */
  procedure = gimp_procedure_new (plug_in_bump_map_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-bump-map");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-bump-map",
                                     "Create an embossing effect using a bump map",
                                     "This plug-in uses the algorithm described by John Schlag, \"Fast Embossing Effects on Raster Image Data\" in Graphics GEMS IV (ISBN 0-12-336155-9). It takes a drawable to be applied as a bump map to another image and produces a nice embossing effect.",
                                     "Compatibility procedure. Please see 'gegl:bump-map' for credits.",
                                     "Compatibility procedure. Please see 'gegl:bump-map' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("bumpmap",
                                                            "bumpmap",
                                                            "Bump map drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("azimuth",
                                                    "azimuth",
                                                    "Azimuth",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("elevation",
                                                    "elevation",
                                                    "Elevation",
                                                    0.5, 90.0, 0.5,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("depth",
                                                      "depth",
                                                      "Depth",
                                                      1, 65, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("xofs",
                                                      "xofs",
                                                      "X offset",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("yofs",
                                                      "yofs",
                                                      "Y offset",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("waterlevel",
                                                    "waterlevel",
                                                    "Level that full transparency should represent",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("ambient",
                                                    "ambient",
                                                    "Ambient lighting factor",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("compensate",
                                                     "compensate",
                                                     "Compensate for darkening",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("invert",
                                                     "invert",
                                                     "Invert bumpmap",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("type",
                                                      "type",
                                                      "Type of map { LINEAR (0), SPHERICAL (1), SINUSOIDAL (2) }",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-bump-map-tiled
   */
  procedure = gimp_procedure_new (plug_in_bump_map_tiled_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-bump-map-tiled");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-bump-map-tiled",
                                     "Create an embossing effect using a tiled image as a bump map",
                                     "This plug-in uses the algorithm described by John Schlag, \"Fast Embossing Effects on Raster Image Data\" in Graphics GEMS IV (ISBN 0-12-336155-9). It takes a drawable to be tiled and applied as a bump map to another image and produces a nice embossing effect.",
                                     "Compatibility procedure. Please see 'gegl:bump-map' for credits.",
                                     "Compatibility procedure. Please see 'gegl:bump-map' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("bumpmap",
                                                            "bumpmap",
                                                            "Bump map drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("azimuth",
                                                    "azimuth",
                                                    "Azimuth",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("elevation",
                                                    "elevation",
                                                    "Elevation",
                                                    0.5, 90.0, 0.5,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("depth",
                                                      "depth",
                                                      "Depth",
                                                      1, 65, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("xofs",
                                                      "xofs",
                                                      "X offset",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("yofs",
                                                      "yofs",
                                                      "Y offset",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("waterlevel",
                                                    "waterlevel",
                                                    "Level that full transparency should represent",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("ambient",
                                                    "ambient",
                                                    "Ambient lighting factor",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("compensate",
                                                     "compensate",
                                                     "Compensate for darkening",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("invert",
                                                     "invert",
                                                     "Invert bumpmap",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("type",
                                                      "type",
                                                      "Type of map { LINEAR (0), SPHERICAL (1), SINUSOIDAL (2) }",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-c-astretch
   */
  procedure = gimp_procedure_new (plug_in_c_astretch_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-c-astretch");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-c-astretch",
                                     "Stretch contrast to cover the maximum possible range",
                                     "This simple plug-in does an automatic contrast stretch. For each channel in the image, it finds the minimum and maximum values... it uses those values to stretch the individual histograms to the full contrast range. For some images it may do just what you want; for others it may not work that well.",
                                     "Compatibility procedure. Please see 'gegl:stretch-contrast' for credits.",
                                     "Compatibility procedure. Please see 'gegl:stretch-contrast' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-colors-channel-mixer
   */
  procedure = gimp_procedure_new (plug_in_colors_channel_mixer_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-colors-channel-mixer");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-colors-channel-mixer",
                                     "Alter colors by mixing RGB Channels",
                                     "This plug-in mixes the RGB channels.",
                                     "Compatibility procedure. Please see 'gegl:channel-mixer' for credits.",
                                     "Compatibility procedure. Please see 'gegl:channel-mixer' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("monochrome",
                                                      "monochrome",
                                                      "Monochrome { TRUE, FALSE }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rr-gain",
                                                    "rr gain",
                                                    "Set the red gain for the red channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rg-gain",
                                                    "rg gain",
                                                    "Set the green gain for the red channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rb-gain",
                                                    "rb gain",
                                                    "Set the blue gain for the red channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("gr-gain",
                                                    "gr gain",
                                                    "Set the red gain for the green channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("gg-gain",
                                                    "gg gain",
                                                    "Set the green gain for the green channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("gb-gain",
                                                    "gb gain",
                                                    "Set the blue gain for the green channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("br-gain",
                                                    "br gain",
                                                    "Set the red gain for the blue channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("bg-gain",
                                                    "bg gain",
                                                    "Set the green gain for the blue channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("bb-gain",
                                                    "bb gain",
                                                    "Set the blue gain for the blue channel",
                                                    -2, 2, -2,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-colortoalpha
   */
  procedure = gimp_procedure_new (plug_in_colortoalpha_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-colortoalpha");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-colortoalpha",
                                     "Convert a specified color to transparency",
                                     "This replaces as much of a given color as possible in each pixel with a corresponding amount of alpha, then readjusts the color accordingly.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1999",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("color",
                                                    "color",
                                                    "Color to remove",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-convmatrix
   */
  procedure = gimp_procedure_new (plug_in_convmatrix_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-convmatrix");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-convmatrix",
                                     "Apply a generic 5x5 convolution matrix",
                                     "Apply a generic 5x5 convolution matrix.",
                                     "Compatibility procedure. Please see 'gegl:convolution-matrix' for credits.",
                                     "Compatibility procedure. Please see 'gegl:convolution-matrix' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("argc-matrix",
                                                      "argc matrix",
                                                      "The number of elements in the following array, must always be 25",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_float_array ("matrix",
                                                            "matrix",
                                                            "The 5x5 convolution matrix",
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("alpha-alg",
                                                     "alpha alg",
                                                     "Enable weighting by alpha channel",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("divisor",
                                                    "divisor",
                                                    "Divisor",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("offset",
                                                    "offset",
                                                    "Offset",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("argc-channels",
                                                      "argc channels",
                                                      "The number of elements in following array, must always be 5",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32_array ("channels",
                                                            "channels",
                                                            "Mask of the channels to be filtered",
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("bmode",
                                                      "bmode",
                                                      "Mode for treating image borders { EXTEND (0), WRAP (1), CLEAR (2) }",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-cubism
   */
  procedure = gimp_procedure_new (plug_in_cubism_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-cubism");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-cubism",
                                     "Convert the image into randomly rotated square blobs",
                                     "Convert the image into randomly rotated square blobs.",
                                     "Compatibility procedure. Please see 'gegl:cubism' for credits.",
                                     "Compatibility procedure. Please see 'gegl:cubism' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("tile-size",
                                                    "tile size",
                                                    "Average diameter of each tile (in pixels)",
                                                    0.0, 100.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("tile-saturation",
                                                    "tile saturation",
                                                    "Expand tiles by this amount",
                                                    0.0, 10.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("bg-color",
                                                      "bg color",
                                                      "Background color { BLACK (0), BG (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-deinterlace
   */
  procedure = gimp_procedure_new (plug_in_deinterlace_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-deinterlace");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-deinterlace",
                                     "Fix images where every other row is missing",
                                     "Deinterlace is useful for processing images from video capture cards. When only the odd or even fields get captured, deinterlace can be used to interpolate between the existing fields to correct this.",
                                     "Compatibility procedure. Please see 'gegl:deinterlace' for credits.",
                                     "Compatibility procedure. Please see 'gegl:deinterlace' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("evenodd",
                                                      "evenodd",
                                                      "Which lines to keep { KEEP-ODD (0), KEEP-EVEN (1)",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-diffraction
   */
  procedure = gimp_procedure_new (plug_in_diffraction_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-diffraction");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-diffraction",
                                     "Generate diffraction patterns",
                                     "Help? What help?",
                                     "Compatibility procedure. Please see 'gegl:diffraction-patterns' for credits.",
                                     "Compatibility procedure. Please see 'gegl:diffraction-patterns' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("lam-r",
                                                    "lam r",
                                                    "Light frequency (red)",
                                                    0.0, 20.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("lam-g",
                                                    "lam g",
                                                    "Light frequency (green)",
                                                    0.0, 20.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("lam-b",
                                                    "lam b",
                                                    "Light frequency (blue)",
                                                    0.0, 20.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("contour-r",
                                                    "contour r",
                                                    "Number of contours (red)",
                                                    0.0, 10.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("contour-g",
                                                    "contour g",
                                                    "Number of contours (green)",
                                                    0.0, 10.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("contour-b",
                                                    "contour b",
                                                    "Number of contours (blue)",
                                                    0.0, 10.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("edges-r",
                                                    "edges r",
                                                    "Number of sharp edges (red)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("edges-g",
                                                    "edges g",
                                                    "Number of sharp edges (green)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("edges-b",
                                                    "edges b",
                                                    "Number of sharp edges (blue)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("brightness",
                                                    "brightness",
                                                    "Brightness and shifting/fattening of contours",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("scattering",
                                                    "scattering",
                                                    "Scattering (Speed vs. quality)",
                                                    0.0, 100.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("polarization",
                                                    "polarization",
                                                    "Polarization",
                                                    -1.0, 1.0, -1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-displace
   */
  procedure = gimp_procedure_new (plug_in_displace_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-displace");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-displace",
                                     "Displace pixels as indicated by displacement maps",
                                     "Displaces the contents of the specified drawable by the amounts specified by 'amount-x' and 'amount-y' multiplied by the luminance of corresponding pixels in the 'displace-map' drawables.",
                                     "Compatibility procedure. Please see 'gegl:displace' for credits.",
                                     "Compatibility procedure. Please see 'gegl:displace' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount-x",
                                                    "amount x",
                                                    "Displace multiplier for x direction",
                                                    -500.0, 500.0, -500.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount-y",
                                                    "amount y",
                                                    "Displace multiplier for y direction",
                                                    -500.0, 500.0, -500.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("do-x",
                                                     "do x",
                                                     "Displace in x direction ?",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("do-y",
                                                     "do y",
                                                     "Displace in y direction ?",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("displace-map-x",
                                                            "displace map x",
                                                            "Displacement map for x direction",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("displace-map-y",
                                                            "displace map y",
                                                            "Displacement map for y direction",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("displace-type",
                                                      "displace type",
                                                      "Edge behavior { WRAP (1), SMEAR (2), BLACK (3) }",
                                                      1, 3, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-displace-polar
   */
  procedure = gimp_procedure_new (plug_in_displace_polar_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-displace-polar");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-displace-polar",
                                     "Displace pixels as indicated by displacement maps",
                                     "Just like plug-in-displace but working in polar coordinates. The drawable is whirled and pinched according to the map.",
                                     "Compatibility procedure. Please see 'gegl:displace' for credits.",
                                     "Compatibility procedure. Please see 'gegl:displace' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount-x",
                                                    "amount x",
                                                    "Displace multiplier for radial direction",
                                                    -500.0, 500.0, -500.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount-y",
                                                    "amount y",
                                                    "Displace multiplier for tangent direction",
                                                    -500.0, 500.0, -500.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("do-x",
                                                     "do x",
                                                     "Displace in radial direction ?",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("do-y",
                                                     "do y",
                                                     "Displace in tangent direction ?",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("displace-map-x",
                                                            "displace map x",
                                                            "Displacement map for radial direction",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("displace-map-y",
                                                            "displace map y",
                                                            "Displacement map for tangent direction",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("displace-type",
                                                      "displace type",
                                                      "Edge behavior { WRAP (1), SMEAR (2), BLACK (3) }",
                                                      1, 3, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-edge
   */
  procedure = gimp_procedure_new (plug_in_edge_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-edge");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-edge",
                                     "Several simple methods for detecting edges",
                                     "Perform edge detection on the contents of the specified drawable. AMOUNT is an arbitrary constant, WRAPMODE is like displace plug-in (useful for tileable image). EDGEMODE sets the kind of matrix transform applied to the pixels, SOBEL was the method used in older versions.",
                                     "Compatibility procedure. Please see 'gegl:edge' for credits.",
                                     "Compatibility procedure. Please see 'gegl:edge' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount",
                                                    "amount",
                                                    "Edge detection amount",
                                                    1.0, 10.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("warpmode",
                                                      "warpmode",
                                                      "Edge detection behavior { NONE (0), WRAP (1), SMEAR (2), BLACK (3) }",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("edgemode",
                                                      "edgemode",
                                                      "Edge detection algorithm { SOBEL (0), PREWITT (1), GRADIENT (2), ROBERTS (3), DIFFERENTIAL (4), LAPLACE (5) }",
                                                      0, 5, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-engrave
   */
  procedure = gimp_procedure_new (plug_in_engrave_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-engrave");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-engrave",
                                     "Simulate an antique engraving",
                                     "Creates a black-and-white 'engraved' version of an image as seen in old illustrations.",
                                     "Compatibility procedure. Please see 'gegl:engrave' for credits.",
                                     "Compatibility procedure. Please see 'gegl:engrave' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("height",
                                                      "height",
                                                      "Resolution in pixels",
                                                      2, 16, 2,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("limit",
                                                     "limit",
                                                     "Limit line width",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-exchange
   */
  procedure = gimp_procedure_new (plug_in_exchange_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-exchange");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-exchange",
                                     "Swap one color with another",
                                     "Exchange one color with another, optionally setting a threshold to convert from one shade to another.",
                                     "Compatibility procedure. Please see 'gegl:color-exchange' for credits.",
                                     "Compatibility procedure. Please see 'gegl:color-exchange' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("from-red",
                                                     "from red",
                                                     "Red value (from)",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("from-green",
                                                     "from green",
                                                     "Green value (from)",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("from-blue",
                                                     "from blue",
                                                     "Blue value (from)",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("to-red",
                                                     "to red",
                                                     "Red value (to)",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("to-green",
                                                     "to green",
                                                     "Green value (to)",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("to-blue",
                                                     "to blue",
                                                     "Blue value (to)",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("red-threshold",
                                                     "red threshold",
                                                     "Red threshold",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("green-threshold",
                                                     "green threshold",
                                                     "Green threshold",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("blue-threshold",
                                                     "blue threshold",
                                                     "Blue threshold",
                                                     0, G_MAXUINT8, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-flarefx
   */
  procedure = gimp_procedure_new (plug_in_flarefx_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-flarefx");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-flarefx",
                                     "Add a lens flare effect",
                                     "Adds a lens flare effects. Makes your image look like it was snapped with a cheap camera with a lot of lens :)",
                                     "Compatibility procedure. Please see 'gegl:lens-flare' for credits.",
                                     "Compatibility procedure. Please see 'gegl:lens-flare' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("pos-x",
                                                      "pos x",
                                                      "X-Position",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("pos-y",
                                                      "pos y",
                                                      "Y-Position",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-gauss
   */
  procedure = gimp_procedure_new (plug_in_gauss_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-gauss");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-gauss",
                                     "Simplest, most commonly used way of blurring",
                                     "Applies a gaussian blur to the drawable, with specified radius of affect. The standard deviation of the normal distribution used to modify pixel values is calculated based on the supplied radius. Horizontal and vertical blurring can be independently invoked by specifying only one to run. The 'method' parameter is ignored.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("horizontal",
                                                    "horizontal",
                                                    "Horizontal radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("vertical",
                                                    "vertical",
                                                    "Vertical radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("method",
                                                      "method",
                                                      "Blur method { IIR (0), RLE (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-gauss-iir
   */
  procedure = gimp_procedure_new (plug_in_gauss_iir_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-gauss-iir");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-gauss-iir",
                                     "Apply a gaussian blur",
                                     "Applies a gaussian blur to the drawable, with specified radius of affect. The standard deviation of the normal distribution used to modify pixel values is calculated based on the supplied radius. Horizontal and vertical blurring can be independently invoked by specifying only one to run.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("radius",
                                                    "radius",
                                                    "Radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("horizontal",
                                                     "horizontal",
                                                     "Blur in horizontal direction",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("vertical",
                                                     "vertical",
                                                     "Blur in vertical direction",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-gauss-iir2
   */
  procedure = gimp_procedure_new (plug_in_gauss_iir2_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-gauss-iir2");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-gauss-iir2",
                                     "Apply a gaussian blur",
                                     "Applies a gaussian blur to the drawable, with specified radius of affect. The standard deviation of the normal distribution used to modify pixel values is calculated based on the supplied radius. Horizontal and vertical blurring can be independently invoked by specifying only one to run.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("horizontal",
                                                    "horizontal",
                                                    "Horizontal radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("vertical",
                                                    "vertical",
                                                    "Vertical radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-gauss-rle
   */
  procedure = gimp_procedure_new (plug_in_gauss_rle_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-gauss-rle");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-gauss-rle",
                                     "Apply a gaussian blur",
                                     "Applies a gaussian blur to the drawable, with specified radius of affect. The standard deviation of the normal distribution used to modify pixel values is calculated based on the supplied radius. Horizontal and vertical blurring can be independently invoked by specifying only one to run.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("radius",
                                                    "radius",
                                                    "Radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("horizontal",
                                                     "horizontal",
                                                     "Blur in horizontal direction",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("vertical",
                                                     "vertical",
                                                     "Blur in vertical direction",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-gauss-rle2
   */
  procedure = gimp_procedure_new (plug_in_gauss_rle2_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-gauss-rle2");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-gauss-rle2",
                                     "Apply a gaussian blur",
                                     "Applies a gaussian blur to the drawable, with specified radius of affect. The standard deviation of the normal distribution used to modify pixel values is calculated based on the supplied radius. Horizontal and vertical blurring can be independently invoked by specifying only one to run.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("horizontal",
                                                    "horizontal",
                                                    "Horizontal radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("vertical",
                                                    "vertical",
                                                    "Vertical radius of gaussian blur (in pixels",
                                                    0.0, 500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-glasstile
   */
  procedure = gimp_procedure_new (plug_in_glasstile_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-glasstile");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-glasstile",
                                     "Simulate distortion caused by square glass tiles",
                                     "Divide the image into square glassblocks in which the image is refracted.",
                                     "Compatibility procedure. Please see 'gegl:tile-glass' for credits.",
                                     "Compatibility procedure. Please see 'gegl:tile-glass' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("tilex",
                                                      "tilex",
                                                      "Tile width",
                                                      10, 500, 10,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("tiley",
                                                      "tiley",
                                                      "Tile height",
                                                      10, 500, 10,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-hsv-noise
   */
  procedure = gimp_procedure_new (plug_in_hsv_noise_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-hsv-noise");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-hsv-noise",
                                     "Randomize hue, saturation and value independently",
                                     "Scattering pixel values in HSV space",
                                     "Compatibility procedure. Please see 'gegl:noise-hsv' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-hsv' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("holdness",
                                                      "holdness",
                                                      "Convolution strength",
                                                      1, 8, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("hue-distance",
                                                      "hue distance",
                                                      "Scattering of hue angle",
                                                      0, 180, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("saturation-distance",
                                                      "saturation distance",
                                                      "Distribution distance on saturation axis",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("value-distance",
                                                      "value distance",
                                                      "Distribution distance on value axis",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-icc-profile-info
   */
  procedure = gimp_procedure_new (plug_in_icc_profile_info_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-icc-profile-info");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-icc-profile-info",
                                     "Retrieve information about an image's color profile",
                                     "This procedure returns information about the RGB color profile attached to an image. If no RGB color profile is attached, sRGB is assumed.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("profile-name",
                                                           "profile name",
                                                           "Name",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("profile-desc",
                                                           "profile desc",
                                                           "Description",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("profile-info",
                                                           "profile info",
                                                           "Info",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-icc-profile-file-info
   */
  procedure = gimp_procedure_new (plug_in_icc_profile_file_info_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-icc-profile-file-info");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-icc-profile-file-info",
                                     "Retrieve information about a color profile",
                                     "This procedure returns information about an ICC color profile on disk.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("profile",
                                                       "profile",
                                                       "Filename of an ICC color profile",
                                                       TRUE, FALSE, FALSE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("profile-name",
                                                           "profile name",
                                                           "Name",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("profile-desc",
                                                           "profile desc",
                                                           "Description",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("profile-info",
                                                           "profile info",
                                                           "Info",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-icc-profile-apply
   */
  procedure = gimp_procedure_new (plug_in_icc_profile_apply_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-icc-profile-apply");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-icc-profile-apply",
                                     "Apply a color profile on the image",
                                     "This procedure transform from the image's color profile (or the default RGB profile if none is set) to the given ICC color profile. Only RGB color profiles are accepted. The profile is then set on the image using the 'icc-profile' \"parasite.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("profile",
                                                       "profile",
                                                       "Filename of an ICC color profile",
                                                       TRUE, FALSE, FALSE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("intent",
                                                  "intent",
                                                  "Rendering intent",
                                                  GIMP_TYPE_COLOR_RENDERING_INTENT,
                                                  GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("bpc",
                                                     "bpc",
                                                     "Black point compensation",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-icc-profile-apply-rgb
   */
  procedure = gimp_procedure_new (plug_in_icc_profile_apply_rgb_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-icc-profile-apply-rgb");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-icc-profile-apply-rgb",
                                     "Apply default RGB color profile on the image",
                                     "This procedure transform from the image's color profile (or the default RGB profile if none is set) to the configured default RGB color profile. The profile is then set on the image using the 'icc-profile' parasite. If no RGB color profile is configured, sRGB is assumed and the parasite is unset.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("intent",
                                                  "intent",
                                                  "Rendering intent",
                                                  GIMP_TYPE_COLOR_RENDERING_INTENT,
                                                  GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("bpc",
                                                     "bpc",
                                                     "Black point compensation",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-icc-profile-set
   */
  procedure = gimp_procedure_new (plug_in_icc_profile_set_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-icc-profile-set");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-icc-profile-set",
                                     "Set a color profile on the image",
                                     "This procedure sets the user-configured RGB profile on an image using the 'icc-profile' parasite. This procedure does not do any color conversion.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("profile",
                                                       "profile",
                                                       "Filename of an ICC color profile",
                                                       TRUE, FALSE, FALSE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-icc-profile-set-rgb
   */
  procedure = gimp_procedure_new (plug_in_icc_profile_set_rgb_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-icc-profile-set-rgb");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-icc-profile-set-rgb",
                                     "Set the default RGB color profile on the image",
                                     "This procedure sets the user-configured RGB profile on an image using the 'icc-profile' parasite. If no RGB profile is configured, sRGB is assumed and the parasite is unset. This procedure does not do any color conversion.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-illusion
   */
  procedure = gimp_procedure_new (plug_in_illusion_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-illusion");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-illusion",
                                     "Superimpose many altered copies of the image",
                                     "Produce illusion.",
                                     "Compatibility procedure. Please see 'gegl:illusion' for credits.",
                                     "Compatibility procedure. Please see 'gegl:illusion' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("division",
                                                      "division",
                                                      "The number of divisions",
                                                      0, 64, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("type",
                                                      "type",
                                                      "Illusion type { TYPE1 (0), TYPE2 (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-laplace
   */
  procedure = gimp_procedure_new (plug_in_laplace_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-laplace");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-laplace",
                                     "High-resolution edge detection",
                                     "This plug-in creates one-pixel wide edges from the image, with the value proportional to the gradient. It uses the Laplace operator (a 3x3 kernel with -8 in the middle). The image has to be laplacered to get useful results, a gauss_iir with 1.5 - 5.0 depending on the noise in the image is best.",
                                     "Compatibility procedure. Please see 'gegl:edge-laplace' for credits.",
                                     "Compatibility procedure. Please see 'gegl:edge-laplace' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-lens-distortion
   */
  procedure = gimp_procedure_new (plug_in_lens_distortion_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-lens-distortion");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-lens-distortion",
                                     "Corrects lens distortion",
                                     "Corrects barrel or pincushion lens distortion.",
                                     "Compatibility procedure. Please see 'gegl:lens-distortion' for credits.",
                                     "Compatibility procedure. Please see 'gegl:lens-distortion' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("offset-x",
                                                    "offset x",
                                                    "Effect centre offset in X",
                                                    -100, 100, -100,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("offset-y",
                                                    "offset y",
                                                    "Effect centre offset in Y",
                                                    -100, 100, -100,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("main-adjust",
                                                    "main adjust",
                                                    "Amount of second-order distortion",
                                                    -100, 100, -100,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("edge-adjust",
                                                    "edge adjust",
                                                    "Amount of fourth-order distortion",
                                                    -100, 100, -100,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rescale",
                                                    "rescale",
                                                    "Rescale overall image size",
                                                    -100, 100, -100,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("brighten",
                                                    "brighten",
                                                    "Adjust brightness in corners",
                                                    -100, 100, -100,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-make-seamless
   */
  procedure = gimp_procedure_new (plug_in_make_seamless_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-make-seamless");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-make-seamless",
                                     "Alters edges to make the image seamlessly tileable",
                                     "This plug-in creates a seamless tileable from the input drawable.",
                                     "Compatibility procedure. Please see 'gegl:tile-seamless' for credits.",
                                     "Compatibility procedure. Please see 'gegl:tile-seamless' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-maze
   */
  procedure = gimp_procedure_new (plug_in_maze_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-maze");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-maze",
                                     "Draw a labyrinth",
                                     "Generates a maze using either the depth-first search method or Prim's algorithm. Can make tileable mazes too.",
                                     "Compatibility procedure. Please see 'gegl:maze' for credits.",
                                     "Compatibility procedure. Please see 'gegl:maze' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int16 ("width",
                                                      "width",
                                                      "Width of the passages",
                                                      1, 1024, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int16 ("height",
                                                      "height",
                                                      "Height of the passages",
                                                      1, 1024, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("tileable",
                                                     "tileable",
                                                     "Tileable maze? (TRUE or FALSE)",
                                                     0, 1, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int8 ("algorithm",
                                                     "algorithm",
                                                     "Generation algorithm (0 = DEPTH FIRST, 1 = PRIM'S ALGORITHM)",
                                                     0, 1, 0,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Random Seed",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int16 ("multiple",
                                                      "multiple",
                                                      "Multiple (use 57)",
                                                      G_MININT16, G_MAXINT16, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int16 ("offset",
                                                      "offset",
                                                      "Offset (use 1)",
                                                      G_MININT16, G_MAXINT16, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-mblur
   */
  procedure = gimp_procedure_new (plug_in_mblur_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-mblur");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-mblur",
                                     "Simulate movement using directional blur",
                                     "This plug-in simulates the effect seen when photographing a moving object at a slow shutter speed. Done by adding multiple displaced copies.",
                                     "Compatibility procedure. Please see 'gegl:motion-blur-linear, -zoom, -cirular' for credits.",
                                     "Compatibility procedure. Please see 'gegl:motion-blur-linear, -zoom, -cirular' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("type",
                                                      "type",
                                                      "Type of motion blur { LINEAR (0), RADIAL (1), ZOOM (2) }",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("length",
                                                    "length",
                                                    "Length",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("angle",
                                                    "angle",
                                                    "Angle",
                                                    0, 360, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("center-x",
                                                    "center x",
                                                    "Center X",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("center-y",
                                                    "center y",
                                                    "Center Y",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-mblur-inward
   */
  procedure = gimp_procedure_new (plug_in_mblur_inward_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-mblur-inward");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-mblur-inward",
                                     "Simulate movement using directional blur",
                                     "This procedure is equivalent to plug-in-mblur but performs the zoom blur inward instead of outward.",
                                     "Compatibility procedure. Please see 'gegl:motion-blur-linear, -zoom, -cirular' for credits.",
                                     "Compatibility procedure. Please see 'gegl:motion-blur-linear, -zoom, -cirular' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("type",
                                                      "type",
                                                      "Type of motion blur { LINEAR (0), RADIAL (1), ZOOM (2) }",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("length",
                                                    "length",
                                                    "Length",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("angle",
                                                    "angle",
                                                    "Angle",
                                                    0, 360, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("center-x",
                                                    "center x",
                                                    "Center X",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("center-y",
                                                    "center y",
                                                    "Center Y",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-median-blur
   */
  procedure = gimp_procedure_new (plug_in_median_blur_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-median-blur");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-median-blur",
                                     "Blur using the median color near each pixel",
                                     "Blur resulting from computing the median color in the neighborhood of each pixel",
                                     "Compatibility procedure. Please see 'gegl:median-blur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:median-blur' for credits.",
                                     "2021",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("radius",
                                                      "radius",
                                                      "Neighborhood radius, a negative value will calculate with inverted percentiles",
                                                      -400, 400, -400,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("percentile",
                                                    "percentile",
                                                    "Neighborhood color percentile",
                                                    0, 100, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-mosaic
   */
  procedure = gimp_procedure_new (plug_in_mosaic_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-mosaic");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-mosaic",
                                     "Convert the image into irregular tiles",
                                     "Mosaic is a filter which transforms an image into what appears to be a mosaic, composed of small primitives, each of constant color and of an approximate size.",
                                     "Compatibility procedure. Please see 'gegl:mosaic' for credits.",
                                     "Compatibility procedure. Please see 'gegl:mosaic' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("tile-size",
                                                    "tile size",
                                                    "Average diameter of each tile (in pixels)",
                                                    1, 1000, 1,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("tile-height",
                                                    "tile height",
                                                    "Apparent height of each tile (in pixels)",
                                                    1, 1000, 1,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("tile-spacing",
                                                    "tile spacing",
                                                    "Inter_tile spacing (in pixels)",
                                                    0.1, 1000, 0.1,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("tile-neatness",
                                                    "tile neatness",
                                                    "Deviation from perfectly formed tiles",
                                                    0, 1.0, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("tile-allow-split",
                                                      "tile allow split",
                                                      "Allows splitting tiles at hard edges",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("light-dir",
                                                    "light dir",
                                                    "Direction of light_source (in degrees)",
                                                    0, 360, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("color-variation",
                                                    "color variation",
                                                    "Magnitude of random color variations",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("antialiasing",
                                                      "antialiasing",
                                                      "Enables smoother tile output at the cost of speed",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("color-averaging",
                                                      "color averaging",
                                                      "Tile color based on average of subsumed pixels",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("tile-type",
                                                      "tile type",
                                                      "Tile geometry { SQUARES (0), HEXAGONS (1), OCTAGONS (2), TRIANGLES (3) }",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("tile-surface",
                                                      "tile surface",
                                                      "Surface characteristics { SMOOTH (0), ROUGH (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("grout-color",
                                                      "grout color",
                                                      "Grout color (black/white or fore/background) { BW (0), FG-BG (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-neon
   */
  procedure = gimp_procedure_new (plug_in_neon_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-neon");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-neon",
                                     "Simulate the glowing boundary of a neon light",
                                     "This filter works in a manner similar to the edge plug-in, but uses the first derivative of the gaussian operator to achieve resolution independence. The IIR method of calculating the effect is utilized to keep the processing time constant between large and small standard deviations.",
                                     "Compatibility procedure. Please see 'gegl:edge-neon' for credits.",
                                     "Compatibility procedure. Please see 'gegl:edge-neon' for credits.",
                                     "2019",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("radius",
                                                    "radius",
                                                    "Radius of neon effect (in pixels)",
                                                    0.0, 1500.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount",
                                                    "amount",
                                                    "Effect enhancement variable",
                                                    0.0, 100.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-newsprint
   */
  procedure = gimp_procedure_new (plug_in_newsprint_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-newsprint");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-newsprint",
                                     "Halftone the image to give newspaper-like effect",
                                     "Halftone the image to give newspaper-like effect",
                                     "Compatibility procedure. Please see 'gegl:newsprint' for credits.",
                                     "Compatibility procedure. Please see 'gegl:newsprint' for credits.",
                                     "2019",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("cell-width",
                                                      "cell width",
                                                      "Screen cell width in pixels",
                                                      0, 1500, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("colorspace",
                                                      "colorspace",
                                                      "Separate to { GRAYSCALE (0), RGB (1), CMYK (2), LUMINANCE (3) }",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("k-pullout",
                                                      "k pullout",
                                                      "Percentage of black to pullout (CMYK only)",
                                                      0, 100, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("gry-ang",
                                                    "gry ang",
                                                    "Grey/black screen angle (degrees)",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("gry-spotfn",
                                                      "gry spotfn",
                                                      "Grey/black spot function { DOTS (0), LINES (1), DIAMONDS (2), EUCLIDIAN-DOT (3), PS-DIAMONDS (4) }",
                                                      0, 4, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("red-ang",
                                                    "red ang",
                                                    "Red/cyan screen angle (degrees)",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("red-spotfn",
                                                      "red spotfn",
                                                      "Red/cyan spot function { DOTS (0), LINES (1), DIAMONDS (2), EUCLIDIAN-DOT (3), PS-DIAMONDS (4) }",
                                                      0, 4, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("grn-ang",
                                                    "grn ang",
                                                    "Green/magenta screen angle (degrees)",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("grn-spotfn",
                                                      "grn spotfn",
                                                      "Green/magenta spot function { DOTS (0), LINES (1), DIAMONDS (2), EUCLIDIAN-DOT (3), PS-DIAMONDS (4) }",
                                                      0, 4, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("blu-ang",
                                                    "blu ang",
                                                    "Blue/yellow screen angle (degrees)",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("blu-spotfn",
                                                      "blu spotfn",
                                                      "Blue/yellow spot function { DOTS (0), LINES (1), DIAMONDS (2), EUCLIDIAN-DOT (3), PS-DIAMONDS (4) }",
                                                      0, 4, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("oversample",
                                                      "oversample",
                                                      "how many times to oversample spot fn",
                                                      0, 128, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-normalize
   */
  procedure = gimp_procedure_new (plug_in_normalize_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-normalize");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-normalize",
                                     "Stretch brightness values to cover the full range",
                                     "This plug-in performs almost the same operation as the 'contrast autostretch' plug-in, except that it won't allow the color channels to normalize independently. This is actually what most people probably want instead of contrast-autostretch; use c-a only if you wish to remove an undesirable color-tint from a source image which is supposed to contain pure-white and pure-black.",
                                     "Compatibility procedure. Please see 'gegl:stretch-contrast' for credits.",
                                     "Compatibility procedure. Please see 'gegl:stretch-contrast' for credits.",
                                     "2019",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-nova
   */
  procedure = gimp_procedure_new (plug_in_nova_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-nova");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-nova",
                                     "Add a starburst to the image",
                                     "This plug-in produces an effect like a supernova burst. The amount of the light effect is approximately in proportion to 1/r, where r is the distance from the center of the star.",
                                     "Compatibility procedure. Please see 'gegl:supernova' for credits.",
                                     "Compatibility procedure. Please see 'gegl:supernova' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("xcenter",
                                                      "xcenter",
                                                      "X coordinates of the center of supernova",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("ycenter",
                                                      "ycenter",
                                                      "Y coordinates of the center of supernova",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("color",
                                                    "color",
                                                    "Color of supernova",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("radius",
                                                      "radius",
                                                      "Radius of supernova",
                                                      1, 3000, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("nspoke",
                                                      "nspoke",
                                                      "Number of spokes",
                                                      1, 1024, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("randomhue",
                                                      "randomhue",
                                                      "Random hue",
                                                      0, 360, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-oilify
   */
  procedure = gimp_procedure_new (plug_in_oilify_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-oilify");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-oilify",
                                     "Smear colors to simulate an oil painting",
                                     "This function performs the well-known oil-paint effect on the specified drawable.",
                                     "Compatibility procedure. Please see 'gegl:oilify' for credits.",
                                     "Compatibility procedure. Please see 'gegl:oilify' for credits.",
                                     "2019",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("mask-size",
                                                      "mask size",
                                                      "Oil paint mask size",
                                                      1, 200, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("mode",
                                                      "mode",
                                                      "Algorithm { RGB (0), INTENSITY (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-oilify-enhanced
   */
  procedure = gimp_procedure_new (plug_in_oilify_enhanced_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-oilify-enhanced");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-oilify-enhanced",
                                     "Smear colors to simulate an oil painting",
                                     "This function performs the well-known oil-paint effect on the specified drawable.",
                                     "Compatibility procedure. Please see 'gegl:oilify' for credits.",
                                     "Compatibility procedure. Please see 'gegl:oilify' for credits.",
                                     "2019",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("mode",
                                                      "mode",
                                                      "Algorithm { RGB (0), INTENSITY (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("mask-size",
                                                      "mask size",
                                                      "Oil paint mask size",
                                                      1, 200, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("mask-size-map",
                                                            "mask size map",
                                                            "Mask size control map",
                                                            pdb->gimp, TRUE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("exponent",
                                                      "exponent",
                                                      "Oil paint exponent",
                                                      1, 20, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("exponent-map",
                                                            "exponent map",
                                                            "Exponent control map",
                                                            pdb->gimp, TRUE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-papertile
   */
  procedure = gimp_procedure_new (plug_in_papertile_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-papertile");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-papertile",
                                     "Cut image into paper tiles, and slide them",
                                     "This plug-in cuts an image into paper tiles and slides each paper tile.",
                                     "Compatibility procedure. Please see 'gegl:tile-paper' for credits.",
                                     "Compatibility procedure. Please see 'gegl:tile-paper' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("tile-size",
                                                      "tile size",
                                                      "Tile size (pixels)",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("move-max",
                                                    "move max",
                                                    "Max move rate (%)",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("fractional-type",
                                                      "fractional type",
                                                      "Fractional type { BACKGROUND (0), IGNORE (1), FORCE (2) }",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("wrap-around",
                                                     "wrap around",
                                                     "Wrap around",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("centering",
                                                     "centering",
                                                     "Centering",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("background-type",
                                                      "background type",
                                                      "Background type { TRANSPARENT (0), INVERTED (1), IMAGE (2), FG (3), BG (4), COLOR (5) }",
                                                      0, 5, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("background-color",
                                                    "background color",
                                                    "Background color (for background-type == 5)",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("background-alpha",
                                                      "background alpha",
                                                      "Background alpha (unused)",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-pixelize
   */
  procedure = gimp_procedure_new (plug_in_pixelize_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-pixelize");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-pixelize",
                                     "Simplify image into an array of solid-colored squares",
                                     "Pixelize the contents of the specified drawable with specified pixelizing width.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("pixel-width",
                                                      "pixel width",
                                                      "Pixel width (the decrease in resolution)",
                                                      1, GIMP_MAX_IMAGE_SIZE, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-pixelize2
   */
  procedure = gimp_procedure_new (plug_in_pixelize2_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-pixelize2");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-pixelize2",
                                     "Simplify image into an array of solid-colored rectangles",
                                     "Pixelize the contents of the specified drawable with specified pixelizing width and height.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("pixel-width",
                                                      "pixel width",
                                                      "Pixel width (the decrease in horizontal resolution)",
                                                      1, GIMP_MAX_IMAGE_SIZE, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("pixel-height",
                                                      "pixel height",
                                                      "Pixel height (the decrease in vertical resolution)",
                                                      1, GIMP_MAX_IMAGE_SIZE, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-plasma
   */
  procedure = gimp_procedure_new (plug_in_plasma_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-plasma");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-plasma",
                                     "Create a random plasma texture",
                                     "This plug-in produces plasma fractal images.",
                                     "Compatibility procedure. Please see 'gegl:plasma' for credits.",
                                     "Compatibility procedure. Please see 'gegl:plasma' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Random seed",
                                                      -1, G_MAXINT, -1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("turbulence",
                                                    "turbulence",
                                                    "The value of the turbulence",
                                                    0.0, 7.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-polar-coords
   */
  procedure = gimp_procedure_new (plug_in_polar_coords_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-polar-coords");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-polar-coords",
                                     "Convert image to or from polar coordinates",
                                     "Remaps and image from rectangular coordinates to polar coordinates or vice versa.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("circle",
                                                    "circle",
                                                    "Circle depth in %",
                                                    0.0, 100.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("angle",
                                                    "angle",
                                                    "Offset angle",
                                                    0.0, 360.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("backwards",
                                                     "backwards",
                                                     "Map backwards",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("inverse",
                                                     "inverse",
                                                     "Map from top",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("polrec",
                                                     "polrec",
                                                     "Polar to rectangular",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-red-eye-removal
   */
  procedure = gimp_procedure_new (plug_in_red_eye_removal_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-red-eye-removal");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-red-eye-removal",
                                     "Remove the red eye effect caused by camera flashes",
                                     "This procedure removes the red eye effect caused by camera flashes by using a percentage based red color threshold. Make a selection containing the eyes, and apply the filter while adjusting the threshold to accurately remove the red eyes.",
                                     "Compatibility procedure. Please see 'gegl:red-eye-removal' for credits.",
                                     "Compatibility procedure. Please see 'gegl:red-eye-removal' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("threshold",
                                                      "threshold",
                                                      "Red eye threshold in percent",
                                                      0, 100, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-randomize-hurl
   */
  procedure = gimp_procedure_new (plug_in_randomize_hurl_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-randomize-hurl");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-randomize-hurl",
                                     "Completely randomize a fraction of pixels",
                                     "This plug-in \"hurls\" randomly-valued pixels onto the selection or image. You may select the percentage of pixels to modify and the number of times to repeat the process.",
                                     "Compatibility procedure. Please see 'gegl:noise-hurl' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-hurl' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rndm-pct",
                                                    "rndm pct",
                                                    "Randomization percentage",
                                                    0.0, 100.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rndm-rcount",
                                                    "rndm rcount",
                                                    "Repeat count",
                                                    1.0, 100.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("randomize",
                                                     "randomize",
                                                     "Use random seed",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Seed value (used only if randomize is FALSE)",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-randomize-pick
   */
  procedure = gimp_procedure_new (plug_in_randomize_pick_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-randomize-pick");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-randomize-pick",
                                     "Randomly interchange some pixels with neighbors",
                                     "This plug-in replaces a pixel with a random adjacent pixel. You may select the percentage of pixels to modify and the number of times to repeat the process.",
                                     "Compatibility procedure. Please see 'gegl:noise-pick' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-pick' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rndm-pct",
                                                    "rndm pct",
                                                    "Randomization percentage",
                                                    1.0, 100.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rndm-rcount",
                                                    "rndm rcount",
                                                    "Repeat count",
                                                    1.0, 100.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("randomize",
                                                     "randomize",
                                                     "Use random seed",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Seed value (used only if randomize is FALSE)",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-randomize-slur
   */
  procedure = gimp_procedure_new (plug_in_randomize_slur_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-randomize-slur");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-randomize-slur",
                                     "Randomly slide some pixels downward (similar to melting",
                                     "This plug-in \"slurs\" (melts like a bunch of icicles) an image. You may select the percentage of pixels to modify and the number of times to repeat the process.",
                                     "Compatibility procedure. Please see 'gegl:noise-slur' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-slur' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rndm-pct",
                                                    "rndm pct",
                                                    "Randomization percentage",
                                                    1.0, 100.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("rndm-rcount",
                                                    "rndm rcount",
                                                    "Repeat count",
                                                    1.0, 100.0, 1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("randomize",
                                                     "randomize",
                                                     "Use random seed",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Seed value (used only if randomize is FALSE)",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-rgb-noise
   */
  procedure = gimp_procedure_new (plug_in_rgb_noise_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-rgb-noise");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-rgb-noise",
                                     "Distort colors by random amounts",
                                     "Add normally distributed (zero mean) random values to image channels. Noise may be additive (uncorrelated) or multiplicative (correlated - also known as speckle noise). For color images color channels may be treated together or independently.",
                                     "Compatibility procedure. Please see 'gegl:noise-rgb' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-rgb' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("independent",
                                                     "independent",
                                                     "Noise in channels independent",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("correlated",
                                                     "correlated",
                                                     "Noise correlated (i.e. multiplicative not additive)",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-1",
                                                    "noise 1",
                                                    "Noise in the first channel (red, gray)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-2",
                                                    "noise 2",
                                                    "Noise in the second channel (green, gray_alpha)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-3",
                                                    "noise 3",
                                                    "Noise in the third channel (blue)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-4",
                                                    "noise 4",
                                                    "Noise in the fourth channel (alpha)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-ripple
   */
  procedure = gimp_procedure_new (plug_in_ripple_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-ripple");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-ripple",
                                     "Displace pixels in a ripple pattern",
                                     "Ripples the pixels of the specified drawable. Each row or column will be displaced a certain number of pixels coinciding with the given wave form.",
                                     "Compatibility procedure. Please see 'gegl:ripple' for credits.",
                                     "Compatibility procedure. Please see 'gegl:ripple' for credits.",
                                     "2018",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("period",
                                                      "period",
                                                      "Period: number of pixels for one wave to complete",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("amplitude",
                                                      "amplitude",
                                                      "Amplitude: maximum displacement of wave",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("orientation",
                                                      "orientation",
                                                      "Orientation { ORIENTATION-HORIZONTAL (0), ORIENTATION-VERTICAL (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("edges",
                                                      "edges",
                                                      "Edges { SMEAR (0), WRAP (1), BLANK (2) }",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("waveform",
                                                      "waveform",
                                                      "Waveform { SAWTOOTH (0), SINE (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("antialias",
                                                     "antialias",
                                                     "Antialias { TRUE, FALSE }",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("tile",
                                                     "tile",
                                                     "Tileable { TRUE, FALSE }",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-rotate
   */
  procedure = gimp_procedure_new (plug_in_rotate_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-rotate");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-rotate",
                                     "Rotates a layer or the whole image by 90, 180 or 270 degrees",
                                     "This plug-in does rotate the active layer or the whole image clockwise by multiples of 90 degrees. When the whole image is chosen, the image is resized if necessary.",
                                     "Sven Neumann <sven@gimp.org>",
                                     "Sven Neumann",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("angle",
                                                      "angle",
                                                      "Angle { 90 (1), 180 (2), 270 (3) } degrees",
                                                      1, 3, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("everything",
                                                     "everything",
                                                     "Rotate the whole image",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-noisify
   */
  procedure = gimp_procedure_new (plug_in_noisify_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-noisify");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-noisify",
                                     "Adds random noise to image channels",
                                     "Add normally distributed random values to image channels. For color images each color channel may be treated together or independently.",
                                     "Compatibility procedure. Please see 'gegl:noise-rgb' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-rgb' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("independent",
                                                     "independent",
                                                     "Noise in channels independent",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-1",
                                                    "noise 1",
                                                    "Noise in the first channel (red, gray)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-2",
                                                    "noise 2",
                                                    "Noise in the second channel (green, gray_alpha)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-3",
                                                    "noise 3",
                                                    "Noise in the third channel (blue)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("noise-4",
                                                    "noise 4",
                                                    "Noise in the fourth channel (alpha)",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-sel-gauss
   */
  procedure = gimp_procedure_new (plug_in_sel_gauss_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-sel-gauss");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-sel-gauss",
                                     "Blur neighboring pixels, but only in low-contrast areas",
                                     "This filter functions similar to the regular gaussian blur filter except that neighbouring pixels that differ more than the given maxdelta parameter will not be blended with. This way with the correct parameters, an image can be smoothed out without losing details. However, this filter can be rather slow.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur-selective' for credits.",
                                     "Compatibility procedure. Please see 'gegl:gaussian-blur-selective' for credits.",
                                     "2099",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("radius",
                                                    "radius",
                                                    "Radius of gaussian blur (in pixels)",
                                                    0.0, G_MAXDOUBLE, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("max-delta",
                                                      "max delta",
                                                      "Maximum delta",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-semiflatten
   */
  procedure = gimp_procedure_new (plug_in_semiflatten_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-semiflatten");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-semiflatten",
                                     "Replace partial transparency with the current background color",
                                     "This plug-in flattens pixels in an RGBA image that aren't completely transparent against the current GIMP background color.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-shift
   */
  procedure = gimp_procedure_new (plug_in_shift_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-shift");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-shift",
                                     "Shift each row or column of pixels by a random amount",
                                     "Shifts the pixels of the specified drawable. Each row or column will be displaced a random value of pixels.",
                                     "Compatibility procedure. Please see 'gegl:shift' for credits.",
                                     "Compatibility procedure. Please see 'gegl:shift' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("shift-amount",
                                                      "shift amount",
                                                      "Shift amount",
                                                      0, 200, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("orientation",
                                                      "orientation",
                                                      "Orientation { ORIENTATION-VERTICAL (0), ORIENTATION-HORIZONTAL (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-sinus
   */
  procedure = gimp_procedure_new (plug_in_sinus_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-sinus");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-sinus",
                                     "Generate complex sinusoidal textures",
                                     "FIXME: sinus help",
                                     "Compatibility procedure. Please see 'gegl:sinus' for credits.",
                                     "Compatibility procedure. Please see 'gegl:sinus' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("xscale",
                                                    "xscale",
                                                    "Scale value for x axis",
                                                    0, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("yscale",
                                                    "yscale",
                                                    "Scale value for y axis",
                                                    0, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("complex",
                                                    "complex",
                                                    "Complexity factor",
                                                    0, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Seed value for random number generator",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("tiling",
                                                     "tiling",
                                                     "If set, the pattern generated will tile",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("perturb",
                                                     "perturb",
                                                     "If set, the pattern is a little more distorted...",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("colors",
                                                      "colors",
                                                      "where to take the colors (0=B&W, 1=fg/bg, 2=col1/col2)",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("col1",
                                                    "col1",
                                                    "fist color (sometimes unused)",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("col2",
                                                    "col2",
                                                    "second color (sometimes unused)",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("alpha1",
                                                    "alpha1",
                                                    "alpha for the first color (used if the drawable has an alpha channel)",
                                                    0, 1, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("alpha2",
                                                    "alpha2",
                                                    "alpha for the second color (used if the drawable has an alpha channel)",
                                                    0, 1, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("blend",
                                                      "blend",
                                                      "0=linear, 1=bilinear, 2=sinusoidal",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("blend-power",
                                                    "blend power",
                                                    "Power used to stretch the blend",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-sobel
   */
  procedure = gimp_procedure_new (plug_in_sobel_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-sobel");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-sobel",
                                     "Specialized direction-dependent edge detection",
                                     "This plug-in calculates the gradient with a sobel operator. The user can specify which direction to use. When both directions are used, the result is the RMS of the two gradients; if only one direction is used, the result either the absolute value of the gradient, or 127 + gradient (if the 'keep sign' switch is on). This way, information about the direction of the gradient is preserved. Resulting images are not autoscaled.\"",
                                     "Compatibility procedure. Please see 'gegl:edge-sobel' for credits.",
                                     "Compatibility procedure. Please see 'gegl:edge-sobel' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("horizontal",
                                                     "horizontal",
                                                     "Sobel in horizontal direction",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("vertical",
                                                     "vertical",
                                                     "Sobel in vertical direction",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("keep-sign",
                                                     "keep sign",
                                                     "Keep sign of result (one direction only)",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-solid-noise
   */
  procedure = gimp_procedure_new (plug_in_solid_noise_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-solid-noise");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-solid-noise",
                                     "Create a random cloud-like texture",
                                     "Generates 2D textures using Perlin's classic solid noise function.",
                                     "Compatibility procedure. Please see 'gegl:noise-solid' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-solid' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("tileable",
                                                     "tileable",
                                                     "Create a tileable output",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("turbulent",
                                                     "turbulent",
                                                     "Make a turbulent noise",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("seed",
                                                      "seed",
                                                      "Random seed",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("detail",
                                                      "detail",
                                                      "Detail level",
                                                      0, 15, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("xsize",
                                                    "xsize",
                                                    "Horizontal texture size",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("ysize",
                                                    "ysize",
                                                    "Vertical texture size",
                                                    -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-spread
   */
  procedure = gimp_procedure_new (plug_in_spread_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-spread");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-spread",
                                     "Move pixels around randomly",
                                     "Spreads the pixels of the specified drawable. Pixels are randomly moved to another location whose distance varies from the original by the horizontal and vertical spread amounts.",
                                     "Compatibility procedure. Please see 'gegl:noise-spread' for credits.",
                                     "Compatibility procedure. Please see 'gegl:noise-spread' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("spread-amount-x",
                                                    "spread amount x",
                                                    "Horizontal spread amount",
                                                    0, 200, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("spread-amount-y",
                                                    "spread amount y",
                                                    "Vertical spread amount",
                                                    0, 200, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-threshold-alpha
   */
  procedure = gimp_procedure_new (plug_in_threshold_alpha_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-threshold-alpha");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-threshold-alpha",
                                     "Make transparency all-or-nothing",
                                     "Make transparency all-or-nothing.",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("threshold",
                                                      "threshold",
                                                      "Threshold",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-unsharp-mask
   */
  procedure = gimp_procedure_new (plug_in_unsharp_mask_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-unsharp-mask");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-unsharp-mask",
                                     "The most widely useful method for sharpening an image",
                                     "The unsharp mask is a sharpening filter that works by comparing using the difference of the image and a blurred version of the image. It is commonly used on photographic images, and is provides a much more pleasing result than the standard sharpen filter.",
                                     "Compatibility procedure. Please see 'gegl:unsharp-mask' for credits.",
                                     "Compatibility procedure. Please see 'gegl:unsharp-mask' for credits.",
                                     "2018",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("radius",
                                                    "radius",
                                                    "Radius of gaussian blur",
                                                    0.0, 300.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amount",
                                                    "amount",
                                                    "Strength of effect",
                                                    0.0, 300.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("threshold",
                                                      "threshold",
                                                      "Threshold",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-video
   */
  procedure = gimp_procedure_new (plug_in_video_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-video");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-video",
                                     "Simulate distortion produced by a fuzzy or low-res monitor",
                                     "This function simulates the degradation of being on an old low-dotpitch RGB video monitor to the specified drawable.",
                                     "Compatibility procedure. Please see 'gegl:video-degradation' for credits.",
                                     "Compatibility procedure. Please see 'gegl:video-degradation' for credits.",
                                     "2014",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("pattern-number",
                                                      "pattern number",
                                                      "Type of RGB pattern to use",
                                                      0, 8, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("additive",
                                                     "additive",
                                                     "Whether the function adds the result to the original image",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("rotated",
                                                     "rotated",
                                                     "Whether to rotate the RGB pattern by ninety degrees",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-vinvert
   */
  procedure = gimp_procedure_new (plug_in_vinvert_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-vinvert");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-vinvert",
                                     "Invert the brightness of each pixel",
                                     "This function takes an indexed/RGB image and inverts its 'value' in HSV space. The upshot of this is that the color and saturation at any given point remains the same, but its brightness is effectively inverted. Quite strange. Sometimes produces unpleasant color artifacts on images from lossy sources (ie. JPEG).",
                                     "Spencer Kimball & Peter Mattis",
                                     "Spencer Kimball & Peter Mattis",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-vpropagate
   */
  procedure = gimp_procedure_new (plug_in_vpropagate_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-vpropagate");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-vpropagate",
                                     "Propagate certain colors to neighboring pixels",
                                     "Propagate values of the layer.",
                                     "Compatibility procedure. Please see 'gegl:value-propagate' for credits.",
                                     "Compatibility procedure. Please see 'gegl:value-propagate' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("propagate-mode",
                                                      "propagate mode",
                                                      "Propagate mode { 0:white, 1:black, 2:middle value 3:foreground to peak, 4:foreground, 5:background, 6:opaque, 7:transparent }",
                                                      0, 7, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("propagating-channel",
                                                      "propagating channel",
                                                      "Channels which values are propagated",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("propagating-rate",
                                                    "propagating rate",
                                                    "Propagating rate",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("direction-mask",
                                                      "direction mask",
                                                      "Direction mask",
                                                      0, 15, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("lower-limit",
                                                      "lower limit",
                                                      "Lower limit",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("upper-limit",
                                                      "upper limit",
                                                      "Upper limit",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-dilate
   */
  procedure = gimp_procedure_new (plug_in_dilate_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-dilate");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-dilate",
                                     "Grow lighter areas of the image",
                                     "Dilate image.",
                                     "Compatibility procedure. Please see 'gegl:value-propagate' for credits.",
                                     "Compatibility procedure. Please see 'gegl:value-propagate' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("propagate-mode",
                                                      "propagate mode",
                                                      "Propagate mode { 0:white, 1:black, 2:middle value 3:foreground to peak, 4:foreground, 5:background, 6:opaque, 7:transparent }",
                                                      0, 7, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("propagating-channel",
                                                      "propagating channel",
                                                      "Channels which values are propagated",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("propagating-rate",
                                                    "propagating rate",
                                                    "Propagating rate",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("direction-mask",
                                                      "direction mask",
                                                      "Direction mask",
                                                      0, 15, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("lower-limit",
                                                      "lower limit",
                                                      "Lower limit",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("upper-limit",
                                                      "upper limit",
                                                      "Upper limit",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-erode
   */
  procedure = gimp_procedure_new (plug_in_erode_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-erode");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-erode",
                                     "Shrink lighter areas of the image",
                                     "Erode image.",
                                     "Compatibility procedure. Please see 'gegl:value-propagate' for credits.",
                                     "Compatibility procedure. Please see 'gegl:value-propagate' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("propagate-mode",
                                                      "propagate mode",
                                                      "Propagate mode { 0:white, 1:black, 2:middle value 3:foreground to peak, 4:foreground, 5:background, 6:opaque, 7:transparent }",
                                                      0, 7, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("propagating-channel",
                                                      "propagating channel",
                                                      "Channels which values are propagated",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("propagating-rate",
                                                    "propagating rate",
                                                    "Propagating rate",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("direction-mask",
                                                      "direction mask",
                                                      "Direction mask",
                                                      0, 15, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("lower-limit",
                                                      "lower limit",
                                                      "Lower limit",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("upper-limit",
                                                      "upper limit",
                                                      "Upper limit",
                                                      0, 255, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-waves
   */
  procedure = gimp_procedure_new (plug_in_waves_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-waves");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-waves",
                                     "Distort the image with waves",
                                     "Distort the image with waves.",
                                     "Compatibility procedure. Please see 'gegl:waves' for credits.",
                                     "Compatibility procedure. Please see 'gegl:waves' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("amplitude",
                                                    "amplitude",
                                                    "The Amplitude of the Waves",
                                                    0, 101, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("phase",
                                                    "phase",
                                                    "The Phase of the Waves",
                                                    -360, 360, -360,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("wavelength",
                                                    "wavelength",
                                                    "The Wavelength of the Waves",
                                                    0.1, 50, 0.1,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("type",
                                                     "type",
                                                     "Type of waves: { 0 = smeared, 1 = black }",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("reflective",
                                                     "reflective",
                                                     "Use Reflection (not implemented)",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-whirl-pinch
   */
  procedure = gimp_procedure_new (plug_in_whirl_pinch_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-whirl-pinch");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-whirl-pinch",
                                     "Distort an image by whirling and pinching",
                                     "Distorts the image by whirling and pinching, which are two common center-based, circular distortions. Whirling is like projecting the image onto the surface of water in a toilet and flushing. Pinching is similar to projecting the image onto an elastic surface and pressing or pulling on the center of the surface.",
                                     "Compatibility procedure. Please see 'gegl:whirl-pinch' for credits.",
                                     "Compatibility procedure. Please see 'gegl:whirl-pinch' for credits.",
                                     "2013",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("whirl",
                                                    "whirl",
                                                    "Whirl angle (degrees)",
                                                    -720, 720, -720,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("pinch",
                                                    "pinch",
                                                    "Pinch amount",
                                                    -1, 1, -1,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("radius",
                                                    "radius",
                                                    "Radius (1.0 is the largest circle that fits in the image, and 2.0 goes all the way to the corners)",
                                                    0, 2, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-plug-in-wind
   */
  procedure = gimp_procedure_new (plug_in_wind_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "plug-in-wind");
  gimp_procedure_set_static_strings (procedure,
                                     "plug-in-wind",
                                     "Smear image to give windblown effect",
                                     "Renders a wind effect.",
                                     "Compatibility procedure. Please see 'gegl:wind' for credits.",
                                     "Compatibility procedure. Please see 'gegl:wind' for credits.",
                                     "2015",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("run-mode",
                                                  "run mode",
                                                  "The run mode",
                                                  GIMP_TYPE_RUN_MODE,
                                                  GIMP_RUN_INTERACTIVE,
                                                  GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_image_id ("image",
                                                         "image",
                                                         "Input image (unused)",
                                                         pdb->gimp, FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_drawable_id ("drawable",
                                                            "drawable",
                                                            "Input drawable",
                                                            pdb->gimp, FALSE,
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("threshold",
                                                      "threshold",
                                                      "Controls where blending will be done",
                                                      0, 50, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("direction",
                                                      "direction",
                                                      "Wind direction { 0:left, 1:right, 2:top, 3:bottom }",
                                                      0, 3, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("strength",
                                                      "strength",
                                                      "Controls the extent of the blending",
                                                      1, 100, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("algorithm",
                                                      "algorithm",
                                                      "Algorithm { WIND (0), BLAST (1) }",
                                                      0, 1, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("edge",
                                                      "edge",
                                                      "Affected edge { BOTH (0), LEADING (1), TRAILING (2) }",
                                                      0, 2, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);
}
