This commit is contained in:
John Cupitt 2009-12-27 21:48:29 +00:00
parent cb888b9765
commit d7f1986ee3
2 changed files with 123 additions and 19 deletions

View File

@ -1,8 +1,4 @@
/* flood-fill /* flood-fill
*
* Currently a rather inefficient pixel-based algorithm, should put something
* better in, really. Speed isn't likely to be a problem, except for very
* large images.
* *
* JC 30/8/97 * JC 30/8/97
* - VIPSified, cleaned up, from "John Robinson's prog to fill * - VIPSified, cleaned up, from "John Robinson's prog to fill
@ -485,6 +481,31 @@ im_flood_blob( IMAGE *im, int x, int y, PEL *ink, Rect *dout )
return( 0 ); return( 0 );
} }
/**
* im_flood_other:
* @test: image to test
* @mark: image to mark
* @x: position to start fill
* @y: position to start fill
* @serial: mark pixels with this number
* @dout: output the bounding box of the filled area
*
* Flood-fill @mark with @serial, starting at position @x, @y. The filled
* area is bounded by pixels in @test that are equal to the start pixel, in
* other words, it searches @test for a blob of same-coloured pixels, marking
* those pixels in @mark with @serial.
*
* The bounding box of the modified pixels is returned in @dout.
*
* This an inplace operation, so @mark is changed. It does not thread and will
* not work well as part of a pipeline. On 32-bit machines, it will be limited
* to 2GB images.
*
* See also: im_flood(), im_label_regions(), im_flood_blob_copy().
*
* Returns: 0 on success, or -1 on error.
*/
int int
im_flood_other( IMAGE *test, IMAGE *mark, int x, int y, int serial, Rect *dout ) im_flood_other( IMAGE *test, IMAGE *mark, int x, int y, int serial, Rect *dout )
{ {
@ -523,7 +544,7 @@ im_flood_other( IMAGE *test, IMAGE *mark, int x, int y, int serial, Rect *dout )
return( 0 ); return( 0 );
} }
/* A Flood blob we can call from nip. Grr! Should be a way to wrap these /* A flood blob we can call from nip. Grr! Should be a way to wrap these
* automatically. Maybe nip could do it if it sees a RW image argument? * automatically. Maybe nip could do it if it sees a RW image argument?
*/ */

View File

