[gimp/goat-invasion: 252/412] app: replace fatten_region() by GimpOperationGrow



commit 83e75a73feee0e05080daf081b86583f559d52b0
Author: Michael Natterer <mitch gimp org>
Date:   Sun Mar 25 23:52:25 2012 +0200

    app: replace fatten_region() by GimpOperationGrow

 app/core/gimpchannel.c        |   23 ++-
 app/gegl/Makefile.am          |    2 +
 app/gegl/gimp-gegl-types.h    |    1 +
 app/gegl/gimp-gegl.c          |    2 +
 app/gegl/gimpoperationgrow.c  |  384 +++++++++++++++++++++++++++++++++++++++++
 app/gegl/gimpoperationgrow.h  |   55 ++++++
 app/paint-funcs/paint-funcs.c |  174 -------------------
 app/paint-funcs/paint-funcs.h |    4 -
 8 files changed, 459 insertions(+), 186 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 623e90c..f2b27bb 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -1472,8 +1472,8 @@ gimp_channel_real_grow (GimpChannel *channel,
                         gint         radius_y,
                         gboolean     push_undo)
 {
-  PixelRegion bPR;
-  gint        x1, y1, x2, y2;
+  GeglNode *grow;
+  gint      x1, y1, x2, y2;
 
   if (radius_x == 0 && radius_y == 0)
     return;
@@ -1519,12 +1519,19 @@ gimp_channel_real_grow (GimpChannel *channel,
   else
     gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
 
-  /*  need full extents for grow, not! */
-  pixel_region_init (&bPR,
-                     gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
-                     x1, y1, (x2 - x1), (y2 - y1), TRUE);
+  grow = gegl_node_new_child (NULL,
+                              "operation", "gimp:grow",
+                              "radius-x",  radius_x,
+                              "radius-y",  radius_y,
+                              NULL);
+
+  gimp_apply_operation (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+                        NULL, NULL,
+                        grow,
+                        gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
+                        GIMP_GEGL_RECT (x1, y1, x2 - x1, y2 - y1));
 
-  fatten_region (&bPR, radius_x, radius_y);
+  g_object_unref (grow);
 
   channel->bounds_known = FALSE;
 
@@ -1587,7 +1594,7 @@ gimp_channel_real_shrink (GimpChannel *channel,
                         NULL, NULL,
                         shrink,
                         gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
-                        NULL);
+                        GIMP_GEGL_RECT (x1, y1, x2 - x1, y2 - y1));
 
   g_object_unref (shrink);
 
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index 84f9104..645c6ed 100644
--- a/app/gegl/Makefile.am
+++ b/app/gegl/Makefile.am
@@ -54,6 +54,8 @@ libappgegl_a_sources = \
 	gimpoperationcagetransform.h		\
 	gimpoperationequalize.c			\
 	gimpoperationequalize.h			\
+	gimpoperationgrow.c			\
+	gimpoperationgrow.h			\
 	gimpoperationsetalpha.c			\
 	gimpoperationsetalpha.h			\
 	gimpoperationshrink.c			\
diff --git a/app/gegl/gimp-gegl-types.h b/app/gegl/gimp-gegl-types.h
index 12c3ea3..d2aff4b 100644
--- a/app/gegl/gimp-gegl-types.h
+++ b/app/gegl/gimp-gegl-types.h
@@ -30,6 +30,7 @@
 typedef struct _GimpOperationCageCoefCalc       GimpOperationCageCoefCalc;
 typedef struct _GimpOperationCageTransform      GimpOperationCageTransform;
 typedef struct _GimpOperationEqualize           GimpOperationEqualize;
+typedef struct _GimpOperationGrow               GimpOperationGrow;
 typedef struct _GimpOperationSetAlpha           GimpOperationSetAlpha;
 typedef struct _GimpOperationShrink             GimpOperationShrink;
 
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index 2254abf..6e43360 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -35,6 +35,7 @@
 #include "gimpoperationcagecoefcalc.h"
 #include "gimpoperationcagetransform.h"
 #include "gimpoperationequalize.h"
+#include "gimpoperationgrow.h"
 #include "gimpoperationsetalpha.h"
 #include "gimpoperationshrink.h"
 
@@ -123,6 +124,7 @@ 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_GROW);
   g_type_class_ref (GIMP_TYPE_OPERATION_SET_ALPHA);
   g_type_class_ref (GIMP_TYPE_OPERATION_SHRINK);
 
