[gegl/soc-2011-seamless-clone: 8/17] Don't do malloc for the entire paste - sample it instead
- From: Barak Itkin <barakitkin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2011-seamless-clone: 8/17] Don't do malloc for the entire paste - sample it instead
- Date: Sat, 17 Mar 2012 19:19:46 +0000 (UTC)
commit 3dd348db2ae63ef747e12095a03a24ca98568979
Author: Barak Itkin <lightningismyname gmail com>
Date: Wed Aug 3 12:47:03 2011 +0300
Don't do malloc for the entire paste - sample it instead
operations/common/seamless-clone/find-outline.c | 42 ++++++++++++--------
operations/common/seamless-clone/find-outline.h | 2 +-
operations/common/seamless-clone/seamless-clone.c | 12 +----
3 files changed, 29 insertions(+), 27 deletions(-)
---
diff --git a/operations/common/seamless-clone/find-outline.c b/operations/common/seamless-clone/find-outline.c
index acd0db1..eef86ab 100644
--- a/operations/common/seamless-clone/find-outline.c
+++ b/operations/common/seamless-clone/find-outline.c
@@ -75,7 +75,7 @@ typedef enum {
* Add a COPY of the given point into the array pts. The original point CAN
* be freed later!
*/
-static void
+static inline void
add_point (GPtrArray* pts, ScPoint *pt)
{
ScPoint *cpy = g_slice_new (ScPoint);
@@ -85,33 +85,39 @@ add_point (GPtrArray* pts, ScPoint *pt)
g_ptr_array_add (pts, cpy);
}
-static void
+static inline void
spoint_move (ScPoint *pt, OUTLINE_DIRECTION t, ScPoint *dest)
{
dest->x = pt->x + (isEast(t) ? 1 : (isWest(t) ? -1 : 0));
dest->y = pt->y + (isSouth(t) ? 1 : (isNorth(t) ? -1 : 0));
}
-static gboolean
+static inline gboolean
in_range(gint val,gint min,gint max)
{
return (((min) <= (val)) && ((val) <= (max)));
}
-#define buf_offset(rect,x0,y0) (((y0) - (rect)->y) * (rect)->width + (x0))
-#define buf_offset_PT(rect,pt) buf_offset((rect),(pt)->x,(pt)->y)
+static inline gfloat
+sc_sample_alpha (GeglBuffer *buf, gint x, gint y, Babl *format)
+{
+ gfloat col[4] = {0, 0, 0, 0};
+ gegl_buffer_sample (buf, x, y, NULL, col, format, GEGL_INTERPOLATION_NEAREST);
+ return col[3];
+}
-static gboolean
+static inline gboolean
is_opaque (GeglRectangle *rect,
- gfloat *pixels,
- ScPoint *pt)
+ GeglBuffer *pixels,
+ Babl *format,
+ ScPoint *pt)
{
g_assert (pt != NULL);
g_assert (rect != NULL);
return in_range(pt->x, rect->x, rect->x + rect->width - 1)
&& in_range(pt->y, rect->y, rect->y + rect->height - 1)
- && (pixels[buf_offset_PT(rect,pt)*4+3] >= 0.5f);
+ && (sc_sample_alpha (pixels, pt->x, pt->y, format) >= 0.5f);
}
/* This function receives a white pixel (pt) and the direction of the movement
@@ -130,10 +136,11 @@ is_opaque (GeglRectangle *rect,
*/
static inline OUTLINE_DIRECTION
outline_walk_cw (GeglRectangle *rect,
- gfloat *pixels,
+ GeglBuffer *pixels,
+ Babl *format,
OUTLINE_DIRECTION prevdirection,
- ScPoint *pt,
- ScPoint *dest)
+ ScPoint *pt,
+ ScPoint *dest)
{
OUTLINE_DIRECTION Dprev = oppositedirection(prevdirection);
OUTLINE_DIRECTION Dnow = cwdirection (Dprev);
@@ -143,7 +150,7 @@ outline_walk_cw (GeglRectangle *rect,
spoint_move (pt, Dprev, &ptP);
spoint_move (pt, Dnow, &ptN);
- while (is_opaque (rect, pixels, &ptN))
+ while (is_opaque (rect, pixels, format, &ptN))
{
Dprev = Dnow;
ptP.x = ptN.x;
@@ -161,8 +168,9 @@ outline_walk_cw (GeglRectangle *rect,
GPtrArray*
sc_outline_find_ccw (GeglRectangle *rect,
- gfloat *pixels)
+ GeglBuffer *pixels)
{
+ Babl *format = babl_format("RGBA float");
GPtrArray *points = g_ptr_array_new ();
gint x = rect->x, y;
@@ -176,7 +184,7 @@ sc_outline_find_ccw (GeglRectangle *rect,
{
for (x = rect->x; x < rect->x + rect->width; x++)
{
- if (pixels[buf_offset(rect,x,y)*4+3] >= 0.5f)
+ if (sc_sample_alpha (pixels, x, y, format) >= 0.5f)
{
found = TRUE;
break;
@@ -194,7 +202,7 @@ sc_outline_find_ccw (GeglRectangle *rect,
add_point (points, &START);
- DIRN = outline_walk_cw (rect, pixels, DIR,&pt,&ptN);
+ DIRN = outline_walk_cw (rect, pixels, format, DIR,&pt,&ptN);
while (! pteq(&ptN,&START))
{
@@ -202,7 +210,7 @@ sc_outline_find_ccw (GeglRectangle *rect,
pt.x = ptN.x;
pt.y = ptN.y;
DIR = DIRN;
- DIRN = outline_walk_cw (rect, pixels, DIR,&pt,&ptN);
+ DIRN = outline_walk_cw (rect, pixels, format, DIR,&pt,&ptN);
}
g_debug ("Outline has %d points", points->len);
diff --git a/operations/common/seamless-clone/find-outline.h b/operations/common/seamless-clone/find-outline.h
index 79dcd4c..a708c54 100644
--- a/operations/common/seamless-clone/find-outline.h
+++ b/operations/common/seamless-clone/find-outline.h
@@ -33,7 +33,7 @@ typedef struct {
*/
typedef GPtrArray ScOutline;
-ScOutline* sc_outline_find_ccw (GeglRectangle *rect, gfloat *pixels);
+ScOutline* sc_outline_find_ccw (GeglRectangle *rect, GeglBuffer *pixels);
void sc_outline_free (ScOutline *self);
diff --git a/operations/common/seamless-clone/seamless-clone.c b/operations/common/seamless-clone/seamless-clone.c
index d2a2474..f6d251d 100644
--- a/operations/common/seamless-clone/seamless-clone.c
+++ b/operations/common/seamless-clone/seamless-clone.c
@@ -138,7 +138,7 @@ process (GeglOperation *operation,
GeglBuffer *output,
const GeglRectangle *result)
{
- gfloat *aux_raw, *out_raw, *pixel;
+ gfloat *out_raw, *pixel;
gdouble x, y;
GeglRectangle aux_rect = *gegl_operation_source_get_bounding_box (operation, "aux");
@@ -163,17 +163,11 @@ process (GeglOperation *operation,
/********************************************************************/
/* Part 1: The preprocessing */
/********************************************************************/
-
- /* First, find the paste outline */
- aux_raw = g_new (gfloat, 4 * aux_rect.width * aux_rect.height);
- gegl_buffer_get (aux, 1.0, &aux_rect, format, aux_raw, GEGL_AUTO_ROWSTRIDE);
+ /* First, find the paste outline */
g_debug ("Start making outline");
- outline = sc_outline_find_ccw (&aux_rect, aux_raw);
+ outline = sc_outline_find_ccw (&aux_rect, aux);
g_debug ("Finish making outline");
-
- g_free (aux_raw);
- aux_raw = NULL;
/* Then, Generate the mesh */
g_debug ("Start making fine mesh");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]