@ -188,9 +188,9 @@ vector_to_ink( IMAGE *im, double *vec )
return( (PEL *) t[2]->data ); return( (PEL *) t[2]->data );
} }
/* Args for im_flood_old(). /* Args for im_flood_copy_old().
*/ */
static im_arg_desc flood_old_args[] = { static im_arg_desc flood_copy_old_args[] = {
IM_INPUT_IMAGE( "in" ), IM_INPUT_IMAGE( "in" ),
IM_OUTPUT_IMAGE( "out" ), IM_OUTPUT_IMAGE( "out" ),
IM_INPUT_INT( "start_x" ), IM_INPUT_INT( "start_x" ),
@ -198,10 +198,10 @@ static im_arg_desc flood_old_args[] = {
IM_INPUT_DOUBLEVEC( "ink" ) IM_INPUT_DOUBLEVEC( "ink" )
}; };
/* Call im_flood_old() via arg vector. /* Call im_flood_copy_old() via arg vector.
*/ */
static int static int
flood_old_vec( im_object *argv ) flood_copy_old_vec( im_object *argv )
{ {
IMAGE *in = argv[0]; IMAGE *in = argv[0];
IMAGE *out = argv[1]; IMAGE *out = argv[1];
@ -209,12 +209,10 @@ flood_old_vec( im_object *argv )
int start_y = *((int *) argv[3]); int start_y = *((int *) argv[3]);
im_doublevec_object *dv = (im_doublevec_object *) argv[4]; im_doublevec_object *dv = (im_doublevec_object *) argv[4];
extern int im_flood_copy_old( IMAGE *, IMAGE *, int, int, PEL * );
PEL *ink; PEL *ink;
if( dv->n != in->Bands ) { if( dv->n != in->Bands ) {
im_error( "im_flood_old", im_error( "im_flood_copy_old",
"%s", _( "bad vector length" ) ); "%s", _( "bad vector length" ) );
return( -1 ); return( -1 );
} }
@ -226,13 +224,13 @@ flood_old_vec( im_object *argv )
/* Description of im_flood_old(). /* Description of im_flood_old().
*/ */
static im_function flood_old_desc = { static im_function flood_copy_old_desc = {
"im_flood_old", /* Name */ "im_flood_copy_old", /* Name */
"flood with ink from start_x, start_y while pixel == start pixel", "flood with ink from start_x, start_y while pixel == start pixel",
0, /* Flags */ 0, /* Flags */
flood_old_vec, /* Dispatch function */ flood_copy_old_vec, /* Dispatch function */
IM_NUMBER( flood_old_args ),/* Size of arg list */ IM_NUMBER( flood_copy_old_args ),/* Size of arg list */
flood_old_args /* Arg list */ flood_copy_old_args /* Arg list */
}; };
/* Args for im_flood_blob_copy(). /* Args for im_flood_blob_copy().
@ -280,6 +278,51 @@ static im_function flood_blob_copy_desc = {
flood_blob_copy_args /* Arg list */ flood_blob_copy_args /* Arg list */
}; };
/* Args for im_flood_blob_copy_old().
*/
static im_arg_desc flood_blob_copy_old_args[] = {
IM_INPUT_IMAGE( "in" ),
IM_OUTPUT_IMAGE( "out" ),
IM_INPUT_INT( "start_x" ),
IM_INPUT_INT( "start_y" ),
IM_INPUT_DOUBLEVEC( "ink" )
};
/* Call im_flood_blob_copy_old() via arg vector.
*/
static int
flood_blob_copy_old_vec( im_object *argv )
{
IMAGE *in = argv[0];
IMAGE *out = argv[1];
int start_x = *((int *) argv[2]);
int start_y = *((int *) argv[3]);
im_doublevec_object *dv = (im_doublevec_object *) argv[4];
PEL *ink;
if( dv->n != in->Bands ) {
im_error( "im_flood_blob_copy_old",
"%s", _( "bad vector length" ) );
return( -1 );
}
if( !(ink = vector_to_ink( in, dv->vec )) )
return( -1 );
return( im_flood_blob_copy_old( in, out, start_x, start_y, ink ) );
}
/* Description of im_flood_blob_copy_old().
*/
static im_function flood_blob_copy_old_desc = {
"im_flood_blob_copy_old", /* Name */
"flood with ink from start_x, start_y while pixel == start pixel",
0, /* Flags */
flood_blob_copy_old_vec, /* Dispatch function */
IM_NUMBER( flood_blob_copy_old_args ),/* Size of arg list */
flood_blob_copy_old_args /* Arg list */
};
/* Args for im_flood_copy(). /* Args for im_flood_copy().
*/ */
static im_arg_desc flood_copy_args[] = { static im_arg_desc flood_copy_args[] = {
@ -363,6 +406,44 @@ static im_function flood_other_copy_desc = {
flood_other_copy_args /* Arg list */ flood_other_copy_args /* Arg list */
}; };
/* Args for im_flood_other_copy_old().
*/
static im_arg_desc flood_other_copy_old_args[] = {
IM_INPUT_IMAGE( "mask" ),
IM_INPUT_IMAGE( "test" ),
IM_OUTPUT_IMAGE( "out" ),
IM_INPUT_INT( "start_x" ),
IM_INPUT_INT( "start_y" ),
IM_INPUT_INT( "serial" )
};
/* Call im_flood_other_copy_old() via arg vector.
*/
static int
flood_other_copy_old_vec( im_object *argv )
{
IMAGE *mask = argv[0];
IMAGE *test = 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_old( mask, test, out,
start_x, start_y, serial ) );
}
/* Description of im_flood_other_copy_old().
*/
static im_function flood_other_copy_old_desc = {
"im_flood_other_copy_old", /* Name */
"flood mask with serial number from start_x, start_y while pixel == start pixel",
0, /* Flags */
flood_other_copy_old_vec, /* Dispatch function */
IM_NUMBER( flood_other_copy_old_args ),/* Size of arg list */
flood_other_copy_old_args /* Arg list */
};
/* To do: /* To do:
* these all need some kind of pel type * these all need some kind of pel type
* *
@ -379,10 +460,12 @@ static im_function flood_other_copy_desc = {
*/ */
static im_function *inplace_list[] = { static im_function *inplace_list[] = {
&circle_desc, &circle_desc,
&flood_blob_copy_desc,
&flood_copy_desc, &flood_copy_desc,
&flood_old_desc, &flood_blob_copy_desc,
&flood_other_copy_desc, &flood_other_copy_desc,
&flood_copy_old_desc,
&flood_blob_copy_old_desc,
&flood_other_copy_old_desc,
&insertplace_desc, &insertplace_desc,
&lineset_desc &lineset_desc
}; };