next up previous contents
Next: 3.5 Output to regions Up: 3. Programming PIO functions Previous: 3.3 Image input with   Contents


3.4 Splitting into sequences

A sequence comes in three parts: a start function, a processing function, and a stop function. When VIPS starts up a new sequence, it runs the start function. Start functions return sequence values: a void pointer representing data local to this sequence. VIPS then repeatedly calls the processing function, passing in the sequence value and a new piece of image data for processing. Finally, when processing is complete, VIPS cleans up by calling the stop function, passing in the sequence value as an argument. The types look like this:

void *
(*start_fn)( IMAGE *out, 
   void *a, void *b )
int 
(*process_fn)( REGION *reg, 
   void *seq, void *a, void *b )
int 
(*stop_fn)( void *seq, void *a, void *b )

The values a and b are carried around by VIPS for your use.

For functions like average() which consume images but produce no image output, VIPS provides im_iterate(). This has type:

int im_iterate( IMAGE *in, 
   void *(*start_fn)(), 
   int (*process_fn)(), 
   int (*stop_fn)(),
   void *a, void *b )

VIPS starts one or more sequences, runs one or more processing functions over image in until all of in has been consumed, and then closes all of the sequences down and returns. VIPS guarantees that the regions the process_fn() is given will be complete and disjoint, that is, every pixel in the image will be passed through exactly one sequence. To make it possible for the sequences to each contribute to the result of the function in an orderly manner, VIPS also guarantees that all start and stop functions are mutually exclusive.

A note on types: <vips/region.h> declares prototypes for im_iterate() and im_generate() (see §3.5), but does not give prototypes for the function arguments. This looses a little type-safety, but gains some convenience.

An example should make this clearer. This version of average() is very similar to the average function in the VIPS library -- it is only missing polymorphism.

Figure 3.3: Final PIO average of image
\begin{figure}\begin{quote}
\begin{verbatim}...

Figure 3.4: Final PIO average of image (cont.)
\begin{figure}\begin{quote}
\begin{verbatim}/* Process function for average()....
...ence.
*/
*seq += total;return( 0 );
}\end{verbatim}
\end{quote}\end{figure}

Figure 3.5: Final PIO average of image (cont.)
\begin{figure}\begin{quote}
\begin{verbatim}/* Find average of image.
*/
int
...
...MENTS( im ) * im->Ysize);return( 0 );
}\end{verbatim}
\end{quote}\end{figure}

There are a couple of variations on im_prepare(): you can use im_prepare_to() to force writing to a particular place, and im_prepare_thread() to force threaded evaluation. See the man pages.


next up previous contents
Next: 3.5 Output to regions Up: 3. Programming PIO functions Previous: 3.3 Image input with   Contents
John Cupitt 2004-11-02