[gimp] app: port gimp_image_contiguous_region_by_seed() to GEGL



commit 6d1776d354635b475102b901934217450615ea49
Author: Michael Natterer <mitch gimp org>
Date:   Tue Apr 17 19:56:13 2012 +0200

    app: port gimp_image_contiguous_region_by_seed() to GEGL

 app/core/gimpimage-contiguous-region.c |  318 ++++++++++----------------------
 1 files changed, 101 insertions(+), 217 deletions(-)
---
diff --git a/app/core/gimpimage-contiguous-region.c b/app/core/gimpimage-contiguous-region.c
index 6581001..e5b3e82 100644
--- a/app/core/gimpimage-contiguous-region.c
+++ b/app/core/gimpimage-contiguous-region.c
@@ -26,11 +26,6 @@
 
 #include "core-types.h"
 
-#include "base/pixel-processor.h"
-#include "base/pixel-region.h"
-#include "base/tile.h"
-#include "base/tile-manager.h"
-
 #include "gimpchannel.h"
 #include "gimpimage.h"
 #include "gimpimage-contiguous-region.h"
@@ -47,34 +42,24 @@ static gint pixel_difference              (const guchar        *col1,
                                            gboolean             has_alpha,
                                            gboolean             select_transparent,
                                            GimpSelectCriterion  select_criterion);
