Imager
view release on metacpan or search on metacpan
static int
i_ccomp_border(i_color const *val1, i_color const *val2, int ch) {
int i;
for(i = 0; i < ch; i++)
if (val1->channel[i] !=val2->channel[i])
return 1;
return 0;
}
static int
i_lspan(i_img *im, i_img_dim seedx, i_img_dim seedy, i_color const *val, ff_cmpfunc cmpfunc) {
i_color cval;
while(1) {
if (seedx-1 < 0) break;
i_gpix(im,seedx-1,seedy,&cval);
if (!cmpfunc(val,&cval,im->channels))
break;
seedx--;
}
return seedx;
}
static int
i_rspan(i_img *im, i_img_dim seedx, i_img_dim seedy, i_color const *val, ff_cmpfunc cmpfunc) {
i_color cval;
while(1) {
if (seedx+1 > im->xsize-1) break;
i_gpix(im,seedx+1,seedy,&cval);
if (!cmpfunc(val,&cval,im->channels)) break;
seedx++;
}
return seedx;
}
#ifdef DEBUG_FLOOD_FILL
#define ST_PUSH_NOTE(left, right, dadl, dadr, y, dir) \
fprintf(stderr, "push(left %" i_DF ", right %" i_DF ", dadleft %" i_DF ", dadright %" i_DF ", y %" i_DF ", dir %d, line %d)\n", \
i_DFc(left), i_DFc(right), i_DFc(dadl), i_DFc(dadr), i_DFc(y), (dir), __LINE__)
#define ST_POP_NOTE(left, right, dadl, dadr, y, dir) \
fprintf(stderr, "popped(left %" i_DF ", right %" i_DF ", dadleft %" i_DF ", dadright %" i_DF ", y %" i_DF ", dir %d, line %d)\n", \
i_DFc(left), i_DFc(right), i_DFc(dadl), i_DFc(dadr), i_DFc(y), (dir), __LINE__)
#define ST_STACK_NOTE(dadl, dadr, left, right, y, dir) \
fprintf(stderr, "stack(left %" i_DF ", right %" i_DF ", dadleft %" i_DF ", dadright %" i_DF ", y %" i_DF ", dir %d, line %d)\n", \
i_DFc(left), i_DFc(right), i_DFc(dadl), i_DFc(dadr), i_DFc(y), (dir), __LINE__)
#else
#define ST_PUSH_NOTE(left, right, dadl, dadr, y, dir)
#define ST_POP_NOTE(left, right, dadl, dadr, y, dir)
#define ST_STACK_NOTE(dadl, dadr, left, right, y, dir)
#endif
/* Macro to create a link and push on to the list */
#define ST_PUSH(left,right,dadl,dadr,y,dir) do { \
struct stack_element *s = crdata(left,right,dadl,dadr,y,dir); \
ST_PUSH_NOTE(left, right, dadl, dadr, y, dir); \
llist_push(st,&s); \
} while (0)
/* pops the shadow on TOS into local variables lx,rx,y,direction,dadLx and dadRx */
/* No overflow check! */
#define ST_POP() do { \
struct stack_element *s; \
llist_pop(st,&s); \
lx = s->myLx; \
rx = s->myRx; \
dadLx = s->dadLx; \
dadRx = s->dadRx; \
y = s->myY; \
direction = s->myDirection; \
ST_POP_NOTE(lx, rx, dadLx, dadRx, y, direction); \
myfree(s); \
} while (0)
#define ST_STACK(dir,dadLx,dadRx,lx,rx,y) do { \
i_img_dim pushrx = rx+1; \
i_img_dim pushlx = lx-1; \
ST_STACK_NOTE(lx, rx, dadLx, dadRx, y, dir); \
ST_PUSH(lx,rx,pushlx,pushrx,y+dir,dir); \
if (rx > dadRx) \
ST_PUSH(dadRx+1,rx,pushlx,pushrx,y-dir,-dir); \
if (lx < dadLx) \
ST_PUSH(lx,dadLx-1,pushlx,pushrx,y-dir,-dir); \
} while (0)
#define SET(x,y) btm_set(btm,x,y)
/* INSIDE returns true if pixel is correct color and we haven't set it before. */
#define INSIDE(x,y, seed) \
(assert((x) >= 0 && (x) < (im)->xsize && (y) >= 0 && (y) < (im)->ysize), \
(!btm_test(btm,x,y) && \
( i_gpix(im,x,y,&cval),cmpfunc(seed,&cval,channels) ) ))
/* The function that does all the real work */
static struct i_bitmap *
i_flood_fill_low(i_img *im,i_img_dim seedx,i_img_dim seedy,
i_img_dim *bxminp, i_img_dim *bxmaxp, i_img_dim *byminp, i_img_dim *bymaxp,
i_color const *seed, ff_cmpfunc cmpfunc) {
i_img_dim ltx, rtx;
i_img_dim tx = 0;
i_img_dim bxmin = seedx;
i_img_dim bxmax = seedx;
i_img_dim bymin = seedy;
i_img_dim bymax = seedy;
struct llist *st;
struct i_bitmap *btm;
int channels;
( run in 0.681 second using v1.01-cache-2.11-cpan-99c4e6809bf )