[gimp] plugins: port border-average.c to GEGL



commit 48c18ce784c0f53328cec9d686823f469cf22c96
Author: Téo Mazars <teo mazars ensimag fr>
Date:   Mon Jul 15 22:48:41 2013 +0200

    plugins: port border-average.c to GEGL

 plug-ins/common/Makefile.am      |    1 +
 plug-ins/common/border-average.c |  163 +++++++++++++++++++++----------------
 plug-ins/common/plugin-defs.pl   |    2 +-
 3 files changed, 94 insertions(+), 72 deletions(-)
---
diff --git a/plug-ins/common/Makefile.am b/plug-ins/common/Makefile.am
index ce6fd8e..9a51f6f 100644
--- a/plug-ins/common/Makefile.am
+++ b/plug-ins/common/Makefile.am
@@ -389,6 +389,7 @@ border_average_LDADD = \
        $(libgimpcolor)         \
        $(libgimpbase)          \
        $(GTK_LIBS)             \
+       $(GEGL_LIBS)            \
        $(RT_LIBS)              \
        $(INTLLIBS)             \
        $(border_average_RC)
diff --git a/plug-ins/common/border-average.c b/plug-ins/common/border-average.c
index be265fb..6659e15 100644
--- a/plug-ins/common/border-average.c
+++ b/plug-ins/common/border-average.c
@@ -40,14 +40,14 @@ static void      run    (const gchar      *name,
                          GimpParam       **return_vals);
 
 
-static void      borderaverage        (GimpDrawable *drawable,
+static void      borderaverage        (GeglBuffer   *buffer,
+                                       gint32        drawable_id,
                                        GimpRGB      *result);
 
 static gboolean  borderaverage_dialog (gint32        image_ID,
-                                       GimpDrawable *drawable);
+                                       gint32        drawable_id);
 
