From a5517d3bdcc374ca43da7c4f2d5de5cd88a184e8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 28 Nov 2008 21:26:23 +0000 Subject: [PATCH] more tweaks, docs updated --- ChangeLog | 2 + TODO | 7 -- doc/src/format.tex | 89 ++++++++++++++------------ include/vips/format.h | 4 +- libsrc/format/format.c | 2 +- libsrc/format/im_analyze2vips.c | 2 +- libsrc/format/im_exr2vips.c | 2 +- libsrc/format/im_ppm2vips.c | 2 +- libsrc/format/im_tiff2vips.c | 2 +- man/VipsFormat.3 | 109 +++++++++++++++++--------------- 10 files changed, 117 insertions(+), 104 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0aa28e3..ef427506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,8 @@ - added affinei_all - don't set im_error() on failed callback - moved im_format_t to VipsFormat, now sits over VipsObject +- IM_FORMAT_FLAG_PARTIAL -> VIPS_FORMAT_PARTIAL +- updated docs 11/9/08 started 7.16.3 - oop typo in manpage for im_project() diff --git a/TODO b/TODO index 3ebdea83..68f35d9f 100644 --- a/TODO +++ b/TODO @@ -6,13 +6,6 @@ user G_DEFINE_ABSTRACT_TYPE for VipsObject -- we have - - VipsFormatFlags - VIPS_FORMAT_FLAG_PARTIAL - - is this right? should we use singular or plural? - diff --git a/doc/src/format.tex b/doc/src/format.tex index b295b96a..227a9dbf 100644 --- a/doc/src/format.tex +++ b/doc/src/format.tex @@ -1,11 +1,11 @@ \section{Image formats} \label{sec:format} -VIPS has a simple system for adding support for new image file formats. You -can register a new format and it will automatically be supported by all -the VIPS interfaces. You can ask VIPS to find a format to load a file with, +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. +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, @@ -18,7 +18,7 @@ images if you use \verb+im_open()+. \subsection{How a format is represented} -See the man page for \verb+im_format+ for full details, but briefly, an image +See the man page for \verb+VipsFormat+ for full details, but briefly, an image format consists of the following items: \begin{itemize} @@ -33,7 +33,7 @@ height and does not read any pixel data) and a function which loads the pixel data \item -A function which will write an IMAGE to a file in the format +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 @@ -44,20 +44,11 @@ version is one indicating that the file can be opened lazily \subsection{The format table} -VIPS keeps a table of known formats, sorted by insert order and priority. You -register new formats with \verb+im_format_register()+ and, optionally, -unregister with \verb+im_format_unregister()+. You can call these operations -from a plugin's init function. - -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. - -The priority system is useful if a file can be read by several possible format -loaders. For example, the libMagick loader can read TIFF files, but not as -well as VIPS' native TIFF reader. To make sure the VIPS TIFF reader is tried -first, the libMagick format is given a low priority. Most of the time, you -won't need this. +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. A switch to the \verb+vips+ command-line program is handy for listing the supported formats. Try: @@ -86,21 +77,40 @@ is_myformat( const char *filename ) return( 0 ); } +// This format adds no new members. +typedef VipsFormat VipsFormatMyformat; +typedef VipsFormatClass VipsFormatMyformatClass; + +static void +vips_format_myformat_class_init( VipsFormatVipsClass *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_vips_init( VipsFormatVips *object ) +{ +} + +G_DEFINE_TYPE( VipsFormatVips, vips_format_vips, VIPS_TYPE_FORMAT ); + char * g_module_check_init( GModule *self ) { - im_format_t *format; - - format = im_format_register( "myformat", - _( "My image format" ), - my_suffs, - is_myformat, - read_myformat_header, - read_myformat_image, - write_myformat, - NULL - }; - im_format_set_priority( format, 100 ); + // register the type + vips_format_vips_get_type(); } \end{verbatim} \caption{Registering a format in a plugin} @@ -109,22 +119,21 @@ g_module_check_init( GModule *self ) \subsection{Finding a format} -You can loop over the format table in order with \verb+im_format_map()+. Like +You can loop over the format table in order 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 it returns non-zero, or until the table has been -all covered. +element in the table until it returns non-zero, or until the table ends. -You find an \verb+im_format_t+ to use to open a file with -\verb+im_format_for_file()+. This searches the VIPS format table and returns +You find an \verb+VipsFormatClass+ to use to open a file with +\verb+vips_format_for_file()+. This searches the type system and returns the first format whose test function returns true, setting an error message and returning NULL if no format is found. -You find a format to write a file with \verb+im_format_for_name()+. This +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+im_format_write()+ and -\verb+im_format_read()+, will copy an image to and from disc using the +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. diff --git a/include/vips/format.h b/include/vips/format.h index 6f45bac8..95e7e4d0 100644 --- a/include/vips/format.h +++ b/include/vips/format.h @@ -54,8 +54,8 @@ extern "C" { * im_format_flags_fn(). 0 is default. */ typedef enum { - VIPS_FORMAT_FLAG_NONE = 0, /* No flags set */ - VIPS_FORMAT_FLAG_PARTIAL = 1 /* Lazy read OK (eg. tiled tiff) */ + VIPS_FORMAT_NONE = 0, /* No flags set */ + VIPS_FORMAT_PARTIAL = 1 /* Lazy read OK (eg. tiled tiff) */ } VipsFormatFlags; /* Function protos for formats. diff --git a/libsrc/format/format.c b/libsrc/format/format.c index a47e406f..6b849d57 100644 --- a/libsrc/format/format.c +++ b/libsrc/format/format.c @@ -125,7 +125,7 @@ vips2file( IMAGE *im, const char *filename ) static VipsFormatFlags vips_flags( const char *filename ) { - return( VIPS_FORMAT_FLAG_PARTIAL ); + return( VIPS_FORMAT_PARTIAL ); } /* Vips format adds no new members. diff --git a/libsrc/format/im_analyze2vips.c b/libsrc/format/im_analyze2vips.c index 666f1a35..79eeace2 100644 --- a/libsrc/format/im_analyze2vips.c +++ b/libsrc/format/im_analyze2vips.c @@ -586,7 +586,7 @@ static const char *analyze_suffs[] = { ".img", ".hdr", NULL }; static VipsFormatFlags analyze_flags( const char *filename ) { - return( VIPS_FORMAT_FLAG_PARTIAL ); + return( VIPS_FORMAT_PARTIAL ); } /* analyze format adds no new members. diff --git a/libsrc/format/im_exr2vips.c b/libsrc/format/im_exr2vips.c index 84e505e3..467c3d02 100644 --- a/libsrc/format/im_exr2vips.c +++ b/libsrc/format/im_exr2vips.c @@ -456,7 +456,7 @@ exr_flags( const char *filename ) flags = 0; if( isexrtiled( filename ) ) - flags |= VIPS_FORMAT_FLAG_PARTIAL; + flags |= VIPS_FORMAT_PARTIAL; return( flags ); } diff --git a/libsrc/format/im_ppm2vips.c b/libsrc/format/im_ppm2vips.c index cb864e62..74a0e450 100644 --- a/libsrc/format/im_ppm2vips.c +++ b/libsrc/format/im_ppm2vips.c @@ -496,7 +496,7 @@ ppm_flags( const char *filename ) flags = 0; if( isppmmmap( filename ) ) - flags |= VIPS_FORMAT_FLAG_PARTIAL; + flags |= VIPS_FORMAT_PARTIAL; return( flags ); } diff --git a/libsrc/format/im_tiff2vips.c b/libsrc/format/im_tiff2vips.c index 3cd90206..c83052ff 100644 --- a/libsrc/format/im_tiff2vips.c +++ b/libsrc/format/im_tiff2vips.c @@ -1545,7 +1545,7 @@ tiff_flags( const char *filename ) flags = 0; if( istifftiled( filename ) ) - flags |= VIPS_FORMAT_FLAG_PARTIAL; + flags |= VIPS_FORMAT_PARTIAL; return( flags ); } diff --git a/man/VipsFormat.3 b/man/VipsFormat.3 index c576e6af..9293ef1b 100644 --- a/man/VipsFormat.3 +++ b/man/VipsFormat.3 @@ -9,24 +9,44 @@ load and search image formats typedef enum { .br - VIPS_FORMAT_FLAG_NONE = 0, + VIPS_FORMAT_NONE = 0, .br - VIPS_FORMAT_FLAG_PARTIAL = 1 + VIPS_FORMAT_PARTIAL = 1 .br } VipsFormatFlags; +typedef struct _VipsFormatClass { +.br + VipsObjectClass parent_class; + + gboolean (*is_a)( const char * ); +.br + int (*header)( const char *, IMAGE * ); +.br + int (*load)( const char *, IMAGE * ); +.br + int (*save)( IMAGE *, const char * ); +.br + VipsFormatFlags (*get_flags)( const char * ); +.br + int priority; +.br + const char **suffs; +.br +} VipsFormatClass; + void *vips_format_map( VSListMap2Fn fn, void *a, void *b ); .br VipsFormatClass *vips_format_for_file( const char *filename ); .br VipsFormatClass *vips_format_for_name( const char *filename ); -int im_format_write( IMAGE *im, const char *filename ); +int vips_format_write( IMAGE *im, const char *filename ); -int im_format_read( const char *filename, IMAGE *out ); +int vips_format_read( const char *filename, IMAGE *out ); .SH DESCRIPTION -These functions register and unregister image formats, and search the table of +These functions search the available image formats to find one suitable for loading or saving a file. .B im_open(3) @@ -36,39 +56,29 @@ than copying to a descriptor you supply. The two APIs are useful in different circumstances: .B im_open(3) is good if you want to directly manipulate a file on disc, for example with -the paintbox functions. The format API is useful for controlling how a image +the paintbox functions. On the other hand, this format API is useful for +controlling how a image is unpacked, since you can specify a destination for the copy. -.B im_format_register(3) -registers an image format with vips. This might typically be called during -module load, see the documentation for GModule. +Image formats are subclasses of +.B VipsFormat +as outlined above. They are expected to implement at least one of the methods. +They should also set values for the +.B nickname +and +.B description +members of +.B VipsObject. -An image format has a number of components: +Other members are: -.B name -The internal name by which the format should be known. For example, the -OpenEXR image format is known within vips as "exr". You can identify formats -by testing this field with -.B strcmp(3). - -.B name_user -The name as it should be displayed to the user. It can be internationalised. -For example, in English, the "analyze" format is shown as "Analyze 6.0". - -.B suffs -A NULL-terminated array of possible file-name suffixes for this format. This -list is used to filter filenames when they are shown to the user, and to help -select a format to sav a file as. For example, the JPEG format has the -suffixes: -.B { ".jpg", ".jpeg", ".jpe", NULL } - -.B is_a +.B is_a() A function which tests whether a file is of the specified format. This is useful if you can guess a file type from the first few bytes in the file. If you leave this function NULL, vips will guess from the filename suffix for you. -.B header +.B header() Load only the image header, not any of the image pixels. vips will call this first on .B im_open(3) @@ -77,54 +87,53 @@ use the .B load function. -.B load +.B load() Load the image from the file into the IMAGE. You can leave this function NULL if you only have a -.B save +.B save() method implemented. -.B save +.B save() Write from the IMAGE to the file in this format. You can leave this function -NULL if you only have a lload method implemented. +NULL if you only have a load method implemented. -.B flags -A function which examines the file and sets various flags to indicated +.B get_flags() +A function which examines the file and sets various flags to indicate properties of the image. The only flag implemented at the moment is -.B IM_FORMAT_FLAG_PARTIAL +.B VIPS_FORMAT_PARTIAL which may be set to indicate that the file can be read lazily. -vips registers the format and returns a pointer to the -.B im_format_t -it created. This may later be used to unregister the format. - -.B im_format_set_priority(3) +.B priority sets a priority for the format. Priorities for formats default to zero: you mmay set a lower or higher number to set where in the format table your format is positioned. -.B im_format_unregister(3) -removes a format from vips. It mmight typically be called during module -unload, see the documentation for GModule. +.B suffs +A NULL-terminated array of possible file-name suffixes for this format. This +list is used to filter filenames when they are shown to the user, and to help +select a format to sav a file as. For example, the JPEG format has the +suffixes: +.B { ".jpg", ".jpeg", ".jpe", NULL } -.B im_format_map(3) -maps a function over the list of loaded formats. See +.B vips_format_map(3) +maps a function over the list of available formats. See .B im_slist_map(3). -.B im_format_for_file(3) +.B vips_format_for_file(3) looks at a file on disc and selects the 'best' format to use to load that file. If no suitable format is found, it returns NULL and sets an error message. -.B im_format_for_name(3) +.B vips_format_for_name(3) looks at a filename and picks a format to use to save that file based on the file extension. If no suitable format is found, it returns NULL and sets an error message. -.B im_format_read(3) +.B vips_format_read(3) is a convenience function which copies the image from the file into the IMAGE. error, it returns non-zero and sets an error message. -.B im_format_write(3) +.B vips_format_write(3) is a convenience function which copies the image to the file in the appropriate format. On error, it returns non-zero and sets an error message.