fixed up flood other

This commit is contained in:
John Cupitt 2010-01-07 16:03:37 +00:00
parent 7ae8c491f2
commit 3cf1646b1d
4 changed files with 45 additions and 51 deletions

2
TODO
View File

@ -1,4 +1,4 @@
- flood_other gets stuck in a loop o the small_gold_discs test
- we sill have the old flood-fill code there, move to deprecated
- add a --without-cpp option?

View File

@ -19,7 +19,8 @@
* easily
* - gtk-doc comments
* 21/12/09
* - rewrite for a scanline based fill, 4x faster!
* - rewrite for a scanline based fill, about 4x faster!
* - allow separate test and mark images
*/
/*
@ -238,23 +239,21 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
PEL *tp;
PEL *mp;
int i;
int j;
int len;
/*
*/
printf( "flood_scanline: %d x %d\n", x, y );
g_assert( flood_connected( flood,
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) );
g_assert( !flood_painted( flood,
(PEL *) IM_IMAGE_ADDR( flood->mark, x, y ) ) );
*/
/* Search to the right for the first non-connected pixel. If the start
* pixel is unpainted, we know all the intervening pixels must be
* unpainted too.
*/
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x, y );
for( i = x; i < width; i++ ) {
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x + 1, y );
for( i = x + 1; i < width; i++ ) {
if( !flood_connected( flood, tp ) )
break;
tp += flood->tsize;
@ -264,7 +263,7 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
/* Search left.
*/
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x - 1, y );
for( i = x - 1; i > 0; i-- ) {
for( i = x - 1; i >= 0; i-- ) {
if( !flood_connected( flood, tp ) )
break;
tp -= flood->tsize;
@ -273,8 +272,9 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
/* Paint the range we discovered.
*/
mp = (PEL *) IM_IMAGE_ADDR( flood->mark, x, y );
for( i = *x1; i <= *x2; i++ ) {
mp = (PEL *) IM_IMAGE_ADDR( flood->mark, *x1, y );
len = *x2 - *x1 + 1;
for( i = 0; i < len; i++ ) {
flood_paint( flood, mp );
mp += flood->msize;
}
@ -285,10 +285,6 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
flood->top = IM_MIN( flood->top, y );
flood->bottom = IM_MAX( flood->bottom, y );
}
/*
*/
printf( "\tfilled between %d and %d\n", *x1, *x2 );
}
/* We know the line below or above us is filled between x1 and x2. Search our
@ -302,8 +298,10 @@ flood_around( Flood *flood, Scan *scan )
g_assert( scan->dir == 1 || scan->dir == -1 );
tp = (PEL *) IM_IMAGE_ADDR( flood->test, scan->x1, scan->y );
for( x = scan->x1; x <= scan->x2; x++ ) {
for( tp = (PEL *) IM_IMAGE_ADDR( flood->test, scan->x1, scan->y ),
x = scan->x1;
x <= scan->x2;
tp += flood->tsize, x++ ) {
if( flood_connected( flood, tp ) ) {
int x1a;
int x2a;
@ -328,11 +326,11 @@ flood_around( Flood *flood, Scan *scan )
*/
if( x1a < scan->x1 - 1 )
flood->out = buffer_add( flood->out, flood,
x1a, scan->x1 - 1,
x1a, scan->x1 - 2,
scan->y - scan->dir, -scan->dir );
if( x2a > scan->x2 + 1 )
flood->out = buffer_add( flood->out, flood,
scan->x2 + 1, x2a,
scan->x2 + 2, x2a,
scan->y - scan->dir, -scan->dir );
flood->out = buffer_add( flood->out, flood,
x1a, x2a, scan->y + scan->dir,
@ -341,44 +339,37 @@ flood_around( Flood *flood, Scan *scan )
x = x2a;
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x, scan->y );
}
tp += flood->tsize;
}
}
static void
flood_buffer( Flood *flood, Buffer *buf )
{
Buffer *p;
for( p = buf; p; p = p->next ) {
int i;
for( i = 0; i < p->n; i++ )
flood_around( flood, &p->scan[i] );
p->n = 0;
}
}
static void
flood_all( Flood *flood, int x, int y )
{
int x1, x2;
/* Test start pixel ... nothing to do?
*/
if( flood_connected( flood,
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) ) {
int x1, x2;
if( !flood_connected( flood,
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) )
return;
flood_scanline( flood, x, y, &x1, &x2 );
flood->in = buffer_add( flood->in, flood, x1, x2, y + 1, 1 );
flood->in = buffer_add( flood->in, flood, x1, x2, y - 1, -1 );
flood_scanline( flood, x, y, &x1, &x2 );
flood->in = buffer_add( flood->in, flood, x1, x2, y + 1, 1 );
flood->in = buffer_add( flood->in, flood, x1, x2, y - 1, -1 );
while( flood->in->n ) {
flood_buffer( flood, flood->in );
while( flood->in->n ) {
Buffer *p;
SWAP( Buffer *, flood->in, flood->out );
for( p = flood->in; p; p = p->next ) {
int i;
for( i = 0; i < p->n; i++ )
flood_around( flood, &p->scan[i] );
p->n = 0;
}
SWAP( Buffer *, flood->in, flood->out );
}
}
@ -531,7 +522,6 @@ im_flood_blob( IMAGE *im, int x, int y, PEL *ink, Rect *dout )
return( 0 );
}
/**
* im_flood_other:
* @test: image to test

View File

@ -371,8 +371,8 @@ static im_function flood_copy_desc = {
/* Args for im_flood_other_copy().
*/
static im_arg_desc flood_other_copy_args[] = {
IM_INPUT_IMAGE( "mask" ),
IM_INPUT_IMAGE( "test" ),
IM_INPUT_IMAGE( "mark" ),
IM_OUTPUT_IMAGE( "out" ),
IM_INPUT_INT( "start_x" ),
IM_INPUT_INT( "start_y" ),
@ -384,14 +384,14 @@ static im_arg_desc flood_other_copy_args[] = {
static int
flood_other_copy_vec( im_object *argv )
{
IMAGE *mask = argv[0];
IMAGE *test = argv[1];
IMAGE *test = argv[0];
IMAGE *mark = argv[1];
IMAGE *out = argv[2];
int start_x = *((int *) argv[3]);
int start_y = *((int *) argv[4]);
int serial = *((int *) argv[5]);
return( im_flood_other_copy( mask, test, out,
return( im_flood_other_copy( test, mark, out,
start_x, start_y, serial ) );
}
@ -399,7 +399,7 @@ flood_other_copy_vec( im_object *argv )
*/
static im_function flood_other_copy_desc = {
"im_flood_other_copy", /* Name */
"flood mask with serial number from start_x, start_y while pixel == start pixel",
"flood mark with serial from start_x, start_y while pixel == start pixel",
0, /* Flags */
flood_other_copy_vec, /* Dispatch function */
IM_NUMBER( flood_other_copy_args ),/* Size of arg list */

View File

@ -92,6 +92,10 @@ im_label_regions( IMAGE *test, IMAGE *mask, int *segments )
for( y = 0; y < test->Ysize; y++ ) {
for( x = 0; x < test->Xsize; x++ ) {
if( !m[x] ) {
/*
if( im_flood_other_old( t[1], test,
x, y, serial ) )
*/
if( im_flood_other( test, t[1],
x, y, serial, NULL ) )
return( -1 );