From: Arnar Mar Hrafnkelsson Date: Tue, 30 Apr 2002 18:32:41 +0000 (+0000) Subject: Second attempt at flood fix. X-Git-Tag: Imager-0.48^2~373 X-Git-Url: http://git.imager.perl.org/imager.git/commitdiff_plain/e25e59b16051115c59eddd527220083aa72aa056?ds=sidebyside Second attempt at flood fix. --- diff --git a/datatypes.c b/datatypes.c index 33d27a5f..ec8e9535 100644 --- a/datatypes.c +++ b/datatypes.c @@ -40,6 +40,7 @@ btm_test(struct i_bitmap *btm,int x,int y) { void btm_set(struct i_bitmap *btm,int x,int y) { int btno; + if (x<0 || x>btm->xsize-1 || y<0 || y>btm->ysize-1) abort(); btno=btm->xsize*y+x; btm->data[btno/8]|=1<<(btno%8); } diff --git a/draw.c b/draw.c index e31e5fa6..5870779d 100644 --- a/draw.c +++ b/draw.c @@ -648,7 +648,7 @@ i_ccomp(i_color *val1,i_color *val2,int ch) { static int -i_lspan(i_img *im,int seedx,int seedy,i_color *val) { +i_lspan(i_img *im, int seedx, int seedy, i_color *val) { i_color cval; while(1) { if (seedx-1 < 0) break; @@ -660,7 +660,7 @@ i_lspan(i_img *im,int seedx,int seedy,i_color *val) { } static int -i_rspan(i_img *im,int seedx,int seedy,i_color *val) { +i_rspan(i_img *im, int seedx, int seedy, i_color *val) { i_color cval; while(1) { if (seedx+1 > im->xsize-1) break; @@ -673,16 +673,36 @@ i_rspan(i_img *im,int seedx,int seedy,i_color *val) { /* Macro to create a link and push on to the list */ -#define ST_PUSH(left,right,dadl,dadr,y,dir) { struct stack_element *s = crdata(left,right,dadl,dadr,y,dir); llist_push(st,&s); } +#define ST_PUSH(left,right,dadl,dadr,y,dir) do { \ + struct stack_element *s = crdata(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() { 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; myfree(s); } - -#define ST_STACK(dir,dadLx,dadRx,lx,rx,y) { int pushrx = rx+1; int pushlx = lx-1; 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); } - -#define SET(x,y) btm_set(btm,x,y); +#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; \ + myfree(s); \ +} while (0) + +#define ST_STACK(dir,dadLx,dadRx,lx,rx,y) do { \ + int pushrx = rx+1; \ + int pushlx = lx-1; \ + 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) #define INSIDE(x,y) ((!btm_test(btm,x,y) && ( i_gpix(im,x,y,&cval),i_ccomp(&val,&cval,channels) ) )) @@ -699,13 +719,16 @@ i_flood_fill(i_img *im, int seedx, int seedy, i_color *dcol) { /* int tx,ty; */ - int bxmin=seedx,bxmax=seedx,bymin=seedy,bymax=seedy; + int bxmin = seedx; + int bxmax = seedx; + int bymin = seedy; + int bymax = seedy; struct llist *st; struct i_bitmap *btm; int channels,xsize,ysize; - i_color cval,val; + i_color cval, val; channels = im->channels; xsize = im->xsize; @@ -724,10 +747,10 @@ i_flood_fill(i_img *im, int seedx, int seedy, i_color *dcol) { i_gpix(im,seedx,seedy,&val); /* Find the starting span and fill it */ - lx = i_lspan(im,seedx,seedy,&val); - rx = i_rspan(im,seedx,seedy,&val); + lx = i_lspan(im, seedx, seedy, &val); + rx = i_rspan(im, seedx, seedy, &val); - /* printf("span: %d %d \n",lx,rx); */ + printf("span: %d %d \n",lx,rx); for(x=lx; x<=rx; x++) SET(x,seedy); @@ -738,31 +761,37 @@ i_flood_fill(i_img *im, int seedx, int seedy, i_color *dcol) { ST_POP(); if (y<0 || y>ysize-1) continue; - if (x<0 || x>xsize-1) continue; + if (bymin > y) bymin=y; /* in the worst case an extra line */ if (bymax < y) bymax=y; - /* - printf("start of scan - on stack : %d \n",st->count); - printf("lx=%d rx=%d dadLx=%d dadRx=%d y=%d direction=%d\n",lx,rx,dadLx,dadRx,y,direction); - printf(" "); - for(tx=0;txcount); + printf("lx=%d rx=%d dadLx=%d dadRx=%d y=%d direction=%d\n",lx,rx,dadLx,dadRx,y,direction); + + + printf(" "); + for(tx=0;tx 0) { + while(lx>0 && INSIDE(lx,y)) { SET(lx,y); lx--; } @@ -850,15 +879,15 @@ i_flood_fill_low(i_img *im,int seedx,int seedy, i_gpix(im,seedx,seedy,&val); /* Find the starting span and fill it */ - lx=i_lspan(im,seedx,seedy,&val); - rx=i_rspan(im,seedx,seedy,&val); + lx = i_lspan(im, seedx, seedy, &val); + rx = i_rspan(im, seedx, seedy, &val); /* printf("span: %d %d \n",lx,rx); */ - for(x=lx;x<=rx;x++) SET(x,seedy); + for(x=lx; x<=rx; x++) SET(x, seedy); - ST_PUSH(lx,rx,lx,rx,seedy+1,1); - ST_PUSH(lx,rx,lx,rx,seedy-1,-1); + ST_PUSH(lx, rx, lx, rx, seedy+1, 1); + ST_PUSH(lx, rx, lx, rx, seedy-1, -1); while(st->count) { ST_POP();