-static void ref_tiles                     (TileManager         *src,
-                                           TileManager         *mask,
-                                           Tile               **s_tile,
-                                           Tile               **m_tile,
-                                           gint                 x,
-                                           gint                 y,
-                                           guchar             **s,
-                                           guchar             **m);
-static gboolean find_contiguous_segment   (GimpImage           *image,
-                                           const guchar        *col,
-                                           PixelRegion         *src,
-                                           PixelRegion         *mask,
-                                           gint                 width,
+static gboolean find_contiguous_segment   (const guchar        *col,
+                                           GeglBuffer          *src_buffer,
+                                           GeglBuffer          *mask_buffer,
+                                           const Babl          *src_format,
                                            gint                 bytes,
-                                           const Babl          *fish,
                                            gboolean             has_alpha,
+                                           gint                 width,
                                            gboolean             select_transparent,
                                            GimpSelectCriterion  select_criterion,
                                            gboolean             antialias,
                                            gint                 threshold,
-                                           gint                 initial,
+                                           gint                 initial_x,
+                                           gint                 initial_y,
                                            gint                *start,
                                            gint                *end);
-static void find_contiguous_region_helper (GimpImage           *image,
-                                           PixelRegion         *mask,
-                                           PixelRegion         *src,
-                                           const Babl          *fish,
-                                           gboolean             has_alpha,
+static void find_contiguous_region_helper (GeglBuffer          *src_buffer,
+                                           GeglBuffer          *mask_buffer,
+                                           const Babl          *format,
                                            gboolean             select_transparent,
                                            GimpSelectCriterion  select_criterion,
                                            gboolean             antialias,
@@ -97,15 +82,12 @@ gimp_image_contiguous_region_by_seed (GimpImage           *image,
                                       gint                 x,
                                       gint                 y)
 {
-  PixelRegion    srcPR, maskPR;
-  GimpPickable  *pickable;
-  TileManager   *tiles;
-  GimpChannel   *mask;
-  const Babl    *src_format;
-  const Babl    *fish = NULL;
-  gboolean       has_alpha;
-  gint           bytes;
-  Tile          *tile;
+  GimpPickable *pickable;
+  GeglBuffer   *src_buffer;
+  GimpChannel  *mask;
+  GeglBuffer   *mask_buffer;
+  const Babl   *src_format;
+  guchar        start_col[MAX_CHANNELS];
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
@@ -118,69 +100,42 @@ gimp_image_contiguous_region_by_seed (GimpImage           *image,
   gimp_pickable_flush (pickable);
 
   src_format = gimp_pickable_get_format (pickable);
-  has_alpha  = babl_format_has_alpha (src_format);
-  bytes      = babl_format_get_bytes_per_pixel (src_format);
-
-  tiles = gimp_pickable_get_tiles (pickable);
-  pixel_region_init (&srcPR, tiles,
-                     0, 0,
-                     tile_manager_width (tiles),
-                     tile_manager_height (tiles),
-                     FALSE);
-
-  mask = gimp_channel_new_mask (image, srcPR.w, srcPR.h);
-  pixel_region_init (&maskPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
-                     0, 0,
-                     gimp_item_get_width  (GIMP_ITEM (mask)),
-                     gimp_item_get_height (GIMP_ITEM (mask)),
-                     TRUE);
-
-  tile = tile_manager_get_tile (srcPR.tiles, x, y, TRUE, FALSE);
-  if (tile)
-    {
-      const guchar *start;
-      guchar        start_col[MAX_CHANNELS];
+  if (babl_format_is_palette (src_format))
+    src_format = babl_format ("R'G'B'A u8");
 
-      start = tile_data_pointer (tile, x, y);
+  src_buffer = gimp_pickable_get_buffer (pickable);
 
-      if (has_alpha)
-        {
-          if (select_transparent)
-            {
-              /*  don't select transparent regions if the start pixel isn't
-               *  fully transparent
-               */
-              if (start[bytes - 1] > 0)
-                select_transparent = FALSE;
-            }
-        }
-      else
-        {
-          select_transparent = FALSE;
-        }
+  mask = gimp_channel_new_mask (image,
+                                gegl_buffer_get_width  (src_buffer),
+                                gegl_buffer_get_height (src_buffer));
 
-      if (babl_format_is_palette (src_format))
-        {
-          fish = babl_fish (src_format, babl_format ("R'G'B'A u8"));
+  mask_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
 
-          babl_process (fish, start, start_col, 1);
-        }
-      else
+  gegl_buffer_sample (src_buffer, x, y, NULL, start_col, src_format,
+                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
+
+  if (babl_format_has_alpha (src_format))
+    {
+      if (select_transparent)
         {
-          gint i;
+          gint bytes = babl_format_get_bytes_per_pixel (src_format);
 
-          for (i = 0; i < bytes; i++)
-            start_col[i] = start[i];
+          /*  don't select transparent regions if the start pixel isn't
+           *  fully transparent
+           */
+          if (start_col[bytes - 1] > 0)
+            select_transparent = FALSE;
         }
-
-      find_contiguous_region_helper (image, &maskPR, &srcPR,
-                                     fish, has_alpha,
-                                     select_transparent, select_criterion,
-                                     antialias, threshold,
-                                     x, y, start_col);
-
-      tile_release (tile, FALSE);
     }
+  else
+    {
+      select_transparent = FALSE;
+    }
+
+  find_contiguous_region_helper (src_buffer, mask_buffer, src_format,
+                                 select_transparent, select_criterion,
+                                 antialias, threshold,
+                                 x, y, start_col);
 
   return mask;
 }
@@ -402,160 +357,90 @@ pixel_difference (const guchar        *col1,
     }
 }
 
-static void
-ref_tiles (TileManager  *src,
-           TileManager  *mask,
-           Tile        **s_tile,
-           Tile        **m_tile,
-           gint          x,
-           gint          y,
-           guchar      **s,
-           guchar      **m)
-{
-  if (*s_tile != NULL)
-    tile_release (*s_tile, FALSE);
-  if (*m_tile != NULL)
-    tile_release (*m_tile, TRUE);
-
-  *s_tile = tile_manager_get_tile (src, x, y, TRUE, FALSE);
-  *m_tile = tile_manager_get_tile (mask, x, y, TRUE, TRUE);
-
-  *s = tile_data_pointer (*s_tile, x, y);
-  *m = tile_data_pointer (*m_tile, x, y);
-}
-
 static gboolean
-find_contiguous_segment (GimpImage           *image,
-                         const guchar        *col,
-                         PixelRegion         *src,
-                         PixelRegion         *mask,
-                         gint                 width,
+find_contiguous_segment (const guchar        *col,
+                         GeglBuffer          *src_buffer,
+                         GeglBuffer          *mask_buffer,
+                         const Babl          *src_format,
                          gint                 bytes,
-                         const Babl          *fish,
                          gboolean             has_alpha,
+                         gint                 width,
                          gboolean             select_transparent,
                          GimpSelectCriterion  select_criterion,
                          gboolean             antialias,
                          gint                 threshold,
-                         gint                 initial,
+                         gint                 initial_x,
+                         gint                 initial_y,
                          gint                *start,
                          gint                *end)
 {
-  guchar *s;
-  guchar *m;
-  guchar  s_color[MAX_CHANNELS];
-  guchar  diff;
-  gint    col_bytes = bytes;
-  Tile   *s_tile    = NULL;
-  Tile   *m_tile    = NULL;
-
-  ref_tiles (src->tiles, mask->tiles,
-             &s_tile, &m_tile, src->x, src->y, &s, &m);
-
-  if (fish)
-    {
-      col_bytes = has_alpha ? 4 : 3;
+  guchar s[MAX_CHANNELS];
+  guchar mask_row[width];
+  guchar diff;
 
-      babl_process (fish, s, s_color, 1);
+  gegl_buffer_sample (src_buffer, initial_x, initial_y, NULL, s, src_format,
+                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
 
-      diff = pixel_difference (col, s_color, antialias, threshold,
-                               col_bytes, has_alpha, select_transparent,
-                               select_criterion);
-     }
-  else
-    {
-      diff = pixel_difference (col, s, antialias, threshold,
-                               col_bytes, has_alpha, select_transparent,
-                               select_criterion);
-    }
+  diff = pixel_difference (col, s, antialias, threshold,
+                           bytes, has_alpha, select_transparent,
+                           select_criterion);
 
   /* check the starting pixel */
   if (! diff)
-    {
-      tile_release (s_tile, FALSE);
-      tile_release (m_tile, TRUE);
-      return FALSE;
-    }
+    return FALSE;
+
+  mask_row[initial_x] = diff;
 
-  *m-- = diff;
-  s -= bytes;
-  *start = initial - 1;
+  *start = initial_x - 1;
 
   while (*start >= 0 && diff)
     {
-      if (! ((*start + 1) % TILE_WIDTH))
-        ref_tiles (src->tiles, mask->tiles,
-                   &s_tile, &m_tile, *start, src->y, &s, &m);
+      gegl_buffer_sample (src_buffer, *start, initial_y, NULL, s, src_format,
+                          GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
 
-      if (fish)
-        {
-          babl_process (fish, s, s_color, 1);
+      diff = pixel_difference (col, s, antialias, threshold,
+                               bytes, has_alpha, select_transparent,
+                               select_criterion);
 
-          diff = pixel_difference (col, s_color, antialias, threshold,
-                                   col_bytes, has_alpha, select_transparent,
-                                   select_criterion);
-        }
-      else
-        {
-          diff = pixel_difference (col, s, antialias, threshold,
-                                   col_bytes, has_alpha, select_transparent,
-                                   select_criterion);
-        }
+      mask_row[*start] = diff;
 
-      if ((*m-- = diff))
-        {
-          s -= bytes;
-          (*start)--;
-        }
+      if (diff)
+        (*start)--;
     }
 
   diff = 1;
-  *end = initial + 1;
-
-  if (*end % TILE_WIDTH && *end < width)
-    ref_tiles (src->tiles, mask->tiles,
-               &s_tile, &m_tile, *end, src->y, &s, &m);
+  *end = initial_x + 1;
 
   while (*end < width && diff)
     {
-      if (! (*end % TILE_WIDTH))
-        ref_tiles (src->tiles, mask->tiles,
-                   &s_tile, &m_tile, *end, src->y, &s, &m);
+      gegl_buffer_sample (src_buffer, *end, initial_y, NULL, s, src_format,
+                          GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
 
-      if (fish)
-        {
-          babl_process (fish, s, s_color, 1);
+      diff = pixel_difference (col, s, antialias, threshold,
+                               bytes, has_alpha, select_transparent,
+                               select_criterion);
 
-          diff = pixel_difference (col, s_color, antialias, threshold,
-                                   col_bytes, has_alpha, select_transparent,
-                                   select_criterion);
-        }
-      else
-        {
-          diff = pixel_difference (col, s, antialias, threshold,
-                                   col_bytes, has_alpha, select_transparent,
-                                   select_criterion);
-        }
+      mask_row[*end] = diff;
 
-      if ((*m++ = diff))
-        {
-          s += bytes;
-          (*end)++;
-        }
+      if (diff)
+        (*end)++;
     }
 
-  tile_release (s_tile, FALSE);
-  tile_release (m_tile, TRUE);
+  gegl_buffer_set (mask_buffer, GEGL_RECTANGLE (*start, initial_y,
+                                                *end - *start, 1),
+                   0, babl_format ("Y u8"), &mask_row[*start],
+                   GEGL_AUTO_ROWSTRIDE);
+
+  /* XXX this should now be needed and is a performance killer */
+  gegl_buffer_sample_cleanup (mask_buffer);
 
   return TRUE;
 }
 
 static void
-find_contiguous_region_helper (GimpImage           *image,
-                               PixelRegion         *mask,
-                               PixelRegion         *src,
-                               const Babl          *fish,
-                               gboolean             has_alpha,
+find_contiguous_region_helper (GeglBuffer          *src_buffer,
+                               GeglBuffer          *mask_buffer,
+                               const Babl          *format,
                                gboolean             select_transparent,
                                GimpSelectCriterion  select_criterion,
                                gboolean             antialias,
@@ -566,8 +451,7 @@ find_contiguous_region_helper (GimpImage           *image,
 {
   gint    start, end;
   gint    new_start, new_end;
-  gint    val;
-  Tile   *tile;
+  guchar  val;
   GQueue *coord_stack;
 
   coord_stack = g_queue_new ();
@@ -589,23 +473,23 @@ find_contiguous_region_helper (GimpImage           *image,
 
       for (x = start + 1; x < end; x++)
         {
-          tile = tile_manager_get_tile (mask->tiles, x, y, TRUE, FALSE);
-          val = *(const guchar *) tile_data_pointer (tile, x, y);
-          tile_release (tile, FALSE);
+          gegl_buffer_sample (mask_buffer, x, y, NULL, &val,
+                              babl_format ("Y u8"),
+                              GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
           if (val != 0)
             continue;
 
-          src->x = x;
-          src->y = y;
-
-          if (! find_contiguous_segment (image, col, src, mask, src->w,
-                                         src->bytes, fish, has_alpha,
+          if (! find_contiguous_segment (col, src_buffer, mask_buffer,
+                                         format,
+                                         babl_format_get_bytes_per_pixel (format),
+                                         babl_format_has_alpha (format),
+                                         gegl_buffer_get_width (src_buffer),
                                          select_transparent, select_criterion,
-                                         antialias, threshold, x,
+                                         antialias, threshold, x, y,
                                          &new_start, &new_end))
             continue;
 
-          if (y + 1 < src->h)
+          if (y + 1 < gegl_buffer_get_height (src_buffer))
             {
               g_queue_push_tail (coord_stack, GINT_TO_POINTER (y + 1));
               g_queue_push_tail (coord_stack, GINT_TO_POINTER (new_start));



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