[Pen-commits] SF.net SVN: pen:[117] src/maskutils.c
Brought to you by:
mdgeorge
From: <mdg...@us...> - 2008-12-03 23:44:28
|
Revision: 117 http://pen.svn.sourceforge.net/pen/?rev=117&view=rev Author: mdgeorge Date: 2008-12-03 23:44:26 +0000 (Wed, 03 Dec 2008) Log Message: ----------- Added in bitmask_convolve and bitmask_find_closest from history. Modified Paths: -------------- src/maskutils.c Modified: src/maskutils.c =================================================================== --- src/maskutils.c 2008-12-03 23:43:41 UTC (rev 116) +++ src/maskutils.c 2008-12-03 23:44:26 UTC (rev 117) @@ -1,6 +1,10 @@ #include <Python.h> #include <mask.h> +/* +** Declarations and python magic *********************************************** +*/ + static const char DOC_CONVOLVE[] = "Return the convolution of self with another mask. \n" " \n" @@ -31,16 +35,80 @@ }; void -initmaskutils() +initmaskutils(void) { - PyInitModule ("maskutils", maskutils_methods); + Py_InitModule ("maskutils", maskutils_methods); } /* -** Implementations ************************************************************* +** Python method implementations *********************************************** */ static +void +bitmask_convolve(const bitmask_t *a, const bitmask_t *b, bitmask_t *o, int xoffset, int yoffset) +{ + int x, y; + + xoffset += b->w - 1; + yoffset += b->h - 1; + for (y = 0; y < b->h; y++) + for (x = 0; x < b->w; x++) + if (bitmask_getbit(b, x, y)) + bitmask_draw(o, a, xoffset - x, yoffset - y); +} + +static inline +int +valid(const bitmask_t *mask, int x, int y) +{ + return x < 0 || y < 0 || + x >= mask->w || y >= mask->h || + !bitmask_getbit(mask,x,y); +} + +static +void +bitmask_find_closest(const bitmask_t *mask, int *x, int *y) +{ +#define SQ(x) (x)*(x) + + /* this method is either very elegant or very ugly. */ + int best_d = SQ(*x + 1), best_x = -1, best_y = *y; + int covered; + +#define check_point(dist,x,y) \ + if(dist < best_d) { \ + best_d = dist; \ + best_x = x; \ + best_y = y; \ + } + + if (valid(mask, *x, *y)) + check_point(0, *x, *y); + + /* loop invariant: I've at least looked at everything of distance less than less than covered */ + for (covered = 1; SQ(covered) <= best_d; covered++) + { + int sx, sy, i; + +#define check_row(xi, yi) \ + sx = *x - (xi)*covered + (yi)*covered; \ + sy = *y - (yi)*covered - (xi)*covered; \ + for (i = 0; i < 2*covered; i++, sx += xi, sy += yi) \ + if (valid(mask, sx, sy)) \ + check_point(SQ(*x-sx) + SQ(*y-sy), sx, sy); + + check_row(1,0); + check_row(-1,0); + check_row(0,1); + check_row(0,-1); + } + + *x = best_x; *y = best_y; +} + +static PyObject * maskutils_convolve(PyObject *self /* Not used */, PyObject *args) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |