Imager

 view release on metacpan or  search on metacpan

draw.c  view on Meta::CPAN


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 )