diff --git a/TODO b/TODO index 1434b4c2..27863c22 100644 --- a/TODO +++ b/TODO @@ -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? diff --git a/libvips/inplace/flood.c b/libvips/inplace/flood.c index 97f4a188..205ed324 100644 --- a/libvips/inplace/flood.c +++ b/libvips/inplace/flood.c @@ -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 diff --git a/libvips/inplace/inplace_dispatch.c b/libvips/inplace/inplace_dispatch.c index a09ac1dd..170419aa 100644 --- a/libvips/inplace/inplace_dispatch.c +++ b/libvips/inplace/inplace_dispatch.c @@ -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 */ diff --git a/libvips/morphology/im_label_regions.c b/libvips/morphology/im_label_regions.c index 4dba872d..82cf9702 100644 --- a/libvips/morphology/im_label_regions.c +++ b/libvips/morphology/im_label_regions.c @@ -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 );