Sujet : Re: filling area by color atack safety
De : tr.17687 (at) *nospam* z991.linuxsc.com (Tim Rentsch)
Groupes : comp.lang.cDate : 30. Mar 2024, 19:59:03
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <86cyrbim14.fsf@linuxsc.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12
User-Agent : Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Michael S <
already5chosen@yahoo.com> writes:
On Thu, 28 Mar 2024 23:04:36 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Intrigued by your idea, I wrote something along the same lines,
only shorter and (at least for me) a little easier to grok.
If someone is interested I can post it.
>
If non-trivially different, why not?
Here is the code:
void
stack_fill( UI w0, UI h0, UC pixels[], Point p0, UC old, UC new ){
U64 w = ( assert( w0 > 0 ), w0 );
U64 h = ( assert( h0 > 0 ), h0 );
U64 px = ( assert( p0.x < w ), p0.x );
U64 py = ( assert( p0.y < h ), p0.y );
UC *x0 = ( assert( pixels ), pixels );
UC *x = x0 + px*h;
UC *xm = x0 + h*w - h;
U64 y0 = 0;
U64 y = py;
U64 ym = h-1;
UC *s0 = malloc( sizeof *s0 );
UC *s = s0;
UC *sn = s0 ? s0+1 : s0;
if( s0 && x[y] == old ) do {
x[y] = new;
if( s == sn ){
U64 s_offset = s - s0;
U64 n = (sn-s0+1) *3 /2;
UC *new_s0 = realloc( s0, n * sizeof *new_s0 );
if( ! new_s0 ) break;
s0 = new_s0, s = s0 + s_offset, sn = s0 + n;
}
if( y < ym && x[y+1] == old ){
y += 1, *s++ = 2; continue; UNDO_UP:
y -= 1;
}
if( y > y0 && x[y-1] == old ){
y -= 1, *s++ = 3; continue; UNDO_DOWN:
y += 1;
}
if( x < xm && y[x+h] == old ){
x += h, *s++ = 0; continue; UNDO_LEFT:
x -= h;
}
if( x > x0 && y[x-h] == old ){
x -= h, *s++ = 1; continue; UNDO_RIGHT:
x += h;
}
if( s == s0 ) break;
switch( *--s & 3 ){
case 0: goto UNDO_LEFT;
case 1: goto UNDO_RIGHT;
case 2: goto UNDO_UP;
case 3: goto UNDO_DOWN;
}
} while( 1 );
free( s0 );
}