| \section{Introduction} |
| \mylabel{sec:oper} |
| |
| This chapter explains how to write image processing operations using the |
| VIPS image I/O (input-output) system. For background, you should probably |
| take a look at \pref{sec:appl}. This is supposed to be a tutorial, if you |
| need detailed information on any particular function, use the on-line UNIX |
| manual pages. |
| |
| \subsection{Why use VIPS?} |
| |
| If you use the VIPS image I/O system, you get a number of benefits: |
| |
| \begin{description} |
| |
| \item[Threading] |
| If your computer has more than one CPU, the VIPS I/O system will automatically |
| split your image processing operation into separate threads (provided you |
| use PIO, see below). You should get an approximately linear speed-up as |
| you add more CPUs. |
| |
| \item[Pipelining] |
| Provided you use PIO (again, see below), VIPS can automatically join |
| operations together. A sequence of image processing operations will all |
| execute together, with image data flowing through the processing pipeline |
| in small pieces. This makes it possible to perform complex processing on |
| very large images with no need to worry about storage management. |
| |
| \item[Composition] |
| Because VIPS can efficiently compose image processing operations, you can |
| implement your new operation in small, reusable, easy-to-understand |
| pieces. VIPS already has a lot of these: many new operations can be |
| implemented by simply composing existing operations. |
| |
| \item[Large files] |
| Provided you use PIO and as long as the underlying OS supports large files |
| (that is, files larger than 2GB), VIPS operations can work on files larger |
| than can be addressed with 32 bits on a plain 32-bit machine. VIPS operations |
| only see 32 bit addresses; the VIPS I/O system transparently maps these to |
| 64 bit operations for I/O. Large file support is included on most machines |
| after about 1998. |
| |
| \item[Abstraction] |
| VIPS operations see only arrays of numbers in native format. Details of |
| representation (big/little endian, VIPS/TIFF/JPEG file format, etc.) are |
| hidden from you. |
| |
| \item[Interfaces] |
| Once you have your image processing operation implemented, it automatically |
| appears in all of the VIPS interfaces. VIPS comes with a GUI (\nip{}), a |
| UNIX command-line interface (\vips{}) and a C++ and Python API. |
| |
| \item[Portability] |
| VIPS operations can be compiled on most unixes, Mac OS X and Windows NT, 2000 |
| and XP without modification. Mostly. |
| |
| \end{description} |
| |
| \subsection{I/O styles} |
| |
| The I/O system supports three styles of input-output. |
| |
| \begin{description} |
| |
| \item[Whole-image I/O (WIO)] |
| This style is a largely a left-over from VIPS 6.x. WIO image-processing |
| operations have all of the input image given to them in a large memory |
| array. They can read any of the input pels at will with simple pointer |
| arithmetic. |
| |
| \item[Partial-image I/O (PIO)] |
| In this style operations only have a small part of the input image available |
| to them at any time. When PIO operations are joined together into a pipeline, |
| images flow through them in small pieces, with all the operations in a |
| pipeline executing at the same time. |
| |
| \item[In-place] |
| The third style allows pels to be read and written anywhere in |
| the image at any time, and is used by the VIPS in-place operations, such |
| as \verb+im_fastline()+. You should only use it for operations which would |
| just be impossibly inefficient to write with either of the other two styles. |
| |
| \end{description} |
| |
| WIO operations are easy to program, but slow and inflexible when images |
| become large. PIO operations are harder to program, but scale well as images |
| become larger, and are automatically parallelized by the VIPS I/O system. |
| |
| If you can face it, and if your algorithm can be expressed in this way, you |
| should write your operations using PIO. Whichever you choose, applications |
| which call your operation will see no difference, except in execution speed. |
| |
| If your image processing operation performs no coordinate transformations, |
| that is, if your output image is the same size as your input image or images, |
| and if each output pixel depends only upon the pixel at the corresponding |
| position in the input images, then you can use the \verb+im_wrapone()+ |
| and \verb+im_wrapmany()+ operations. These take a simple buffer-processing |
| operation supplied by you and wrap it up as a full-blown PIO operation. |
| See~\pref{sec:wrapone}. |
| |