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
*
* 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
* - 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 );
}
/**
* 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
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 );
}
/* 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?
*/

View File

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