[gimp/goat-invasion: 518/526] app: change GimpBoundary to find the boundary a float component
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion: 518/526] app: change GimpBoundary to find the boundary a float component
- Date: Sun, 22 Apr 2012 13:42:48 +0000 (UTC)
commit e6805ed8913d519c593a44431b7dd019a6270594
Author: Michael Natterer <mitch gimp org>
Date: Sat Apr 21 20:10:45 2012 +0200
app: change GimpBoundary to find the boundary a float component
Require passing in a Babl format that will extract the float component
the algorithm should run on.
app/core/gimpboundary.c | 155 ++++++++++++++++++-------------------
app/core/gimpboundary.h | 5 +-
app/core/gimpbrush-boundary.c | 3 +-
app/core/gimpchannel.c | 2 +
app/core/gimplayer-floating-sel.c | 1 +
app/gegl/gimp-gegl.c | 6 ++
app/tools/gimpregionselecttool.c | 1 +
7 files changed, 92 insertions(+), 81 deletions(-)
---
diff --git a/app/core/gimpboundary.c b/app/core/gimpboundary.c
index 0463778..ff370a8 100644
--- a/app/core/gimpboundary.c
+++ b/app/core/gimpboundary.c
@@ -56,71 +56,71 @@ struct _GimpBoundary
/* local function prototypes */
static GimpBoundary * gimp_boundary_new (const GeglRectangle *region);
-static GimpBoundSeg * gimp_boundary_free (GimpBoundary *boundary,
- gboolean free_segs);
+static GimpBoundSeg * gimp_boundary_free (GimpBoundary *boundary,
+ gboolean free_segs);
static void gimp_boundary_add_seg (GimpBoundary *bounrady,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- gboolean open);
-
-static void find_empty_segs (const GeglRectangle *region,
- const guchar *line_data,
- gint bpp,
- gint scanline,
- gint empty_segs[],
- gint max_empty,
- gint *num_empty,
- GimpBoundaryType type,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- guchar threshold);
-static void process_horiz_seg (GimpBoundary *boundary,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- gboolean open);
-static void make_horiz_segs (GimpBoundary *boundary,
- gint start,
- gint end,
- gint scanline,
- gint empty[],
- gint num_empty,
- gint top);
-static GimpBoundary * generate_boundary (GeglBuffer *buffer,
- const GeglRectangle *region,
- GimpBoundaryType type,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- guchar threshold);
-
-static gint cmp_segptr_xy1_addr (const GimpBoundSeg **seg_ptr_a,
- const GimpBoundSeg **seg_ptr_b);
-static gint cmp_segptr_xy2_addr (const GimpBoundSeg **seg_ptr_a,
- const GimpBoundSeg **seg_ptr_b);
-
-static gint cmp_segptr_xy1 (const GimpBoundSeg **seg_ptr_a,
- const GimpBoundSeg **seg_ptr_b);
-static gint cmp_segptr_xy2 (const GimpBoundSeg **seg_ptr_a,
- const GimpBoundSeg **seg_ptr_b);
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gboolean open);
+
+static void find_empty_segs (const GeglRectangle *region,
+ const gfloat *line_data,
+ gint scanline,
+ gint empty_segs[],
+ gint max_empty,
+ gint *num_empty,
+ GimpBoundaryType type,
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gfloat threshold);
+static void process_horiz_seg (GimpBoundary *boundary,
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gboolean open);
+static void make_horiz_segs (GimpBoundary *boundary,
+ gint start,
+ gint end,
+ gint scanline,
+ gint empty[],
+ gint num_empty,
+ gint top);
+static GimpBoundary * generate_boundary (GeglBuffer *buffer,
+ const GeglRectangle *region,
+ const Babl *format,
+ GimpBoundaryType type,
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gfloat threshold);
+
+static gint cmp_segptr_xy1_addr (const GimpBoundSeg **seg_ptr_a,
+ const GimpBoundSeg **seg_ptr_b);
+static gint cmp_segptr_xy2_addr (const GimpBoundSeg **seg_ptr_a,
+ const GimpBoundSeg **seg_ptr_b);
+
+static gint cmp_segptr_xy1 (const GimpBoundSeg **seg_ptr_a,
+ const GimpBoundSeg **seg_ptr_b);
+static gint cmp_segptr_xy2 (const GimpBoundSeg **seg_ptr_a,
+ const GimpBoundSeg **seg_ptr_b);
static const GimpBoundSeg * find_segment (const GimpBoundSeg **segs_by_xy1,
const GimpBoundSeg **segs_by_xy2,
- gint num_segs,
- gint x,
- gint y);
+ gint num_segs,
+ gint x,
+ gint y);
static const GimpBoundSeg * find_segment_with_func (const GimpBoundSeg **segs,
- gint num_segs,
+ gint num_segs,
const GimpBoundSeg *search_seg,
- GCompareFunc cmp_func);
+ GCompareFunc cmp_func);
static void simplify_subdivide (const GimpBoundSeg *segs,
gint start_idx,
@@ -133,6 +133,7 @@ static void simplify_subdivide (const GimpBoundSeg *segs,
/**
* gimp_boundary_find:
* @maskPR: any PixelRegion
+ * @format: a #Babl float format representing the component to analyze
* @type: type of bounds
* @x1: left side of bounds
* @y1: top side of bounds
@@ -154,12 +155,13 @@ static void simplify_subdivide (const GimpBoundSeg *segs,
GimpBoundSeg *
gimp_boundary_find (GeglBuffer *buffer,
const GeglRectangle *region,
+ const Babl *format,
GimpBoundaryType type,
int x1,
int y1,
int x2,
int y2,
- guchar threshold,
+ gfloat threshold,
int *num_segs)
{
GimpBoundary *boundary;
@@ -167,6 +169,9 @@ gimp_boundary_find (GeglBuffer *buffer,
g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
g_return_val_if_fail (num_segs != NULL, NULL);
+ g_return_val_if_fail (format != NULL, NULL);
+ g_return_val_if_fail (babl_format_get_bytes_per_pixel (format) ==
+ sizeof (gfloat), NULL);
if (region)
{
@@ -178,7 +183,8 @@ gimp_boundary_find (GeglBuffer *buffer,
rect.height = gegl_buffer_get_height (buffer);
}
- boundary = generate_boundary (buffer, &rect, type, x1, y1, x2, y2, threshold);
+ boundary = generate_boundary (buffer, &rect, format, type,
+ x1, y1, x2, y2, threshold);
*num_segs = boundary->num_segs;
@@ -477,8 +483,7 @@ gimp_boundary_add_seg (GimpBoundary *boundary,
static void
find_empty_segs (const GeglRectangle *region,
- const guchar *line_data,
- gint bpp,
+ const gfloat *line_data,
gint scanline,
gint empty_segs[],
gint max_empty,
@@ -488,7 +493,7 @@ find_empty_segs (const GeglRectangle *region,
gint y1,
gint x2,
gint y2,
- guchar threshold)
+ gfloat threshold)
{
gint start = 0;
gint end = 0;
@@ -532,8 +537,7 @@ find_empty_segs (const GeglRectangle *region,
endx = end;
- line_data += bpp * start;
- line_data += bpp - 1;
+ line_data += start;
for (x = start; x < end;)
{
@@ -555,7 +559,7 @@ find_empty_segs (const GeglRectangle *region,
val = -1;
}
- line_data += bpp;
+ line_data++;
if (last != val)
empty_segs[l_num_empty++] = x;
@@ -574,7 +578,7 @@ find_empty_segs (const GeglRectangle *region,
else
val = -1;
- line_data += bpp;
+ line_data++;
if (last != val)
empty_segs[l_num_empty++] = x;
@@ -657,18 +661,17 @@ make_horiz_segs (GimpBoundary *boundary,
static GimpBoundary *
generate_boundary (GeglBuffer *buffer,
const GeglRectangle *region,
+ const Babl *format,
GimpBoundaryType type,
gint x1,
gint y1,
gint x2,
gint y2,
- guchar threshold)
+ gfloat threshold)
{
GimpBoundary *boundary;
- const Babl *format;
GeglRectangle line_rect = { 0, };
- guchar *line_data;
- gint bpp;
+ gfloat *line_data;
gint scanline;
gint i;
gint start, end;
@@ -680,14 +683,10 @@ generate_boundary (GeglBuffer *buffer,
boundary = gimp_boundary_new (region);
- /* XXX use an appropriate format here */
- format = gegl_buffer_get_format (buffer);
- bpp = babl_format_get_bytes_per_pixel (format);
-
line_rect.width = gegl_buffer_get_width (buffer);
line_rect.height = 1;
- line_data = g_alloca (bpp * line_rect.width);
+ line_data = g_alloca (sizeof (gfloat) * line_rect.width);
start = 0;
end = 0;
@@ -704,7 +703,7 @@ generate_boundary (GeglBuffer *buffer,
}
/* Find the empty segments for the previous and current scanlines */
- find_empty_segs (region, NULL, bpp,
+ find_empty_segs (region, NULL,
start - 1, boundary->empty_segs_l,
boundary->max_empty_segs, &num_empty_l,
type, x1, y1, x2, y2,
@@ -715,7 +714,7 @@ generate_boundary (GeglBuffer *buffer,
line_data, GEGL_AUTO_ROWSTRIDE,
GEGL_ABYSS_NONE);
- find_empty_segs (region, line_data, bpp,
+ find_empty_segs (region, line_data,
start, boundary->empty_segs_c,
boundary->max_empty_segs, &num_empty_c,
type, x1, y1, x2, y2,
@@ -732,7 +731,7 @@ generate_boundary (GeglBuffer *buffer,
line_data, GEGL_AUTO_ROWSTRIDE,
GEGL_ABYSS_NONE);
- find_empty_segs (region, line_data, bpp,
+ find_empty_segs (region, line_data,
scanline + 1, boundary->empty_segs_n,
boundary->max_empty_segs, &num_empty_n,
type, x1, y1, x2, y2,
diff --git a/app/core/gimpboundary.h b/app/core/gimpboundary.h
index fabda66..29049ad 100644
--- a/app/core/gimpboundary.h
+++ b/app/core/gimpboundary.h
@@ -20,7 +20,7 @@
/* half intensity for mask */
-#define GIMP_BOUNDARY_HALF_WAY 127
+#define GIMP_BOUNDARY_HALF_WAY 0.5
typedef enum
@@ -43,12 +43,13 @@ struct _GimpBoundSeg
GimpBoundSeg * gimp_boundary_find (GeglBuffer *buffer,
const GeglRectangle *region,
+ const Babl *format,
GimpBoundaryType type,
gint x1,
gint y1,
gint x2,
gint y2,
- guchar threshold,
+ gfloat threshold,
gint *num_segs);
GimpBoundSeg * gimp_boundary_sort (const GimpBoundSeg *segs,
gint num_segs,
diff --git a/app/core/gimpbrush-boundary.c b/app/core/gimpbrush-boundary.c
index 98eec01..3d2e863 100644
--- a/app/core/gimpbrush-boundary.c
+++ b/app/core/gimpbrush-boundary.c
@@ -50,11 +50,12 @@ gimp_brush_transform_boundary_exact (GimpBrush *brush,
buffer = gimp_temp_buf_create_buffer ((GimpTempBuf *) mask);
bound_segs = gimp_boundary_find (buffer, NULL,
+ babl_format ("Y float"),
GIMP_BOUNDARY_WITHIN_BOUNDS,
0, 0,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer),
- 0,
+ 0.0,
&n_bound_segs);
g_object_unref (buffer);
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 7ad30e8..a1fc90a 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -995,6 +995,7 @@ gimp_channel_real_boundary (GimpChannel *channel,
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (channel));
channel->segs_out = gimp_boundary_find (buffer, &rect,
+ babl_format ("Y float"),
GIMP_BOUNDARY_IGNORE_BOUNDS,
x1, y1, x2, y2,
GIMP_BOUNDARY_HALF_WAY,
@@ -1007,6 +1008,7 @@ gimp_channel_real_boundary (GimpChannel *channel,
if (x2 > x1 && y2 > y1)
{
channel->segs_in = gimp_boundary_find (buffer, NULL,
+ babl_format ("Y float"),
GIMP_BOUNDARY_WITHIN_BOUNDS,
x1, y1, x2, y2,
GIMP_BOUNDARY_HALF_WAY,
diff --git a/app/core/gimplayer-floating-sel.c b/app/core/gimplayer-floating-sel.c
index ab3f4d9..6eb00db 100644
--- a/app/core/gimplayer-floating-sel.c
+++ b/app/core/gimplayer-floating-sel.c
@@ -215,6 +215,7 @@ floating_sel_boundary (GimpLayer *layer,
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
layer->fs.segs = gimp_boundary_find (buffer, NULL,
+ babl_format ("A float"),
GIMP_BOUNDARY_WITHIN_BOUNDS,
0, 0, width, height,
GIMP_BOUNDARY_HALF_WAY,
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index 758508e..af0b471 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -134,6 +134,12 @@ gimp_gegl_init (Gimp *gimp)
babl_component ("A"),
NULL);
+ babl_format_new ("name", "A float",
+ babl_model ("R'G'B'A"),
+ babl_type ("float"),
+ babl_component ("A"),
+ NULL);
+
babl_format_new ("name", "A double",
babl_model ("R'G'B'A"),
babl_type ("double"),
diff --git a/app/tools/gimpregionselecttool.c b/app/tools/gimpregionselecttool.c
index 732de58..63c2399 100644
--- a/app/tools/gimpregionselecttool.c
+++ b/app/tools/gimpregionselecttool.c
@@ -369,6 +369,7 @@ gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (region_sel->region_mask));
segs = gimp_boundary_find (buffer, NULL,
+ babl_format ("Y float"),
GIMP_BOUNDARY_WITHIN_BOUNDS,
0, 0,
gimp_item_get_width (GIMP_ITEM (region_sel->region_mask)),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]