-static void      add_new_color        (gint          bytes,
-                                       const guchar *buffer,
+static void      add_new_color        (const guchar *buffer,
                                        gint         *cube,
                                        gint          bucket_expo);
 
@@ -119,19 +119,21 @@ run (const gchar      *name,
      GimpParam       **return_vals)
 {
   static GimpParam   values[3];
-  GimpDrawable      *drawable;
   gint32             image_ID;
   GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
   GimpRGB            result_color;
   GimpRunMode        run_mode;
+  gint32             drawable_id;
+  GeglBuffer        *buffer;
 
   INIT_I18N ();
+  gegl_init (NULL, NULL);
 
   run_mode = param[0].data.d_int32;
   image_ID = param[1].data.d_int32;
+  drawable_id = param[2].data.d_drawable;
 
-  /*    Get the specified drawable      */
-  drawable = gimp_drawable_get (param[2].data.d_drawable);
+  buffer = gimp_drawable_get_buffer (drawable_id);
 
   switch (run_mode)
     {
@@ -139,7 +141,7 @@ run (const gchar      *name,
       gimp_get_data (PLUG_IN_PROC, &borderaverage_data);
       borderaverage_thickness       = borderaverage_data.thickness;
       borderaverage_bucket_exponent = borderaverage_data.bucket_exponent;
-      if (! borderaverage_dialog (image_ID, drawable))
+      if (! borderaverage_dialog (image_ID, drawable_id))
         status = GIMP_PDB_EXECUTION_ERROR;
       break;
 
@@ -166,10 +168,10 @@ run (const gchar      *name,
   if (status == GIMP_PDB_SUCCESS)
     {
       /*  Make sure that the drawable is RGB color  */
-      if (gimp_drawable_is_rgb (drawable->drawable_id))
+      if (gimp_drawable_is_rgb (drawable_id))
         {
           gimp_progress_init ( _("Border Average"));
-          borderaverage (drawable, &result_color);
+          borderaverage (buffer, drawable_id, &result_color);
 
           if (run_mode != GIMP_RUN_NONINTERACTIVE)
             {
@@ -197,53 +199,28 @@ run (const gchar      *name,
   values[1].type         = GIMP_PDB_COLOR;
   values[1].data.d_color = result_color;
 
-  gimp_drawable_detach (drawable);
+  g_object_unref (buffer);
 }
 
-typedef struct {
-  gint x1, x2, y1, y2;
-  gint bucket_expo;
-  gint *cube;
-} BorderAverageParam_t;
 
 static void
-borderaverage_func (gint x,
-                    gint y,
-                    const guchar *src,
-                    gint bpp,
-                    gpointer data)
-{
-  BorderAverageParam_t *param = (BorderAverageParam_t*) data;
-
-  if (x <  param->x1 + borderaverage_thickness ||
-      x >= param->x2 - borderaverage_thickness ||
-      y <  param->y1 + borderaverage_thickness ||
-      y >= param->y2 - borderaverage_thickness)
-    {
-      add_new_color (bpp, src, param->cube, param->bucket_expo);
-    }
-}
-
-static void
-borderaverage (GimpDrawable *drawable,
+borderaverage (GeglBuffer   *buffer,
+               gint32        drawable_id,
                GimpRGB      *result)
 {
-  gint    x1, x2, y1, y2;
-  gint    bytes;
-  gint    max;
-  guchar  r, g, b;
-  guchar *buffer;
-  gint    bucket_num, bucket_expo, bucket_rexpo;
-  gint   *cube;
-  gint    i, j, k; /* index variables */
-  GimpRgnIterator *iter;
-
-  BorderAverageParam_t     param;
+  gint            x1, x2, y1, y2;
+  gint            x, y, width, height;
+  gint            max;
+  guchar          r, g, b;
+  gint            bucket_num, bucket_expo, bucket_rexpo;
+  gint           *cube;
+  gint            i, j, k;
+  GeglRectangle   border[4];
 
   /* allocate and clear the cube before */
   bucket_expo = borderaverage_bucket_exponent;
   bucket_rexpo = 8 - bucket_expo;
-  param.cube = cube = g_new (gint, 1 << (bucket_rexpo * 3));
+  cube = g_new (gint, 1 << (bucket_rexpo * 3));
   bucket_num = 1 << bucket_rexpo;
 
   for (i = 0; i < bucket_num; i++)
@@ -257,26 +234,64 @@ borderaverage (GimpDrawable *drawable,
         }
     }
 
-  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
-  param.x1 = x1;
-  param.y1 = y1;
-  param.x2 = x2;
-  param.y2 = y2;
-  param.bucket_expo = bucket_expo;
+  gimp_drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
+
+  x = x1;
+  y = y1;
+
+  width  = x2 - x1;
+  height = y2 - y1;
+
+  /* Top */
+  border[0].x =       x;
+  border[0].y =       y;
+  border[0].width =   width;
+  border[0].height =  borderaverage_thickness;
+
+  /* Bottom */
+  border[1].x =       x;
+  border[1].y =       y + height - borderaverage_thickness;
+  border[1].width =   width;
+  border[1].height =  borderaverage_thickness;
+
+  /* Left */
+  border[2].x =       x;
+  border[2].y =       y + borderaverage_thickness;
+  border[2].width =   borderaverage_thickness;
+  border[2].height =  height - 2 * borderaverage_thickness;
 
-  /*  Get the size of the input image. (This will/must be the same
-   *  as the size of the output image.
-   */
-  bytes = drawable->bpp;
+  /* Right */
+  border[3].x =       x + width - borderaverage_thickness;
+  border[3].y =       y + borderaverage_thickness;
+  border[3].width =   borderaverage_thickness;
+  border[3].height =  height - 2 * borderaverage_thickness;
 
-  gimp_tile_cache_ntiles (2 * ((x2 - x1) / gimp_tile_width () + 1));
+  /* Fill the cube */
+  for (i = 0; i < 4; i++)
+    {
+      if (border[i].width > 0 && border[i].height > 0)
+        {
+          GeglBufferIterator *gi;
+
+          gi = gegl_buffer_iterator_new (buffer, &border[i], 0, babl_format ("R'G'B' u8"),
+                                         GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE);
 
-  /*  allocate row buffer  */
-  buffer = g_new (guchar, (x2 - x1) * bytes);
+          while (gegl_buffer_iterator_next (gi))
+            {
+              guint   k;
+              guchar *data;
+
+              data = (guchar*) gi->data[0];
 
-  iter = gimp_rgn_iterator_new (drawable, 0);
-  gimp_rgn_iterator_src (iter, borderaverage_func, &param);
-  gimp_rgn_iterator_free (iter);
+              for (k = 0; k < gi->length; k++)
+                {
+                  add_new_color (data + k * 3,
+                                 cube,
+                                 bucket_expo);
+                }
+            }
+        }
+    }
 
   max = 0; r = 0; g = 0; b = 0;
 
@@ -291,7 +306,7 @@ borderaverage (GimpDrawable *drawable,
                       (j << bucket_rexpo) + k] > max)
                 {
                   max = cube[(i << (bucket_rexpo << 1)) +
-                            (j << bucket_rexpo) + k];
+                             (j << bucket_rexpo) + k];
                   r = (i<<bucket_expo) + (1<<(bucket_expo - 1));
                   g = (j<<bucket_expo) + (1<<(bucket_expo - 1));
                   b = (k<<bucket_expo) + (1<<(bucket_expo - 1));
@@ -303,13 +318,11 @@ borderaverage (GimpDrawable *drawable,
   /* return the color */
   gimp_rgb_set_uchar (result, r, g, b);
 
-  g_free (buffer);
   g_free (cube);
 }
 
 static void
-add_new_color (gint          bytes,
-               const guchar *buffer,
+add_new_color (const guchar *buffer,
                gint         *cube,
                gint          bucket_expo)
 {
@@ -318,14 +331,14 @@ add_new_color (gint          bytes,
 
   bucket_rexpo = 8 - bucket_expo;
   r = buffer[0] >> bucket_expo;
-  g = (bytes > 1) ? buffer[1] >> bucket_expo : 0;
-  b = (bytes > 2) ? buffer[2] >> bucket_expo : 0;
+  g = buffer[1] >> bucket_expo;
+  b = buffer[2] >> bucket_expo;
   cube[(r << (bucket_rexpo << 1)) + (g << bucket_rexpo) + b]++;
 }
 
 static gboolean
 borderaverage_dialog (gint32        image_ID,
-                      GimpDrawable *drawable)
+                      gint32        drawable_id)
 {
   GtkWidget    *dialog;
   GtkWidget    *frame;
@@ -338,6 +351,7 @@ borderaverage_dialog (gint32        image_ID,
   GtkSizeGroup *group;
   gboolean      run;
   gdouble       xres, yres;
+  gint          width, height;
 
   const gchar *labels[] =
     { "1", "2", "4", "8", "16", "32", "64", "128", "256" };
@@ -394,9 +408,16 @@ borderaverage_dialog (gint32        image_ID,
   gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (size_entry), GIMP_UNIT_PIXEL);
   gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (size_entry), 0, xres, TRUE);
 
+  {
+    gint x1, x2, y1, y2;
+    gimp_drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
+    width  = x2 - x1;
+    height = y2 - y1;
+  }
+
   /*  set the size (in pixels) that will be treated as 0% and 100%  */
   gimp_size_entry_set_size (GIMP_SIZE_ENTRY (size_entry), 0, 0.0,
-                            drawable->width);
+                            MIN (width, height));
 
   gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (size_entry), 0,
                                          1.0, 256.0);
diff --git a/plug-ins/common/plugin-defs.pl b/plug-ins/common/plugin-defs.pl
index 7a9229a..e63e720 100644
--- a/plug-ins/common/plugin-defs.pl
+++ b/plug-ins/common/plugin-defs.pl
@@ -9,7 +9,7 @@
     'blur' => {},
     'blur-gauss' => { ui => 1 },
     'blur-gauss-selective' => { ui => 1, cflags => 'MMX_EXTRA_CFLAGS' },
-    'border-average' => { ui => 1 },
+    'border-average' => { ui => 1, gegl => 1 },
     'bump-map' => { ui => 1 },
     'cartoon' => { ui => 1 },
     'channel-mixer' => { ui => 1 },


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