[gegl] Respect the threshold parameter when finding the outline
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] Respect the threshold parameter when finding the outline
- Date: Tue, 14 May 2013 22:19:38 +0000 (UTC)
commit 44eef97f43f49c6db9c3ab1577b6de9726be2d42
Author: Barak Itkin <lightningismyname gmail com>
Date: Sat Sep 29 19:44:26 2012 +0200
Respect the threshold parameter when finding the outline
operations/common/seamless-clone/sc-common.h | 7 +++
operations/common/seamless-clone/sc-context.c | 16 ++-----
operations/common/seamless-clone/sc-outline.c | 57 ++++++++++--------------
operations/common/seamless-clone/sc-outline.h | 25 ++++++-----
4 files changed, 50 insertions(+), 55 deletions(-)
---
diff --git a/operations/common/seamless-clone/sc-common.h b/operations/common/seamless-clone/sc-common.h
index 604f213..12f9b86 100644
--- a/operations/common/seamless-clone/sc-common.h
+++ b/operations/common/seamless-clone/sc-common.h
@@ -77,4 +77,11 @@ typedef struct {
gboolean render_bg;
} ScRenderInfo;
+#define sc_point_in_rectangle(px, py, rect) \
+ ( ((px) >= (rect)->x) \
+ && ((py) >= (rect)->y) \
+ && ((px) < (rect)->x + (rect)->width) \
+ && ((py) < (rect)->y + (rect)->height) \
+ )
+
#endif
diff --git a/operations/common/seamless-clone/sc-context.c b/operations/common/seamless-clone/sc-context.c
index fcbea7e..83ed022 100644
--- a/operations/common/seamless-clone/sc-context.c
+++ b/operations/common/seamless-clone/sc-context.c
@@ -123,7 +123,7 @@ sc_context_create_outline (GeglBuffer *input,
ScCreationError *error)
{
gboolean ignored_islands = FALSE;
- ScOutline *outline = sc_outline_find (roi, input, &ignored_islands);
+ ScOutline *outline = sc_outline_find (roi, input, threshold, &ignored_islands);
guint length = sc_outline_length (outline);
*error = SC_CREATION_ERROR_NONE;
@@ -144,7 +144,7 @@ sc_context_create_outline (GeglBuffer *input,
*error = SC_CREATION_ERROR_TOO_SMALL;
}
else if (ignored_islands ||
- ! sc_outline_check_if_single (roi, input, outline))
+ ! sc_outline_check_if_single (roi, input, threshold, outline))
{
*error = SC_CREATION_ERROR_HOLED_OR_SPLIT;
}
@@ -425,19 +425,13 @@ sc_context_sample_color_difference (ScRenderInfo *info,
* location in background coordinates is the following:
* (pt->x + info->x, pt->y + info->y).
*/
-#define sc_rect_contains(rect,x0,y0) \
- (((x0) >= (rect).x) && ((x0) < (rect).x + (rect).width) \
- && ((y0) >= (rect).y) && ((y0) < (rect).y + (rect).height))
-
- if (! sc_rect_contains (info->bg_rect,
- x + info->xoff,
- y + info->yoff))
+ if (! sc_point_in_rectangle (x + info->xoff,
+ y + info->yoff,
+ &info->bg_rect))
{
return FALSE;
}
-#undef sc_rect_contains
-
gegl_buffer_sample (info->fg,
x, y,
NULL, fg_c, format,
diff --git a/operations/common/seamless-clone/sc-outline.c b/operations/common/seamless-clone/sc-outline.c
index 7f72e8b..0c56908 100644
--- a/operations/common/seamless-clone/sc-outline.c
+++ b/operations/common/seamless-clone/sc-outline.c
@@ -22,7 +22,7 @@
*
* Terminology:
*
- * Opaque - A pixel with alpha of at least 0.5
+ * Opaque - A pixel with alpha of at least a given threshold
* Island - An opaque pixel with 8 non-opaque neighbors
* Edge - An opaque pixel with at least 1 (out of 8) non-opaque
* neighbors
@@ -41,6 +41,7 @@
#include <gegl.h>
#include "sc-outline.h"
+#include "sc-common.h"
static inline void
sc_point_copy_to (const ScPoint *src,
@@ -77,36 +78,21 @@ sc_point_eq (const ScPoint *pt1,
}
static inline gboolean
-in_range (gint val,
- gint min,
- gint max)
-{
- return (min <= val) && (val <= max);
-}
-
-static inline gboolean
-in_rectangle (const GeglRectangle *rect,
- const ScPoint *pt)
-{
- return in_range (pt->x, rect->x, rect->x + rect->width - 1)
- && in_range (pt->y, rect->y, rect->y + rect->height - 1);
-}
-
-static inline gboolean
is_opaque (const GeglRectangle *search_area,
GeglBuffer *buffer,
const Babl *format,
+ gdouble threshold,
const ScPoint *pt)
{
- gfloat col[4] = {0, 0, 0, 0};
+ ScColor col[SC_COLORA_CHANNEL_COUNT];
- if (! in_rectangle (search_area, pt))
+ if (! sc_point_in_rectangle (pt->x, pt->y, search_area))
return FALSE;
gegl_buffer_sample (buffer, pt->x, pt->y, NULL, col, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- return col[3] >= 0.5f;
+ return col[SC_COLOR_ALPHA_INDEX] >= threshold;
}
/* This function assumes the pixel is opaque! */
@@ -114,13 +100,14 @@ static inline gboolean
is_opaque_island (const GeglRectangle *search_area,
GeglBuffer *buffer,
const Babl *format,
+ gdouble threshold,
const ScPoint *pt)
{
gint i;
ScPoint temp;
for (i = 0; i < 8; ++i)
- if (is_opaque (search_area, buffer, format, sc_point_move (pt, i, &temp)))
+ if (is_opaque (search_area, buffer, format, threshold, sc_point_move (pt, i, &temp)))
return FALSE;
return TRUE;
@@ -132,16 +119,17 @@ static inline gboolean
is_valid_edge (const GeglRectangle *search_area,
GeglBuffer *buffer,
const Babl *format,
+ gdouble threshold,
const ScPoint *pt)
{
gint i;
ScPoint temp;
- if (! is_opaque (search_area, buffer, format, pt))
+ if (! is_opaque (search_area, buffer, format, threshold, pt))
return FALSE;
- for (i = 0; i < 8; ++i)
- if (is_opaque (search_area, buffer, format, sc_point_move (pt, i, &temp)))
+ for (i = 0; i < SC_DIRECTION_COUNT; ++i)
+ if (is_opaque (search_area, buffer, format, threshold, sc_point_move (pt, i, &temp)))
return FALSE;
return TRUE;
@@ -166,6 +154,7 @@ static inline ScDirection
walk_cw (const GeglRectangle *search_area,
GeglBuffer *buffer,
const Babl *format,
+ gdouble threshold,
const ScPoint *cur_pt,
ScDirection dir_from_prev,
ScPoint *next_pt)
@@ -175,7 +164,7 @@ walk_cw (const GeglRectangle *search_area,
sc_point_move (cur_pt, dir_to_next, next_pt);
- while (! is_opaque (search_area, buffer, format, next_pt))
+ while (! is_opaque (search_area, buffer, format, threshold, next_pt))
{
dir_to_next = SC_DIRECTION_CW (dir_to_next);
sc_point_move (cur_pt, dir_to_next, next_pt);
@@ -194,6 +183,7 @@ walk_cw (const GeglRectangle *search_area,
ScOutline*
sc_outline_find (const GeglRectangle *search_area,
GeglBuffer *buffer,
+ gdouble threshold,
gboolean *ignored_islands)
{
const Babl *format = babl_format("RGBA float");
@@ -209,9 +199,9 @@ sc_outline_find (const GeglRectangle *search_area,
for (current.y = search_area->y; current.y < row_max; ++current.y)
{
for (current.x = search_area->x; current.x < col_max; ++current.x)
- if (is_opaque (search_area, buffer, format, ¤t))
+ if (is_opaque (search_area, buffer, format, threshold, ¤t))
{
- if (is_opaque_island (search_area, buffer, format, ¤t))
+ if (is_opaque_island (search_area, buffer, format, threshold, ¤t))
{
if (ignored_islands)
*ignored_islands = TRUE;
@@ -232,16 +222,16 @@ sc_outline_find (const GeglRectangle *search_area,
current.outside_normal = SC_DIRECTION_N;
g_ptr_array_add (result, first = sc_point_copy (¤t));
- to_next = walk_cw (search_area, buffer, format, ¤t,
- SC_DIRECTION_E, &next);
+ to_next = walk_cw (search_area, buffer, format, threshold,
+ ¤t, SC_DIRECTION_E, &next);
while (! sc_point_eq (&next, first))
{
next.outside_normal = SC_DIRECTION_CW(SC_DIRECTION_CW(to_next));
g_ptr_array_add (result, sc_point_copy (&next));
sc_point_copy_to (&next, ¤t);
- to_next = walk_cw (search_area, buffer, format, ¤t,
- to_next, &next);
+ to_next = walk_cw (search_area, buffer, format, threshold,
+ ¤t, to_next, &next);
}
}
@@ -292,6 +282,7 @@ sc_point_cmp (const ScPoint **pt1,
gboolean
sc_outline_check_if_single (const GeglRectangle *search_area,
GeglBuffer *buffer,
+ gdouble threshold,
ScOutline *existing)
{
const Babl *format = babl_format("RGBA float");
@@ -319,7 +310,7 @@ sc_outline_check_if_single (const GeglRectangle *search_area,
{
gboolean hit, opaque;
- opaque = is_opaque (search_area, buffer, format, ¤t);
+ opaque = is_opaque (search_area, buffer, format, threshold, ¤t);
hit = sc_point_eq (¤t, sorted_p);
if (hit && ! inside)
@@ -331,7 +322,7 @@ sc_outline_check_if_single (const GeglRectangle *search_area,
}
if (inside != opaque
- && ! (opaque && is_opaque_island (search_area, buffer, format, ¤t)))
+ && ! (opaque && is_opaque_island (search_area, buffer, format, threshold, ¤t)))
{
not_single = FALSE;
break;
diff --git a/operations/common/seamless-clone/sc-outline.h b/operations/common/seamless-clone/sc-outline.h
index d49c812..4636cda 100644
--- a/operations/common/seamless-clone/sc-outline.h
+++ b/operations/common/seamless-clone/sc-outline.h
@@ -39,19 +39,20 @@
* </pre>
*/
typedef enum {
- SC_DIRECTION_N = 0,
- SC_DIRECTION_NE = 1,
- SC_DIRECTION_E = 2,
- SC_DIRECTION_SE = 3,
- SC_DIRECTION_S = 4,
- SC_DIRECTION_SW = 5,
- SC_DIRECTION_W = 6,
- SC_DIRECTION_NW = 7
+ SC_DIRECTION_N = 0,
+ SC_DIRECTION_NE = 1,
+ SC_DIRECTION_E = 2,
+ SC_DIRECTION_SE = 3,
+ SC_DIRECTION_S = 4,
+ SC_DIRECTION_SW = 5,
+ SC_DIRECTION_W = 6,
+ SC_DIRECTION_NW = 7,
+ SC_DIRECTION_COUNT = 8
} ScDirection;
-#define SC_DIRECTION_CW(d) (((d)+1)%8)
-#define SC_DIRECTION_CCW(d) (((d)+7)%8)
-#define SC_DIRECTION_OPPOSITE(d) (((d)+4)%8)
+#define SC_DIRECTION_CW(d) (((d) + 1) % 8)
+#define SC_DIRECTION_CCW(d) (((d) + 7) % 8)
+#define SC_DIRECTION_OPPOSITE(d) (((d) + 4) % 8)
#define SC_DIRECTION_IS_NORTH(d) ( \
((d) == SC_DIRECTION_N) || \
@@ -108,10 +109,12 @@ typedef GPtrArray ScOutline;
ScOutline* sc_outline_find (const GeglRectangle *rect,
GeglBuffer *pixels,
+ gdouble threshold,
gboolean *ignored_islands);
gboolean sc_outline_check_if_single (const GeglRectangle *search_area,
GeglBuffer *buffer,
+ gdouble threshold,
ScOutline *existing);
guint sc_outline_length (ScOutline *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]