fixed up flood other
This commit is contained in:
parent
7ae8c491f2
commit
3cf1646b1d
2
TODO
2
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?
|
- add a --without-cpp option?
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
* easily
|
* easily
|
||||||
* - gtk-doc comments
|
* - gtk-doc comments
|
||||||
* 21/12/09
|
* 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 *tp;
|
||||||
PEL *mp;
|
PEL *mp;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
|
||||||
printf( "flood_scanline: %d x %d\n", x, y );
|
|
||||||
|
|
||||||
g_assert( flood_connected( flood,
|
g_assert( flood_connected( flood,
|
||||||
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) );
|
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) );
|
||||||
g_assert( !flood_painted( flood,
|
g_assert( !flood_painted( flood,
|
||||||
(PEL *) IM_IMAGE_ADDR( flood->mark, x, y ) ) );
|
(PEL *) IM_IMAGE_ADDR( flood->mark, x, y ) ) );
|
||||||
|
*/
|
||||||
|
|
||||||
/* Search to the right for the first non-connected pixel. If the start
|
/* Search to the right for the first non-connected pixel. If the start
|
||||||
* pixel is unpainted, we know all the intervening pixels must be
|
* pixel is unpainted, we know all the intervening pixels must be
|
||||||
* unpainted too.
|
* unpainted too.
|
||||||
*/
|
*/
|
||||||
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x, y );
|
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x + 1, y );
|
||||||
for( i = x; i < width; i++ ) {
|
for( i = x + 1; i < width; i++ ) {
|
||||||
if( !flood_connected( flood, tp ) )
|
if( !flood_connected( flood, tp ) )
|
||||||
break;
|
break;
|
||||||
tp += flood->tsize;
|
tp += flood->tsize;
|
||||||
@ -264,7 +263,7 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
|
|||||||
/* Search left.
|
/* Search left.
|
||||||
*/
|
*/
|
||||||
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x - 1, y );
|
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 ) )
|
if( !flood_connected( flood, tp ) )
|
||||||
break;
|
break;
|
||||||
tp -= flood->tsize;
|
tp -= flood->tsize;
|
||||||
@ -273,8 +272,9 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
|
|||||||
|
|
||||||
/* Paint the range we discovered.
|
/* Paint the range we discovered.
|
||||||
*/
|
*/
|
||||||
mp = (PEL *) IM_IMAGE_ADDR( flood->mark, x, y );
|
mp = (PEL *) IM_IMAGE_ADDR( flood->mark, *x1, y );
|
||||||
for( i = *x1; i <= *x2; i++ ) {
|
len = *x2 - *x1 + 1;
|
||||||
|
for( i = 0; i < len; i++ ) {
|
||||||
flood_paint( flood, mp );
|
flood_paint( flood, mp );
|
||||||
mp += flood->msize;
|
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->top = IM_MIN( flood->top, y );
|
||||||
flood->bottom = IM_MAX( flood->bottom, 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
|
/* 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 );
|
g_assert( scan->dir == 1 || scan->dir == -1 );
|
||||||
|
|
||||||
tp = (PEL *) IM_IMAGE_ADDR( flood->test, scan->x1, scan->y );
|
for( tp = (PEL *) IM_IMAGE_ADDR( flood->test, scan->x1, scan->y ),
|
||||||
for( x = scan->x1; x <= scan->x2; x++ ) {
|
x = scan->x1;
|
||||||
|
x <= scan->x2;
|
||||||
|
tp += flood->tsize, x++ ) {
|
||||||
if( flood_connected( flood, tp ) ) {
|
if( flood_connected( flood, tp ) ) {
|
||||||
int x1a;
|
int x1a;
|
||||||
int x2a;
|
int x2a;
|
||||||
@ -328,11 +326,11 @@ flood_around( Flood *flood, Scan *scan )
|
|||||||
*/
|
*/
|
||||||
if( x1a < scan->x1 - 1 )
|
if( x1a < scan->x1 - 1 )
|
||||||
flood->out = buffer_add( flood->out, flood,
|
flood->out = buffer_add( flood->out, flood,
|
||||||
x1a, scan->x1 - 1,
|
x1a, scan->x1 - 2,
|
||||||
scan->y - scan->dir, -scan->dir );
|
scan->y - scan->dir, -scan->dir );
|
||||||
if( x2a > scan->x2 + 1 )
|
if( x2a > scan->x2 + 1 )
|
||||||
flood->out = buffer_add( flood->out, flood,
|
flood->out = buffer_add( flood->out, flood,
|
||||||
scan->x2 + 1, x2a,
|
scan->x2 + 2, x2a,
|
||||||
scan->y - scan->dir, -scan->dir );
|
scan->y - scan->dir, -scan->dir );
|
||||||
flood->out = buffer_add( flood->out, flood,
|
flood->out = buffer_add( flood->out, flood,
|
||||||
x1a, x2a, scan->y + scan->dir,
|
x1a, x2a, scan->y + scan->dir,
|
||||||
@ -341,44 +339,37 @@ flood_around( Flood *flood, Scan *scan )
|
|||||||
x = x2a;
|
x = x2a;
|
||||||
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x, scan->y );
|
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
|
static void
|
||||||
flood_all( Flood *flood, int x, int y )
|
flood_all( Flood *flood, int x, int y )
|
||||||
{
|
{
|
||||||
|
int x1, x2;
|
||||||
|
|
||||||
/* Test start pixel ... nothing to do?
|
/* Test start pixel ... nothing to do?
|
||||||
*/
|
*/
|
||||||
if( flood_connected( flood,
|
if( !flood_connected( flood,
|
||||||
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) ) {
|
(PEL *) IM_IMAGE_ADDR( flood->test, x, y ) ) )
|
||||||
int x1, x2;
|
return;
|
||||||
|
|
||||||
flood_scanline( flood, x, y, &x1, &x2 );
|
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->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 ) {
|
while( flood->in->n ) {
|
||||||
flood_buffer( flood, flood->in );
|
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 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* im_flood_other:
|
* im_flood_other:
|
||||||
* @test: image to test
|
* @test: image to test
|
||||||
|
@ -371,8 +371,8 @@ static im_function flood_copy_desc = {
|
|||||||
/* Args for im_flood_other_copy().
|
/* Args for im_flood_other_copy().
|
||||||
*/
|
*/
|
||||||
static im_arg_desc flood_other_copy_args[] = {
|
static im_arg_desc flood_other_copy_args[] = {
|
||||||
IM_INPUT_IMAGE( "mask" ),
|
|
||||||
IM_INPUT_IMAGE( "test" ),
|
IM_INPUT_IMAGE( "test" ),
|
||||||
|
IM_INPUT_IMAGE( "mark" ),
|
||||||
IM_OUTPUT_IMAGE( "out" ),
|
IM_OUTPUT_IMAGE( "out" ),
|
||||||
IM_INPUT_INT( "start_x" ),
|
IM_INPUT_INT( "start_x" ),
|
||||||
IM_INPUT_INT( "start_y" ),
|
IM_INPUT_INT( "start_y" ),
|
||||||
@ -384,14 +384,14 @@ static im_arg_desc flood_other_copy_args[] = {
|
|||||||
static int
|
static int
|
||||||
flood_other_copy_vec( im_object *argv )
|
flood_other_copy_vec( im_object *argv )
|
||||||
{
|
{
|
||||||
IMAGE *mask = argv[0];
|
IMAGE *test = argv[0];
|
||||||
IMAGE *test = argv[1];
|
IMAGE *mark = argv[1];
|
||||||
IMAGE *out = argv[2];
|
IMAGE *out = argv[2];
|
||||||
int start_x = *((int *) argv[3]);
|
int start_x = *((int *) argv[3]);
|
||||||
int start_y = *((int *) argv[4]);
|
int start_y = *((int *) argv[4]);
|
||||||
int serial = *((int *) argv[5]);
|
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 ) );
|
start_x, start_y, serial ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ flood_other_copy_vec( im_object *argv )
|
|||||||
*/
|
*/
|
||||||
static im_function flood_other_copy_desc = {
|
static im_function flood_other_copy_desc = {
|
||||||
"im_flood_other_copy", /* Name */
|
"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 */
|
0, /* Flags */
|
||||||
flood_other_copy_vec, /* Dispatch function */
|
flood_other_copy_vec, /* Dispatch function */
|
||||||
IM_NUMBER( flood_other_copy_args ),/* Size of arg list */
|
IM_NUMBER( flood_other_copy_args ),/* Size of arg list */
|
||||||
|
@ -92,6 +92,10 @@ im_label_regions( IMAGE *test, IMAGE *mask, int *segments )
|
|||||||
for( y = 0; y < test->Ysize; y++ ) {
|
for( y = 0; y < test->Ysize; y++ ) {
|
||||||
for( x = 0; x < test->Xsize; x++ ) {
|
for( x = 0; x < test->Xsize; x++ ) {
|
||||||
if( !m[x] ) {
|
if( !m[x] ) {
|
||||||
|
/*
|
||||||
|
if( im_flood_other_old( t[1], test,
|
||||||
|
x, y, serial ) )
|
||||||
|
*/
|
||||||
if( im_flood_other( test, t[1],
|
if( im_flood_other( test, t[1],
|
||||||
x, y, serial, NULL ) )
|
x, y, serial, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
Loading…
Reference in New Issue
Block a user