[SDL] fillflood algo and SDL.

Charles Vidal vidalc at ifrance.com
Mon Jan 8 06:48:59 PST 2001


Hi thank's for your reply:
I send you a not recursive sdl function , I have found 

http://www.acm.org/tog/GraphicsGems/ ( thank's frank for this link :).

It's seem to work , and don't make any core dump.

void setPixels(SDL_Surface *s,int x,int y,Uint32 c);
Uint32 getPixels(SDL_Surface *s,int x,int y);
/*
 * A Seed Fill Algorithm
 * by Paul Heckbert
 * from "Graphics Gems", Academic Press, 1990
 *
 * user provides pixelread() and pixelwrite() routines
 */
typedef struct {short y, xl, xr, dy;} Segment;

/*
 * Filled horizontal segment of scanline y for xl<=x<=xr.
 * Parent segment was on line y-dy.  dy=1 or -1
 */

#define MAX 10000               /* max depth of stack */

#define PUSH(Y, XL, XR, DY,S)   /* push new segment on stack */ \
    if (sp<stack+MAX && Y+(DY)>=0 && Y+(DY)<=S->h)  \
    {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}

#define POP(Y, XL, XR, DY)      /* pop segment off stack */ \
    {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}

/*
 * fill: set the pixel at (x,y) and all of its 4-connected neighbors
 * with the same pixel value to the new pixel value nv.
 * A 4-connected neighbor is a pixel above, below, left, or right of a
pixel.
 */
/******************************/
void floodfill(SDL_Surface *win,int x,int  y, Uint32 nv)
{
    int l, x1, x2, dy;
    Segment stack[MAX], *sp = stack;    /* stack of filled segments */
    Uint32 ov=getPixels(win,x,y);

    if (x<0 || y<0 || x>=win->w || y>=win->h ) return;
    if (ov==nv) return;
    PUSH(y, x, x, 1,win);                       /* needed in some cases
*/
    PUSH(y+1, x, x, -1,win);            /* seed segment (popped 1st) */

    while (sp>stack) {
        /* pop segment off stack and fill a neighboring scan line */
        POP(y, x1, x2, dy);
        /*
         * segment of scan line y-dy for x1<=x<=x2 was previously
filled,
         * now explore adjacent pixels in scan line y
         */
        for (x=x1; x>=0 && getPixels(win,x, y)==ov; x--)
setPixels(win,x,y,nv);
        if (x>=x1) goto skip;
        l = x+1;
        if (l<x1) PUSH(y, l, x1-1, -dy,win);            /* leak on left?
*/
        x = x1+1;
        do {
            for (; x<=win->w && getPixels(win,x, y)==ov; x++)
                setPixels(win,x, y, nv);
            PUSH(y, l, x-1, dy,win);
            if (x>x2+1) PUSH(y, x2+1, x-1, -dy,win);    /* leak on
right? */
skip:       for (x++; x<=x2 && getPixels(win,x, y)!=ov; x++);
            l = x;
        } while (x<=x2);
    }
}

charles.






More information about the SDL mailing list