| \section{Image formats} |
| \label{sec:format} |
| |
| VIPS has a simple system for adding support for new image file formats. |
| You can ask VIPS to find a format to load a file with or to select a image |
| file writer based on a filename. Convenience functions copy a file to an |
| \verb+IMAGE+, or an \verb+IMAGE+ to a file. New formats may be added to |
| VIPS by simply defining a new subclass of \verb+VipsFormat+. |
| |
| This is a parallel API to \verb+im_open()+, see \pref{sec:open}. The |
| format system is useful for images which are large or slow to open, |
| because you pass a descriptor to write to and so control how and where |
| the decompressed image is held. \verb+im_open()+ is useful for images in |
| formats which can be directly read from disc, since you will avoid a copy |
| operation and can directly control the disc file. The inplace operations |
| (see \pref{sec:inplace}), for example, will only work directly on disc |
| images if you use \verb+im_open()+. |
| |
| \subsection{How a format is represented} |
| |
| See the man page for \verb+VipsFormat+ for full details, but briefly, an image |
| format consists of the following items: |
| |
| \begin{itemize} |
| \item |
| A name, a name that can be shows to the user, and a list of possible filename |
| suffixes (\verb+.tif+, for example) |
| |
| \item |
| A function which tests for a file being in that format, a function which loads |
| just the header of the file (that is, it reads properties like width and |
| height and does not read any pixel data) and a function which loads the pixel |
| data |
| |
| \item |
| A function which will write an \verb+IMAGE+ to a file in the format |
| |
| \item |
| And finally a function which examines a file in the format and returns flags |
| indicating how VIPS should deal with the file. The only flag in the current |
| version is one indicating that the file can be opened lazily |
| |
| \end{itemize} |
| |
| \subsection{The format class} |
| |
| The interface to the format system is defined by the abstract base class |
| \verb+VipsFormat+. Formats subclass this and implement some or all of the |
| methods. Any of the functions may be left NULL and VIPS will try to make do |
| with what you do supply. Of course a format with all functions as NULL will |
| not be very useful. |
| |
| As an example, \fref{fg:newformat} shows how to register a new format in a |
| plugin. |
| |
| \begin{fig2} |
| \begin{verbatim} |
| static const char *my_suffs[] = { ".me", NULL }; |
| |
| static int |
| is_myformat( const char *filename ) |
| { |
| unsigned char buf[2]; |
| |
| if( im__get_bytes( filename, buf, 2 ) && |
| (int) buf[0] == 0xff && |
| (int) buf[1] == 0xd8 ) |
| return( 1 ); |
| |
| return( 0 ); |
| } |
| |
| // This format adds no new members. |
| typedef VipsFormat VipsFormatMyformat; |
| typedef VipsFormatClass VipsFormatMyformatClass; |
| |
| static void |
| vips_format_myformat_class_init( VipsFormatMyformatClass *class ) |
| { |
| VipsObjectClass *object_class = (VipsObjectClass *) class; |
| VipsFormatClass *format_class = (VipsFormatClass *) class; |
| |
| object_class->nickname = "myformat"; |
| object_class->description = _( "My format" ); |
| |
| format_class->is_a = is_myformat; |
| format_class->header = my_header; |
| format_class->load = my_read; |
| format_class->save = my_write; |
| format_class->get_flags = my_get_flags; |
| format_class->priority = 100; |
| format_class->suffs = my_suffs; |
| } |
| |
| static void |
| vips_format_myformat_init( VipsFormatMyformat *object ) |
| { |
| } |
| |
| G_DEFINE_TYPE( VipsFormatMyformat, vips_format_myformat, VIPS_TYPE_FORMAT ); |
| |
| char * |
| g_module_check_init( GModule *self ) |
| { |
| // register the type |
| vips_format_myformat_get_type(); |
| } |
| \end{verbatim} |
| \caption{Registering a format in a plugin} |
| \label{fg:newformat} |
| \end{fig2} |
| |
| \subsection{Finding a format} |
| |
| You can loop over the subclasses of \verb+VipsFormat+ in order of priority |
| with \verb+vips_format_map()+. Like all the map functions in VIPS, this take |
| a function and applies it to every element in the table until the function |
| returns non-zero or until the table ends. |
| |
| You find an \verb+VipsFormatClass+ to use to open a file with |
| \verb+vips_format_for_file()+. This finds the first format whose \verb+is_a()+ |
| function returns true or whose suffix list matches the suffix of the filename, |
| setting an error message and returning NULL if no format is found. |
| |
| You find a format to write a file with \verb+vips_format_for_name()+. This |
| returns the first format with a save function whose suffix list matches the |
| suffix of the supplied filename. |
| |
| \subsection{Convenience functions} |
| |
| A pair of convenience functions, \verb+vips_format_write()+ and |
| \verb+vips_format_read()+, will copy an image to and from disc using the |
| appropriate format. |