Before you can read from a region, you need to call im_prepare()
to fill the region with image data. It has type:
int im_prepare( REGION *reg, Rect *r )
Area r
of the image on which reg
has been created is prepared
and attached to the region.
Exactly what this preparation involves depends upon the image -- it can
vary from simply adjusting some pointers, to triggering the evaluation of a
series of other functions. If it returns successfully, im_prepare()
guarantees that all pixels within reg->valid
may be accessed. Note
that this may be smaller or larger than r
, since im_prepare()
clips r
against the size of the image.
Programs can access image data in the region by calling the macro
IM_REGION_ADDR()
. It has type
char *IM_REGION_ADDR( REGION *reg, int x, int y )
Provided that point (x,y) lies inside reg->valid
,
IM_REGION_ADDR()
returns a pointer to pel . Adding to the result
of
IM_REGION_ADDR()
moves to the right along the line of pels, provided
you stay strictly within reg->valid
. Add IM_REGION_LSKIP()
to move down a line, see below. IM_REGION_ADDR()
has some other
useful features -- see the manual page.
Other macros are available to ease address calculation:
int IM_REGION_LSKIP( REGION *reg ) int IM_REGION_N_ELEMENTS( REGION *reg ) int IM_REGION_SIZEOF_LINE( REGION *reg )
These find the number of bytes to add to the result of IM_REGION_ADDR()
to move down a line, the number of band elements across the region and the
number of bytes across the region.
Figure 3.1 is a version of average()
which uses
regions rather than WIO input. Two things: first, we should really be
using im_iterate()
, see §3.4, to do the rectangle
algebra for us. Secondly, note that we call im_pincheck()
rather
than im_incheck()
. im_pincheck()
signals to the IO system
that you are a PIO-aware function, giving im_prepare()
much more
flexibility in the sorts of preparation it can do. Also see the manual
pages for im_poutcheck()
and im_piocheck()
.
This version of average()
can be called in exactly the same way as
the previous one, but this version has the great advantage of not needing
to have the whole of the input image available at once.
We can do one better than this -- if the image is being split into small pieces, we can assign each piece to a separate thread of execution and get parallelism. To support this splitting of tasks, VIPS has the notion of a sequence.