.TH IM_GENERATE 3 "11 April 1993"
.SH NAME
im_generate, im_start_one, im_stop_one, im_allocate_input_array, 
im_start_many, im_stop_many \- generate image pixels
.SH SYNOPSIS
.B #include <vips/vips.h>

void *im_start_one( out, in )
.br
IMAGE *out, *in;

int im_stop_one( reg )
.br
REGION *reg;

IMAGE **im_allocate_input_array( IMAGE *out, ... )

void *im_start_many( out, in )
.br
IMAGE *out, **in;

int im_stop_many( REGION **out )
.br
REGION **out;

int im_generate( im, 
    start_fn, gen_fn, stop_fn, void *a, void *b )
.br
IMAGE *im;
.br
void *(*start_fn)();
.br
int (*gen_fn)();
.br
int (*stop_fn)();
.br
void *a, void *b;

where, typically, 

void *start_fn( im, a, b )
.br
IMAGE *im;
.br
void *a, *b;

int gen_fn( or, seq, a, b )
.br
REGION *or;
.br
void *seq;
.br
void *a, *b;

int stop_fn( seq, a, b )
.br
void *seq;
.br
void *a, *b;
.SH DESCRIPTION
.B im_generate(3), 
with its supporting convenience functions, is used for
PIO image output.  See also
.B im_wrapone(3) 
for an easy alternative to 
.B im_generate(3) 
for simple image
processing operations.

.B im_start_one(3) 
and 
.B im_stop_one(3) 
are convenience functions, useful for
simple one-image-in, one-image-out operations. 
.B im_start_one(3) 
assumes the
first of the two user arguments (a, above) is the input image. It creates a
REGION on this image and returns a pointer to the region as a sequence value.

.B im_stop_one(3) 
assumes the sequence value is a REGION pointer, and frees it.

.B im_allocate_input_array(3) 
takes as arguments the output image and a list of
input images, terminated with a NULL. It allocates a NULL-terminated array to
hold the images, and attaches a close callback to the output image to free
that array. Example:

    IMAGE *in, *in2, *in3, *in4;
    IMAGE **arry;

    if( !(arry = im_allocate_input_array( out, 
        in1, in2, in3, in4, NULL )) )
        return( -1 );

builds the structure

    IMAGE *arry[] = { in1, in2, in3, in4, NULL };

and makes sure it will be freed. 

.B im_start_many(3) 
and 
.B im_stop_many(3) 
work exactly as 
.B im_start_one(3) 
and
.B im_stop_one(3), 
but with NULL-terminated arrays of IMAGEs and REGIONs.
They are useful for many-images-in, one-image-out operations.
.B im_start_many(3) 
assumes that the first of the two user arguments is a pointer
to a NULL-terminates array of IMAGEs. It builds and returns as the sequence
value a NULL-terminated array of REGIONs.

.B im_stop_many(3) 
assumes the sequence value is a pointer to a NULL-terminated
array of REGIONs. It frees all the regions in turn. See 
.B im_add(3) 
for an
example of this pair of functions in action.

.B im_generate(3) 
looks at the type of im and acts accordingly:

    IM_PARTIAL: the start, process and stop functions are attached to the 
region, and im_generate returns immediately. See 
.B im_prepare(3).

    IM_SETBUF: memory for the output image is created and sequences
started to fill it. It is an error to write to the same buffer twice.

    IM_MMAPINRW: sequences are started, and asked to fill the image in patches.

    IM_OPENOUT: The output file is created and a header written to disc. A 
buffer
large enough to hold GENERATE_TILE_HEIGHT complete horizontal lines is
created, and sequences started to fill this buffer. When the buffer has been
filled, the whole set of lines are flushed to disc in a single write(2)
operation, and work starts on the next set of lines.

Any other image type is an error. 
.B im_generate(3) 
returns 0 for complete
success, and non-zero on failure.

    static int
    wombat_gen( or, ir, in )
    REGION *or, *ir;
    IMAGE *in;
    {
        ... process!

        return( 0 );
    }

    int
    im_wombat( in, out )
    IMAGE *in, *out;
    {
        if( im_iocheck( in, out ) )
            return( -1 );

        ... check parametersm check image descriptors 
        ... for type-compatibility, etc. etc.

        if( im_cp_desc( out, in ) )
            return( -1 );

        ... set fields in out for the type of image you
        ... wish to write

        if( im_generate( out,
            im_start_one, wombat_gen, im_stop_one, 
            in, NULL ) )
            return( -1 );

        return( 0 );
    }

See also the source to 
.B im_invert(3), 
.B im_exptra(3), 
and, if you are brave,
.B im_conv(3) 
or 
.B im_add(3).

On machines with several CPUs, 
.B im_generate(3) 
and
.B im_iterate(3) 
automatically parallelise programs. You can set the desired
concurrency level with the environment variable IM_CONCURRENCY, for example

    example% export IM_CONCURRENCY=2
    example% lintra 2.0 fred.v 0.0 fred2.v

will run lintra with enough concurrency to keep 2 CPUs fully occupied.
If IM_CONCURRENCY is not set, then it defaults to 1. See also
im_concurrency_set(3).

Most programs which use VIPS will also let you use the command-line argument
--vips-concurrency to set parallelisation, see im_get_option_group(3).

.SH COPYRIGHT
National Gallery, 1993
.SH SEE ALSO
im_wrapone(3), im_add_eval_callback(3), im_iterate(3), im_piocheck(3),
im_concurrency_set(3),
im_get_option_group(3),
`VIPS manual,' in accompanying documentation.
.SH AUTHOR
J. Cupitt \- 23/7/93