[gimp/goat-invasion] app: add GimpOperationShrink which does "shrink selection"



commit 81f272aea790033a1b42bdb3b7936a2b4904ba3d
Author: Michael Natterer <mitch gimp org>
Date:   Sun Mar 25 22:31:22 2012 +0200

    app: add GimpOperationShrink which does "shrink selection"
    
    but it's horribly slow, so keep the old code around for now and make
    the new one depend on use_gegl.

 app/core/gimpchannel.c         |   36 +++-
 app/gegl/Makefile.am           |    6 +-
 app/gegl/gimp-gegl-nodes.c     |    2 +-
 app/gegl/gimp-gegl-types.h     |    6 +-
 app/gegl/gimp-gegl.c           |    6 +-
 app/gegl/gimpoperationshrink.c |  426 ++++++++++++++++++++++++++++++++++++++++
 app/gegl/gimpoperationshrink.h |   56 ++++++
 7 files changed, 523 insertions(+), 15 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 64663d8..c254514 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -40,6 +40,7 @@
 #include "gegl/gimp-gegl-utils.h"
 
 #include "gimp.h"
+#include "gimp-apply-operation.h"
 #include "gimp-utils.h"
 #include "gimpboundary.h"
 #include "gimpcontainer.h"
@@ -1539,8 +1540,7 @@ gimp_channel_real_shrink (GimpChannel *channel,
                           gboolean     edge_lock,
                           gboolean     push_undo)
 {
-  PixelRegion bPR;
-  gint        x1, y1, x2, y2;
+  gint      x1, y1, x2, y2;
 
   if (radius_x == 0 && radius_y == 0)
     return;
@@ -1575,11 +1575,35 @@ gimp_channel_real_shrink (GimpChannel *channel,
   else
     gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
 
-  pixel_region_init (&bPR,
-                     gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
-                     x1, y1, (x2 - x1), (y2 - y1), TRUE);
+  if (gimp_use_gegl (gimp_item_get_image (GIMP_ITEM (channel))->gimp))
+    {
+      GeglNode *shrink;
+
+      shrink = gegl_node_new_child (NULL,
+                                    "operation", "gimp:shrink",
+                                    "radius-x",  radius_x,
+                                    "radius-y",  radius_y,
+                                    "edge-lock", edge_lock,
+                                    NULL);
+
+      gimp_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+                            NULL, NULL,
+                            shrink, TRUE,
+                            gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+                            NULL);
+
+      g_object_unref (shrink);
+    }
+  else
+    {
+      PixelRegion bPR;
 
-  thin_region (&bPR, radius_x, radius_y, edge_lock);
+      pixel_region_init (&bPR,
+                         gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
+                         x1, y1, (x2 - x1), (y2 - y1), TRUE);
+
+      thin_region (&bPR, radius_x, radius_y, edge_lock);
+    }
 
   channel->bounds_known = FALSE;
 
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index afe483c..84f9104 100644
--- a/app/gegl/Makefile.am
+++ b/app/gegl/Makefile.am
@@ -52,8 +52,12 @@ libappgegl_a_sources = \
 	gimpoperationcagecoefcalc.h		\
 	gimpoperationcagetransform.c		\
 	gimpoperationcagetransform.h		\
+	gimpoperationequalize.c			\
+	gimpoperationequalize.h			\
 	gimpoperationsetalpha.c			\
 	gimpoperationsetalpha.h			\
+	gimpoperationshrink.c			\
+	gimpoperationshrink.h			\
 	\
 	gimpoperationpointfilter.c		\
 	gimpoperationpointfilter.h		\
@@ -67,8 +71,6 @@ libappgegl_a_sources = \
 	gimpoperationcurves.h			\
 	gimpoperationdesaturate.c		\
 	gimpoperationdesaturate.h		\
-	gimpoperationequalize.c			\
-	gimpoperationequalize.h			\
 	gimpoperationhuesaturation.c		\
 	gimpoperationhuesaturation.h		\
 	gimpoperationlevels.c			\
diff --git a/app/gegl/gimp-gegl-nodes.c b/app/gegl/gimp-gegl-nodes.c
index dc00c43..707cb43 100644
--- a/app/gegl/gimp-gegl-nodes.c
+++ b/app/gegl/gimp-gegl-nodes.c
@@ -189,7 +189,7 @@ gimp_gegl_create_apply_buffer_node (GeglBuffer           *buffer,
     gegl_node_connect_to (mask_source,   "output",
                           opacity_node,  "aux");
 
-  mode_node = gegl_node_new_child (node, NULL, NULL);
+  mode_node = gegl_node_new_child (node, "gegl:nop", NULL);
   gimp_gegl_node_set_layer_mode (node, mode, FALSE);
 
   gegl_node_connect_to (opacity_node, "output",
diff --git a/app/gegl/gimp-gegl-types.h b/app/gegl/gimp-gegl-types.h
index 99eda62..12c3ea3 100644
--- a/app/gegl/gimp-gegl-types.h
+++ b/app/gegl/gimp-gegl-types.h
@@ -27,12 +27,11 @@
 
 /*  operations  */
 
-typedef struct _GimpOperationTileSink           GimpOperationTileSink;
-typedef struct _GimpOperationTileSource         GimpOperationTileSource;
-
 typedef struct _GimpOperationCageCoefCalc       GimpOperationCageCoefCalc;
 typedef struct _GimpOperationCageTransform      GimpOperationCageTransform;
+typedef struct _GimpOperationEqualize           GimpOperationEqualize;
 typedef struct _GimpOperationSetAlpha           GimpOperationSetAlpha;
+typedef struct _GimpOperationShrink             GimpOperationShrink;
 
 typedef struct _GimpOperationPointFilter        GimpOperationPointFilter;
 typedef struct _GimpOperationBrightnessContrast GimpOperationBrightnessContrast;
@@ -40,7 +39,6 @@ typedef struct _GimpOperationColorBalance       GimpOperationColorBalance;
 typedef struct _GimpOperationColorize           GimpOperationColorize;
 typedef struct _GimpOperationCurves             GimpOperationCurves;
 typedef struct _GimpOperationDesaturate         GimpOperationDesaturate;
-typedef struct _GimpOperationEqualize           GimpOperationEqualize;
 typedef struct _GimpOperationHueSaturation      GimpOperationHueSaturation;
 typedef struct _GimpOperationLevels             GimpOperationLevels;
 typedef struct _GimpOperationPosterize          GimpOperationPosterize;
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index 61a6c94..2254abf 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -34,14 +34,15 @@
 
 #include "gimpoperationcagecoefcalc.h"
 #include "gimpoperationcagetransform.h"
+#include "gimpoperationequalize.h"
 #include "gimpoperationsetalpha.h"
+#include "gimpoperationshrink.h"
 
 #include "gimpoperationbrightnesscontrast.h"
 #include "gimpoperationcolorbalance.h"
 #include "gimpoperationcolorize.h"
 #include "gimpoperationcurves.h"
 #include "gimpoperationdesaturate.h"
-#include "gimpoperationequalize.h"
 #include "gimpoperationhuesaturation.h"
 #include "gimpoperationlevels.h"
 #include "gimpoperationposterize.h"
@@ -121,14 +122,15 @@ gimp_gegl_init (Gimp *gimp)
 
   g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_COEF_CALC);
   g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_TRANSFORM);
+  g_type_class_ref (GIMP_TYPE_OPERATION_EQUALIZE);
   g_type_class_ref (GIMP_TYPE_OPERATION_SET_ALPHA);
+  g_type_class_ref (GIMP_TYPE_OPERATION_SHRINK);
 
   g_type_class_ref (GIMP_TYPE_OPERATION_BRIGHTNESS_CONTRAST);
   g_type_class_ref (GIMP_TYPE_OPERATION_COLOR_BALANCE);
   g_type_class_ref (GIMP_TYPE_OPERATION_COLORIZE);
   g_type_class_ref (GIMP_TYPE_OPERATION_CURVES);
   g_type_class_ref (GIMP_TYPE_OPERATION_DESATURATE);
-  g_type_class_ref (GIMP_TYPE_OPERATION_EQUALIZE);
   g_type_class_ref (GIMP_TYPE_OPERATION_HUE_SATURATION);
   g_type_class_ref (GIMP_TYPE_OPERATION_LEVELS);
   g_type_class_ref (GIMP_TYPE_OPERATION_POSTERIZE);
diff --git a/app/gegl/gimpoperationshrink.c b/app/gegl/gimpoperationshrink.c
new file mode 100644
index 0000000..8fa9940
--- /dev/null
+++ b/app/gegl/gimpoperationshrink.c
@@ -0,0 +1,426 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationshrink.c
+ * Copyright (C) 2012 Michael Natterer <mitch gimp org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpmath/gimpmath.h"
+
+#include "gimp-gegl-types.h"
+
+#include "gimp-gegl-utils.h"
+#include "gimpoperationshrink.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_RADIUS_X,
+  PROP_RADIUS_Y,
+  PROP_EDGE_LOCK
+};
+
+
+static void     gimp_operation_shrink_get_property (GObject      *object,
+                                                    guint         property_id,
+                                                    GValue       *value,
+                                                    GParamSpec   *pspec);
+static void     gimp_operation_shrink_set_property (GObject      *object,
+                                                    guint         property_id,
+                                                    const GValue *value,
+                                                    GParamSpec   *pspec);
+
+static GeglRectangle
+gimp_operation_shrink_get_required_for_output (GeglOperation       *self,
+                                               const gchar         *input_pad,
+                                               const GeglRectangle *roi);
+static GeglRectangle
+      gimp_operation_shrink_get_cached_region (GeglOperation       *self,
+                                               const GeglRectangle *roi);
+static void     gimp_operation_shrink_prepare (GeglOperation       *operation);
+static gboolean gimp_operation_shrink_process (GeglOperation       *operation,
+                                               GeglBuffer          *input,
+                                               GeglBuffer          *output,
+                                               const GeglRectangle *roi,
+                                               gint                 level);
+
+
+G_DEFINE_TYPE (GimpOperationShrink, gimp_operation_shrink,
+               GEGL_TYPE_OPERATION_FILTER)
+
+#define parent_class gimp_operation_shrink_parent_class
+
+
+static void
+gimp_operation_shrink_class_init (GimpOperationShrinkClass *klass)
+{
+  GObjectClass             *object_class    = G_OBJECT_CLASS (klass);
+  GeglOperationClass       *operation_class = GEGL_OPERATION_CLASS (klass);
+  GeglOperationFilterClass *filter_class    = GEGL_OPERATION_FILTER_CLASS (klass);
+
+  object_class->set_property   = gimp_operation_shrink_set_property;
+  object_class->get_property   = gimp_operation_shrink_get_property;
+
+  operation_class->name        = "gimp:shrink";
+  operation_class->categories  = "gimp";
+  operation_class->description = "GIMP Shrink operation";
+
+  operation_class->prepare                 = gimp_operation_shrink_prepare;
+  operation_class->get_required_for_output = gimp_operation_shrink_get_required_for_output;
+  operation_class->get_cached_region       = gimp_operation_shrink_get_cached_region;
+
+  filter_class->process        = gimp_operation_shrink_process;
+
+  g_object_class_install_property (object_class, PROP_RADIUS_X,
+                                   g_param_spec_int ("radius-x",
+                                                     "Radius X",
+                                                     "Shrink radius in X diection",
+                                                     1, 2342, 1,
+                                                     G_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT));
+
+  g_object_class_install_property (object_class, PROP_RADIUS_Y,
+                                   g_param_spec_int ("radius-y",
+                                                     "Radius Y",
+                                                     "Shrink radius in Y diection",
+                                                     1, 2342, 1,
+                                                     G_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT));
+
+  g_object_class_install_property (object_class, PROP_EDGE_LOCK,
+                                   g_param_spec_boolean ("edge-lock",
+                                                         "Edge Lock",
+                                                         "Shrink from border",
+                                                         FALSE,
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
+}
+
+static void
+gimp_operation_shrink_init (GimpOperationShrink *self)
+{
+}
+
+static void
+gimp_operation_shrink_get_property (GObject    *object,
+                                    guint       property_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+ GimpOperationShrink *self = GIMP_OPERATION_SHRINK (object);
+
+  switch (property_id)
+    {
+    case PROP_RADIUS_X:
+      g_value_set_int (value, self->radius_x);
+      break;
+
+    case PROP_RADIUS_Y:
+      g_value_set_int (value, self->radius_y);
+      break;
+
+    case PROP_EDGE_LOCK:
+      g_value_set_boolean (value, self->edge_lock);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_operation_shrink_set_property (GObject      *object,
+                                    guint         property_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  GimpOperationShrink *self = GIMP_OPERATION_SHRINK (object);
+
+  switch (property_id)
+    {
+    case PROP_RADIUS_X:
+      self->radius_x = g_value_get_int (value);
+      break;
+
+    case PROP_RADIUS_Y:
+      self->radius_y = g_value_get_int (value);
+      break;
+
+    case PROP_EDGE_LOCK:
+      self->edge_lock = g_value_get_boolean (value);
+      break;
+
+   default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_operation_shrink_prepare (GeglOperation *operation)
+{
+  gegl_operation_set_format (operation, "input",  babl_format ("Y u8"));
+  gegl_operation_set_format (operation, "output", babl_format ("Y u8"));
+}
+
+static GeglRectangle
+gimp_operation_shrink_get_required_for_output (GeglOperation       *self,
+                                               const gchar         *input_pad,
+                                               const GeglRectangle *roi)
+{
+  return *gegl_operation_source_get_bounding_box (self, "input");
+}
+
+static GeglRectangle
+gimp_operation_shrink_get_cached_region (GeglOperation       *self,
+                                         const GeglRectangle *roi)
+{
+  return *gegl_operation_source_get_bounding_box (self, "input");
+}
+
+static void
+compute_border (gint16  *circ,
+                guint16  xradius,
+                guint16  yradius)
+{
+  gint32  i;
+  gint32  diameter = xradius * 2 + 1;
+  gdouble tmp;
+
+  for (i = 0; i < diameter; i++)
+    {
+      if (i > xradius)
+        tmp = (i - xradius) - 0.5;
+      else if (i < xradius)
+        tmp = (xradius - i) - 0.5;
+      else
+        tmp = 0.0;
+
+      circ[i] = RINT (yradius /
+                      (gdouble) xradius * sqrt (SQR (xradius) - SQR (tmp)));
+    }
+}
+
+static inline void
+rotate_pointers (guchar  **p,
+                 guint32   n)
+{
+  guint32  i;
+  guchar  *tmp;
+
+  tmp = p[0];
+
+  for (i = 0; i < n - 1; i++)
+    p[i] = p[i + 1];
+
+  p[i] = tmp;
+}
+
+static gboolean
+gimp_operation_shrink_process (GeglOperation       *operation,
+                               GeglBuffer          *input,
+                               GeglBuffer          *output,
+                               const GeglRectangle *roi,
+                               gint                 level)
+{
+  GimpOperationShrink *self = GIMP_OPERATION_SHRINK (operation);
+  /*
+     pretty much the same as fatten_region only different
+     blame all bugs in this function on jaycox gimp org
+  */
+  /* If edge_lock is true  we assume that pixels outside the region
+     we are passed are identical to the edge pixels.
+     If edge_lock is false, we assume that pixels outside the region are 0
+  */
+  gint32    i, j, x, y;
+  guchar  **buf;  /* caches the the region's pixels */
+  guchar   *out;  /* holds the new scan line we are computing */
+  guchar  **max;  /* caches the smallest values for each column */
+  gint16   *circ; /* holds the y coords of the filter's mask */
+  gint16    last_max, last_index;
+
+  guchar   *buffer;
+  gint      buffer_size;
+
+  max = g_new (guchar *, roi->width + 2 * self->radius_x);
+  buf = g_new (guchar *, self->radius_y + 1);
+
+  for (i = 0; i < self->radius_y + 1; i++)
+    buf[i] = g_new (guchar, roi->width);
+
+  buffer_size = (roi->width+ 2 * self->radius_x + 1) * (self->radius_y + 1);
+  buffer = g_new (guchar, buffer_size);
+
+  if (self->edge_lock)
+    memset(buffer, 255, buffer_size);
+  else
+    memset(buffer, 0, buffer_size);
+
+  for (i = 0; i < roi->width + 2 * self->radius_x; i++)
+    {
+      if (i < self->radius_x)
+        {
+          if (self->edge_lock)
+            max[i] = buffer;
+          else
+            max[i] = &buffer[(self->radius_x + 1) * (roi->width + self->radius_x)];
+        }
+      else if (i < roi->width + self->radius_x)
+        {
+          max[i] = &buffer[(self->radius_y + 1) * (i - self->radius_x)];
+        }
+      else
+        {
+          if (self->edge_lock)
+            max[i] = &buffer[(self->radius_x + 1) * (roi->width + self->radius_x - 1)];
+          else
+            max[i] = &buffer[(self->radius_x + 1) * (roi->width + self->radius_x)];
+        }
+    }
+
+  if (! self->edge_lock)
+    for (j = 0 ; j < self->radius_x + 1; j++)
+      max[0][j] = 0;
+
+  /* offset the max pointer by xradius so the range of the array
+     is [-xradius] to [region->w + xradius] */
+  max += self->radius_x;
+
+  out = g_new (guchar, roi->width);
+
+  circ = g_new (gint16, 2 * self->radius_x + 1);
+  compute_border (circ, self->radius_x, self->radius_y);
+
+ /* offset the circ pointer by xradius so the range of the array
+    is [-xradius] to [xradius] */
+  circ += self->radius_x;
+
+  for (i = 0; i < self->radius_y && i < roi->height; i++) /* load top of image */
+    gegl_buffer_get (input,
+                     GIMP_GEGL_RECT (roi->x, roi->y + i,
+                                     roi->width, 1),
+                     1.0, NULL, buf[i + 1], GEGL_AUTO_ROWSTRIDE);
+
+  if (self->edge_lock)
+    memcpy (buf[0], buf[1], roi->width);
+  else
+    memset (buf[0], 0, roi->width);
+
+
+  for (x = 0; x < roi->width; x++) /* set up max for top of image */
+    {
+      max[x][0] = buf[0][x];
+
+      for (j = 1; j < self->radius_y + 1; j++)
+        max[x][j] = MIN(buf[j][x], max[x][j-1]);
+    }
+
+  for (y = 0; y < roi->height; y++)
+    {
+      rotate_pointers (buf, self->radius_y + 1);
+
+      if (y < roi->height - self->radius_y)
+        gegl_buffer_get (input,
+                         GIMP_GEGL_RECT (roi->x,  roi->y + y + self->radius_y,
+                                         roi->width, 1),
+                         1.0, NULL, buf[self->radius_y], GEGL_AUTO_ROWSTRIDE);
+      else if (self->edge_lock)
+        memcpy (buf[self->radius_y], buf[self->radius_y - 1], roi->width);
+      else
+        memset (buf[self->radius_y], 0, roi->width);
+
+      for (x = 0 ; x < roi->width; x++) /* update max array */
+        {
+          for (i = self->radius_y; i > 0; i--)
+            max[x][i] = MIN (MIN (max[x][i - 1], buf[i - 1][x]), buf[i][x]);
+
+          max[x][0] = buf[0][x];
+        }
+
+      last_max =  max[0][circ[-1]];
+      last_index = 0;
+
+      for (x = 0 ; x < roi->width; x++) /* render scan line */
+        {
+          last_index--;
+
+          if (last_index >= 0)
+            {
+              if (last_max == 0)
+                {
+                  out[x] = 0;
+                }
+              else
+                {
+                  last_max = 255;
+
+                  for (i = self->radius_x; i >= 0; i--)
+                    if (last_max > max[x + i][circ[i]])
+                      {
+                        last_max = max[x + i][circ[i]];
+                        last_index = i;
+                      }
+
+                  out[x] = last_max;
+                }
+            }
+          else
+            {
+              last_index = self->radius_x;
+              last_max = max[x + self->radius_y][circ[self->radius_x]];
+
+              for (i = self->radius_x - 1; i >= -self->radius_x; i--)
+                if (last_max > max[x + i][circ[i]])
+                  {
+                    last_max = max[x + i][circ[i]];
+                    last_index = i;
+                  }
+
+              out[x] = last_max;
+            }
+        }
+
+      gegl_buffer_set (output,
+                       GIMP_GEGL_RECT (roi->x, roi->y + y,
+                                       roi->width, 1),
+                       1.0, NULL, out, GEGL_AUTO_ROWSTRIDE);
+    }
+
+  /* undo the offsets to the pointers so we can free the malloced memmory */
+  circ -= self->radius_x;
+  max -= self->radius_x;
+
+  /* free the memmory */
+  g_free (circ);
+  g_free (buffer);
+  g_free (max);
+
+  for (i = 0; i < self->radius_x + 1; i++)
+    g_free (buf[i]);
+
+  g_free (buf);
+  g_free (out);
+
+  return TRUE;
+}
diff --git a/app/gegl/gimpoperationshrink.h b/app/gegl/gimpoperationshrink.h
new file mode 100644
index 0000000..b7ccfac
--- /dev/null
+++ b/app/gegl/gimpoperationshrink.h
@@ -0,0 +1,56 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationshrink.h
+ * Copyright (C) 2012 Michael Natterer <mitch gimp org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_OPERATION_SHRINK_H__
+#define __GIMP_OPERATION_SHRINK_H__
+
+
+#include <gegl-plugin.h>
+
+
+#define GIMP_TYPE_OPERATION_SHRINK            (gimp_operation_shrink_get_type ())
+#define GIMP_OPERATION_SHRINK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_SHRINK, GimpOperationShrink))
+#define GIMP_OPERATION_SHRINK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GIMP_TYPE_OPERATION_SHRINK, GimpOperationShrinkClass))
+#define GIMP_IS_OPERATION_SHRINK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_SHRINK))
+#define GIMP_IS_OPERATION_SHRINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GIMP_TYPE_OPERATION_SHRINK))
+#define GIMP_OPERATION_SHRINK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GIMP_TYPE_OPERATION_SHRINK, GimpOperationShrinkClass))
+
+
+typedef struct _GimpOperationShrinkClass GimpOperationShrinkClass;
+
+struct _GimpOperationShrink
+{
+  GeglOperationFilter  parent_instance;
+
+  gint                 radius_x;
+  gint                 radius_y;
+  gboolean             edge_lock;
+};
+
+struct _GimpOperationShrinkClass
+{
+  GeglOperationFilterClass  parent_class;
+};
+
+
+GType   gimp_operation_shrink_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_OPERATION_SHRINK_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]