[gimp/goat-invasion: 503/608] app: port gimp_image_contiguous_region_by_seed() to GEGL
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion: 503/608] app: port gimp_image_contiguous_region_by_seed() to GEGL
- Date: Fri, 27 Apr 2012 21:07:39 +0000 (UTC)
commit f1c348f1d15683d36ce8ad2d76fb9e50ef167390
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]