Regions are written to in just the same way they are read from -- by
writing to a pointer found with the IM_REGION_ADDR()
macro.
im_iterate()
does input -- im_generate()
does output. It
has the same type as im_iterate()
:
int im_generate( IMAGE *out, void *(*start_fn)(), int (*process_fn)(), int (*stop_fn)(), void *a, void *b )
The region given to the process function is ready for output. Each time
the process function is called, it should fill in the pels in the region
it was given. Note that, unlike im_iterate()
, the areas the process
function is asked to produce are not guaranteed to be either disjoint or
complete. Again, VIPS may start up many process functions if it sees fit.
Here is invert()
, rewritten to use PIO. This piece of code makes use
of a pair of standard start and stop functions provided by the VIPS library:
im_start_one()
and im_stop_one()
. They assume that the first
of the two user arguments to im_generate()
is the input image. They are
defined as:
REGION * im_start_one( IMAGE *out, IMAGE *in ) { return( im_region_create( in ) ); }
and:
int im_stop_one( REGION *seq ) { return( im_region_free( seq ) ); }
They are useful for simple functions which expect only one input
image. See the manual page for im_start_many()
for many-input
functions.
Functions have some choice about the way they write their output. Usually, they
should just write to the region they were given by im_generate()
. They
can, if they wish, set up the region for output to some other place. See
the manual page for im_region_region()
. See also the source for
im_copy()
and im_extract()
for examples of these tricks.
Note also the call to im_demand_hint()
. This function hints to the IO
system, suggesting the sorts of shapes of region this function is happiest
with. VIPS supports four basic shapes -- choosing the correct shape can
have a dramatic effect on the speed of your function. See the man page for
full details.