diff --git a/app/gegl/gimpoperationgrow.c b/app/gegl/gimpoperationgrow.c
new file mode 100644
index 0000000..21208b4
--- /dev/null
+++ b/app/gegl/gimpoperationgrow.c
@@ -0,0 +1,384 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationgrow.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 "gimpoperationgrow.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_RADIUS_X,
+  PROP_RADIUS_Y
+};
+
+
+static void     gimp_operation_grow_get_property (GObject      *object,
+                                                  guint         property_id,
+                                                  GValue       *value,
+                                                  GParamSpec   *pspec);
+static void     gimp_operation_grow_set_property (GObject      *object,
+                                                  guint         property_id,
+                                                  const GValue *value,
+                                                  GParamSpec   *pspec);
+
+static GeglRectangle
+gimp_operation_grow_get_required_for_output (GeglOperation       *self,
+                                             const gchar         *input_pad,
+                                             const GeglRectangle *roi);
+static GeglRectangle
+      gimp_operation_grow_get_cached_region (GeglOperation       *self,
+                                             const GeglRectangle *roi);
+static void     gimp_operation_grow_prepare (GeglOperation       *operation);
+static gboolean gimp_operation_grow_process (GeglOperation       *operation,
+                                             GeglBuffer          *input,
+                                             GeglBuffer          *output,
+                                             const GeglRectangle *roi,
+                                             gint                 level);
+
+
+G_DEFINE_TYPE (GimpOperationGrow, gimp_operation_grow,
+               GEGL_TYPE_OPERATION_FILTER)
+
+#define parent_class gimp_operation_grow_parent_class
+
+
+static void
+gimp_operation_grow_class_init (GimpOperationGrowClass *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_grow_set_property;
+  object_class->get_property   = gimp_operation_grow_get_property;
+
+  operation_class->name        = "gimp:grow";
+  operation_class->categories  = "gimp";
+  operation_class->description = "GIMP Grow operation";
+
+  operation_class->prepare                 = gimp_operation_grow_prepare;
+  operation_class->get_required_for_output = gimp_operation_grow_get_required_for_output;
+  operation_class->get_cached_region       = gimp_operation_grow_get_cached_region;
+
+  filter_class->process        = gimp_operation_grow_process;
+
+  g_object_class_install_property (object_class, PROP_RADIUS_X,
+                                   g_param_spec_int ("radius-x",
+                                                     "Radius X",
+                                                     "Grow 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",
+                                                     "Grow radius in Y diection",
+                                                     1, 2342, 1,
+                                                     G_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT));
+}
+
+static void
+gimp_operation_grow_init (GimpOperationGrow *self)
+{
+}
+
+static void
+gimp_operation_grow_get_property (GObject    *object,
+                                  guint       property_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+ GimpOperationGrow *self = GIMP_OPERATION_GROW (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;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_operation_grow_set_property (GObject      *object,
+                                  guint         property_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+  GimpOperationGrow *self = GIMP_OPERATION_GROW (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;
+
+   default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_operation_grow_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_grow_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_grow_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_grow_process (GeglOperation       *operation,
+                             GeglBuffer          *input,
+                             GeglBuffer          *output,
+                             const GeglRectangle *roi,
+                             gint                 level)
+{
+  /* Any bugs in this fuction are probably also in thin_region Blame
+   * all bugs in this function on jaycox gimp org
+   */
+  GimpOperationGrow *self          = GIMP_OPERATION_GROW (operation);
+  const Babl        *input_format  = babl_format ("Y u8");
+  const Babl        *output_format = babl_format ("Y u8");
+  gint32             i, j, x, y;
+  guchar           **buf;  /* caches the region's pixel data */
+  guchar            *out;  /* holds the new scan line we are computing */
+  guchar           **max;  /* caches the largest values for each column */
+  gint16            *circ; /* holds the y coords of the filter's mask */
+  gint16             last_max, last_index;
+  guchar            *buffer;
+
+  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 = g_new (guchar, (roi->width + 2 * self->radius_x) * (self->radius_y + 1));
+
+  for (i = 0; i < roi->width + 2 * self->radius_x; i++)
+    {
+      if (i < self->radius_x)
+        max[i] = buffer;
+      else if (i < roi->width + self->radius_x)
+        max[i] = &buffer[(self->radius_y + 1) * (i - self->radius_x)];
+      else
+        max[i] = &buffer[(self->radius_y + 1) * (roi->width + self->radius_x - 1)];
+
+      for (j = 0; j < self->radius_x + 1; j++)
+        max[i][j] = 0;
+    }
+
+  /* offset the max pointer by self->radius_x so the range of the
+   * array is [-self->radius_x] to [roi->width + self->radius_x]
+   */
+  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 self->radius_x so the range of the
+   * array is [-self->radius_x] to [self->radius_x]
+   */
+  circ += self->radius_x;
+
+  memset (buf[0], 0, roi->width);
+
+  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, input_format, buf[i + 1],
+                     GEGL_AUTO_ROWSTRIDE);
+
+  for (x = 0; x < roi->width; x++) /* set up max for top of image */
+    {
+      max[x][0] = 0;         /* buf[0][x] is always 0 */
+      max[x][1] = buf[1][x]; /* MAX (buf[1][x], max[x][0]) always = buf[1][x]*/
+
+      for (j = 2; j < self->radius_y + 1; j++)
+        max[x][j] = MAX(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, input_format, buf[self->radius_y],
+                         GEGL_AUTO_ROWSTRIDE);
+      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] = MAX (MAX (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 = 1;
+
+      for (x = 0; x < roi->width; x++) /* render scan line */
+        {
+          last_index--;
+
+          if (last_index >= 0)
+            {
+              if (last_max == 255)
+                {
+                  out[x] = 255;
+                }
+              else
+                {
+                  last_max = 0;
+
+                  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_x][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, output_format, 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;
+
+  g_free (circ);
+  g_free (buffer);
+  g_free (max);
+
+  for (i = 0; i < self->radius_y + 1; i++)
+    g_free (buf[i]);
+
+  g_free (buf);
+  g_free (out);
+
+  return TRUE;
+}
diff --git a/app/gegl/gimpoperationgrow.h b/app/gegl/gimpoperationgrow.h
new file mode 100644
index 0000000..a1dca07
--- /dev/null
+++ b/app/gegl/gimpoperationgrow.h
@@ -0,0 +1,55 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpoperationgrow.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_GROW_H__
+#define __GIMP_OPERATION_GROW_H__
+
+
+#include <gegl-plugin.h>
+
+
+#define GIMP_TYPE_OPERATION_GROW            (gimp_operation_grow_get_type ())
+#define GIMP_OPERATION_GROW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_OPERATION_GROW, GimpOperationGrow))
+#define GIMP_OPERATION_GROW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GIMP_TYPE_OPERATION_GROW, GimpOperationGrowClass))
+#define GIMP_IS_OPERATION_GROW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_OPERATION_GROW))
+#define GIMP_IS_OPERATION_GROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GIMP_TYPE_OPERATION_GROW))
+#define GIMP_OPERATION_GROW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GIMP_TYPE_OPERATION_GROW, GimpOperationGrowClass))
+
+
+typedef struct _GimpOperationGrowClass GimpOperationGrowClass;
+
+struct _GimpOperationGrow
+{
+  GeglOperationFilter  parent_instance;
+
+  gint                 radius_x;
+  gint                 radius_y;
+};
+
+struct _GimpOperationGrowClass
+{
+  GeglOperationFilterClass  parent_class;
+};
+
+
+GType   gimp_operation_grow_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_OPERATION_GROW_H__ */
diff --git a/app/paint-funcs/paint-funcs.c b/app/paint-funcs/paint-funcs.c
index 97a605c..58c022f 100644
--- a/app/paint-funcs/paint-funcs.c
+++ b/app/paint-funcs/paint-funcs.c
@@ -2066,180 +2066,6 @@ shapeburst_region (PixelRegion      *srcPR,
   return max_iterations;
 }
 
-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)));
-  }
-}
-
-void
-fatten_region (PixelRegion *region,
-               gint16       xradius,
-               gint16       yradius)
-{
-  /*
-     Any bugs in this fuction are probably also in thin_region
-     Blame all bugs in this function on jaycox gimp org
-  */
-  register gint32 i, j, x, y;
-
-  guchar  **buf;  /* caches the region's pixel data */
-  guchar   *out;  /* holds the new scan line we are computing */
-  guchar  **max;  /* caches the largest values for each column */
-  gint16   *circ; /* holds the y coords of the filter's mask */
-  gint16    last_max, last_index;
-
-  guchar   *buffer;
-
-  if (xradius <= 0 || yradius <= 0)
-    return;
-
-  max = g_new (guchar *, region->w + 2 * xradius);
-  buf = g_new (guchar *, yradius + 1);
-
-  for (i = 0; i < yradius + 1; i++)
-    buf[i] = g_new (guchar, region->w);
-
-  buffer = g_new (guchar, (region->w + 2 * xradius) * (yradius + 1));
-
-  for (i = 0; i < region->w + 2 * xradius; i++)
-    {
-      if (i < xradius)
-        max[i] = buffer;
-      else if (i < region->w + xradius)
-        max[i] = &buffer[(yradius + 1) * (i - xradius)];
-      else
-        max[i] = &buffer[(yradius + 1) * (region->w + xradius - 1)];
-
-      for (j = 0; j < xradius + 1; j++)
-        max[i][j] = 0;
-    }
-
-  /* offset the max pointer by xradius so the range of the array
-     is [-xradius] to [region->w + xradius] */
-  max += xradius;
-
-  out =  g_new (guchar, region->w);
-
-  circ = g_new (gint16, 2 * xradius + 1);
-  compute_border (circ, xradius, yradius);
-
-  /* offset the circ pointer by xradius so the range of the array
-     is [-xradius] to [xradius] */
-  circ += xradius;
-
-  memset (buf[0], 0, region->w);
-
-  for (i = 0; i < yradius && i < region->h; i++) /* load top of image */
-    pixel_region_get_row (region,
-                          region->x, region->y + i, region->w, buf[i + 1], 1);
-
-  for (x = 0; x < region->w; x++) /* set up max for top of image */
-    {
-      max[x][0] = 0;         /* buf[0][x] is always 0 */
-      max[x][1] = buf[1][x]; /* MAX (buf[1][x], max[x][0]) always = buf[1][x]*/
-
-      for (j = 2; j < yradius + 1; j++)
-        max[x][j] = MAX(buf[j][x], max[x][j-1]);
-    }
-
-  for (y = 0; y < region->h; y++)
-    {
-      rotate_pointers (buf, yradius + 1);
-
-      if (y < region->h - (yradius))
-        pixel_region_get_row (region,
-                              region->x, region->y + y + yradius, region->w,
-                              buf[yradius], 1);
-      else
-        memset (buf[yradius], 0, region->w);
-
-      for (x = 0; x < region->w; x++) /* update max array */
-        {
-          for (i = yradius; i > 0; i--)
-            max[x][i] = MAX (MAX (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 = 1;
-
-      for (x = 0; x < region->w; x++) /* render scan line */
-        {
-          last_index--;
-
-          if (last_index >= 0)
-            {
-              if (last_max == 255)
-                {
-                  out[x] = 255;
-                }
-              else
-                {
-                  last_max = 0;
-
-                  for (i = xradius; 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 = xradius;
-              last_max = max[x + xradius][circ[xradius]];
-
-              for (i = xradius - 1; i >= -xradius; i--)
-                if (last_max < max[x + i][circ[i]])
-                  {
-                    last_max = max[x + i][circ[i]];
-                    last_index = i;
-                  }
-
-              out[x] = last_max;
-            }
-        }
-
-      pixel_region_set_row (region, region->x, region->y + y, region->w, out);
-    }
-
-  /* undo the offsets to the pointers so we can free the malloced memmory */
-  circ -= xradius;
-  max -= xradius;
-
-  g_free (circ);
-  g_free (buffer);
-  g_free (max);
-
-  for (i = 0; i < yradius + 1; i++)
-    g_free (buf[i]);
-
-  g_free (buf);
-  g_free (out);
-}
-
 /*  Simple convolution filter to smooth a mask (1bpp).  */
 void
 smooth_region (PixelRegion *region)
diff --git a/app/paint-funcs/paint-funcs.h b/app/paint-funcs/paint-funcs.h
index 74ebe79..4981ce6 100644
--- a/app/paint-funcs/paint-funcs.h
+++ b/app/paint-funcs/paint-funcs.h
@@ -296,10 +296,6 @@ gfloat shapeburst_region                  (PixelRegion      *srcPR,
                                            GimpProgressFunc  progress_callback,
                                            gpointer          progress_data);
 
-void  fatten_region                       (PixelRegion *region,
-                                           gint16       xradius,
-                                           gint16       yradius);
-
 void  smooth_region                       (PixelRegion *region);
 void  erode_region                        (PixelRegion *region);
 void  dilate_region                       (PixelRegion *region);



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