im_format -> VipsFormat

This commit is contained in:
John Cupitt 2008-11-28 16:26:33 +00:00
parent c5de67a542
commit 9518a659ab
17 changed files with 494 additions and 308 deletions

View File

@ -14,6 +14,7 @@
- cleanups after yafr hacking
- added affinei_all
- don't set im_error() on failed callback
- moved im_format_t to VipsFormat, now sits over VipsObject
11/9/08 started 7.16.3
- oop typo in manpage for im_project()

19
TODO
View File

@ -1,6 +1,25 @@
- format/ now uses VipsFormat
im_format docs need redoing
nip2 needs revising
user G_DEFINE_ABSTRACT_TYPE for VipsObject
- we have
VipsFormatFlags
VIPS_FORMAT_FLAG_PARTIAL
is this right? should we use singular or plural?
- started adding
#define IM_TYPE_GOBJECT "gobject" /* A GObject of a specified class */
or maybe "transform"? flip/rot90/embed etc. as well?
- make a "deprecated" package too

View File

@ -1,4 +1,5 @@
/* Suppprted image formats.
/* Abstract base type for supported image formats. Subclass this to add a new
* format.
*/
/*
@ -34,56 +35,85 @@
extern "C" {
#endif /*__cplusplus*/
#define VIPS_TYPE_FORMAT (vips_format_get_type())
#define VIPS_FORMAT( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FORMAT, VipsFormat ))
#define VIPS_FORMAT_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FORMAT, VipsFormatClass))
#define VIPS_IS_FORMAT( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FORMAT ))
#define VIPS_IS_FORMAT_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FORMAT ))
#define VIPS_FORMAT_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FORMAT, VipsFormatClass ))
/* Image file properties. OR these together to get the result of
* im_format_flags_fn(). 0 is default.
*/
typedef enum {
IM_FORMAT_FLAG_NONE = 0,/* No flags set */
IM_FORMAT_FLAG_PARTIAL = 1/* Lazy read OK (eg. tiled tiff) */
} im_format_flags;
VIPS_FORMAT_FLAG_NONE = 0, /* No flags set */
VIPS_FORMAT_FLAG_PARTIAL = 1 /* Lazy read OK (eg. tiled tiff) */
} VipsFormatFlags;
/* Function protos for formats.
*/
typedef gboolean (*im_format_is_a_fn)( const char * );
typedef int (*im_format_header_fn)( const char *, IMAGE * );
typedef int (*im_format_load_fn)( const char *, IMAGE * );
typedef int (*im_format_save_fn)( IMAGE *, const char * );
typedef im_format_flags (*im_format_flags_fn)( const char * );
/* A VIPS image format.
*/
typedef struct im__format_t {
const char *name; /* Format name, same as mime */
const char *name_user; /* I18n'd name for users */
int priority; /* Keep formats sorted by this, default 0 */
const char **suffs; /* Allowed suffixes */
im_format_is_a_fn is_a; /* Filename is in format */
im_format_header_fn header;/* Load header only from filename */
im_format_load_fn load; /* Load image from filename */
im_format_save_fn save; /* Save image to filename */
im_format_flags_fn flags;/* Get flags for filename */
} im_format_t;
typedef struct _VipsFormat {
VipsObject parent_object;
/* Register/unregister formats.
*/
im_format_t *im_format_register(
const char *name, const char *name_user, const char **suffs,
im_format_is_a_fn is_a, im_format_header_fn header,
im_format_load_fn load, im_format_save_fn save,
im_format_flags_fn flags );
void im_format_set_priority( im_format_t *format, int priority );
void im_format_unregister( im_format_t *format );
} VipsFormat;
/* Map over and find formats.
*/
void *im_format_map( VSListMap2Fn fn, void *a, void *b );
im_format_t *im_format_for_file( const char *filename );
im_format_t *im_format_for_name( const char *filename );
typedef struct _VipsFormatClass {
VipsObjectClass parent_class;
/* Write an image convenience function.
/* Is a file in this format.
*/
gboolean (*is_a)( const char * );
/* Read just the header into the IMAGE.
*/
int (*header)( const char *, IMAGE * );
/* Load the whole image.
*/
int (*load)( const char *, IMAGE * );
/* Write the IMAGE to the file in this format.
*/
int (*save)( IMAGE *, const char * );
/* Get the flags for this file in this format.
*/
VipsFormatFlags (*get_flags)( const char * );
/* Loop over formats in this order, default 0. We need this because
* some formats can be read by several loaders (eg. tiff can be read
* by the libMagick loader as well as by the tiff loader), and we want
* to make sure the better loader comes first.
*/
int priority;
/* Null-terminated list of allowed suffixes, eg. ".tif", ".tiff".
*/
const char **suffs;
} VipsFormatClass;
GType vips_format_get_type( void );
/* Map over and find formats. This uses type introspection to loop over
* subclasses of VipsFormat.
*/
int im_format_read( const char *name, IMAGE *out );
int im_format_write( IMAGE *im, const char *name );
void *vips_format_map( VSListMap2Fn fn, void *a, void *b );
VipsFormatClass *vips_format_for_file( const char *filename );
VipsFormatClass *vips_format_for_name( const char *filename );
/* Read/write an image convenience functions.
*/
int vips_format_read( const char *name, IMAGE *out );
int vips_format_write( IMAGE *im, const char *name );
#ifdef __cplusplus
}

View File

@ -300,11 +300,13 @@ void *im_map_equal( void *a, void *b );
void *im_hash_table_map( GHashTable *hash, VSListMap2Fn fn, void *a, void *b );
typedef void *(*VTypeMapFn)( GType, void * );
typedef void *(*VTypeMap2Fn)( GType, void *, void * );
void *im_type_map( GType base, VTypeMap2Fn fn, void *a, void *b );
void *im_type_map_concrete_all( GType base, VTypeMapFn fn, void *a );
GType im_type_find( const char *basename, const char *nickname );
typedef void *(*VipsTypeMap)( GType, void * );
typedef void *(*VipsTypeMap2)( GType, void *, void * );
typedef void *(*VipsClassMap)( VipsObjectClass *, void * );
void *vips_type_map( GType base, VipsTypeMap2 fn, void *a, void *b );
void *vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a );
void *vips_class_map_concrete_all( GType base, VipsClassMap fn, void *a );
GType vips_type_find( const char *basename, const char *nickname );
char *im_strncpy( char *dest, const char *src, int n );
char *im_strrstr( const char *haystack, const char *needle );

View File

@ -41,71 +41,60 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/* List of loaded formats.
/* To iterate over supported formats, we build a temp list of subclasses of
* VipsFormat, sort by priority, iterate, and free.
*/
static GSList *format_list = NULL;
static void *
format_add_class( VipsFormatClass *format, GSList **formats )
{
/* Append so we don't reverse the list of formats.
*/
*formats = g_slist_append( *formats, format );
return( NULL );
}
static gint
format_compare( im_format_t *a, im_format_t *b )
format_compare( VipsFormatClass *a, VipsFormatClass *b )
{
return( b->priority - a->priority );
}
/* Sort the format list after a change.
void *
vips_format_map( VSListMap2Fn fn, void *a, void *b )
{
GSList *formats;
void *result;
formats = NULL;
(void) vips_class_map_concrete_all( g_type_from_name( "VipsFormat" ),
(VipsClassMap) format_add_class, (void *) &formats );
formats = g_slist_sort( formats, (GCompareFunc) format_compare );
result = im_slist_map2( formats, fn, a, b );
g_slist_free( formats );
return( result );
}
/* Abstract base class for image formats.
*/
static void
format_sort( void )
vips_format_class_init( VipsFormatClass *class )
{
format_list = g_slist_sort( format_list,
(GCompareFunc) format_compare );
}
/* Register/unregister formats.
static void
vips_format_init( VipsFormat *object )
{
}
G_DEFINE_ABSTRACT_TYPE( VipsFormat, vips_format, VIPS_TYPE_OBJECT );
/* VIPS format class.
*/
im_format_t *
im_format_register(
const char *name, const char *name_user, const char **suffs,
im_format_is_a_fn is_a, im_format_header_fn header,
im_format_load_fn load, im_format_save_fn save,
im_format_flags_fn flags )
{
im_format_t *format;
if( !(format = IM_NEW( NULL, im_format_t )) )
return( NULL );
format->name = name;
format->name_user = name_user;
format->priority = 0;
format->suffs = suffs;
format->is_a = is_a;
format->header = header;
format->load = load;
format->save = save;
format->flags = flags;
/* Append, so we keep the ordering where possible.
*/
format_list = g_slist_append( format_list, format );
format_sort();
return( format );
}
void
im_format_set_priority( im_format_t *format, int priority )
{
g_assert( format );
format->priority = priority;
format_sort();
}
void
im_format_unregister( im_format_t *format )
{
format_list = g_slist_remove( format_list, format );
IM_FREE( format );
}
static const char *vips_suffs[] = { ".v", NULL };
@ -133,60 +122,80 @@ vips2file( IMAGE *im, const char *filename )
return( 0 );
}
static im_format_flags
static VipsFormatFlags
vips_flags( const char *filename )
{
return( IM_FORMAT_FLAG_PARTIAL );
return( VIPS_FORMAT_FLAG_PARTIAL );
}
/* Vips format adds no new members.
*/
typedef VipsFormat VipsFormatVips;
typedef VipsFormatClass VipsFormatVipsClass;
static void
vips_format_vips_class_init( VipsFormatVipsClass *class )
{
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "vips";
object_class->description = _( "VIPS" );
format_class->is_a = im_isvips;
format_class->header = file2vips;
format_class->load = file2vips;
format_class->save = vips2file;
format_class->get_flags = vips_flags;
format_class->suffs = vips_suffs;
}
static void
vips_format_vips_init( VipsFormatVips *object )
{
}
G_DEFINE_TYPE( VipsFormatVips, vips_format_vips, VIPS_TYPE_FORMAT );
/* Called on startup: register the base vips formats.
*/
void
im__format_init( void )
{
im_format_register(
"vips", /* internal name */
_( "VIPS" ), /* i18n'd visible name */
vips_suffs, /* Allowed suffixes */
im_isvips, /* is_a */
file2vips, /* Load header only */
file2vips, /* Load */
vips2file, /* Save */
vips_flags /* Flags */
);
extern GType vips_format_csv_get_type();
extern GType vips_format_ppm_get_type();
extern GType vips_format_analyze_get_type();
vips_format_vips_get_type();
#ifdef HAVE_JPEG
im__jpeg_register();
extern GType vips_format_jpeg_get_type();
vips_format_jpeg_get_type();
#endif /*HAVE_JPEG*/
#ifdef HAVE_PNG
im__png_register();
extern GType vips_format_png_get_type();
vips_format_png_get_type();
#endif /*HAVE_PNG*/
im__csv_register();
im__ppm_register();
im__analyze_register();
vips_format_csv_get_type();
vips_format_ppm_get_type();
vips_format_analyze_get_type();
#ifdef HAVE_OPENEXR
im__exr_register();
extern GType vips_format_exr_get_type();
vips_format_exr_get_type();
#endif /*HAVE_OPENEXR*/
#ifdef HAVE_MAGICK
im__magick_register();
extern GType vips_format_magick_get_type();
vips_format_magick_get_type();
#endif /*HAVE_MAGICK*/
#ifdef HAVE_TIFF
im__tiff_register();
extern GType vips_format_tiff_get_type();
vips_format_tiff_get_type();
#endif /*HAVE_TIFF*/
}
/* Map a function over all formats.
*/
void *
im_format_map( VSListMap2Fn fn, void *a, void *b )
{
return( im_slist_map2( format_list, fn, a, b ) );
}
/* Can this format open this file?
*/
static void *
format_for_file_sub( im_format_t *format,
format_for_file_sub( VipsFormatClass *format,
const char *name, const char *filename )
{
if( format->is_a ) {
@ -199,12 +208,12 @@ format_for_file_sub( im_format_t *format,
return( NULL );
}
im_format_t *
im_format_for_file( const char *name )
VipsFormatClass *
vips_format_for_file( const char *name )
{
char filename[FILENAME_MAX];
char options[FILENAME_MAX];
im_format_t *format;
VipsFormatClass *format;
/* Break any options off the name ... eg. "fred.tif:jpeg,tile"
* etc.
@ -212,15 +221,15 @@ im_format_for_file( const char *name )
im_filename_split( name, filename, options );
if( !im_existsf( "%s", filename ) ) {
im_error( "im_format_for_file",
im_error( "vips_format_for_file",
_( "\"%s\" is not readable" ), filename );
return( NULL );
}
if( !(format = (im_format_t *) im_format_map(
if( !(format = (VipsFormatClass *) vips_format_map(
(VSListMap2Fn) format_for_file_sub,
(void *) name, (void *) filename )) ) {
im_error( "im_format_for_file",
im_error( "vips_format_for_file",
_( "\"%s\" is not in a supported format" ), filename );
return( NULL );
}
@ -232,7 +241,7 @@ im_format_for_file( const char *name )
* method.
*/
static void *
format_for_name_sub( im_format_t *format, const char *name )
format_for_name_sub( VipsFormatClass *format, const char *name )
{
if( format->save &&
im_filename_suffix_match( name, format->suffs ) )
@ -241,17 +250,17 @@ format_for_name_sub( im_format_t *format, const char *name )
return( NULL );
}
im_format_t *
im_format_for_name( const char *name )
VipsFormatClass *
vips_format_for_name( const char *name )
{
im_format_t *format;
VipsFormatClass *format;
if( !(format = (im_format_t *) im_format_map(
if( !(format = (VipsFormatClass *) vips_format_map(
(VSListMap2Fn) format_for_name_sub, (void *) name, NULL )) ) {
char suffix[FILENAME_MAX];
im_filename_suffix( name, suffix );
im_error( "im_format_for_name",
im_error( "vips_format_for_name",
_( "\"%s\" is not a supported image format." ),
suffix );
@ -262,11 +271,11 @@ im_format_for_name( const char *name )
}
int
im_format_read( const char *name, IMAGE *out )
vips_format_read( const char *name, IMAGE *out )
{
im_format_t *format;
VipsFormatClass *format;
if( !(format = im_format_for_file( name )) ||
if( !(format = vips_format_for_file( name )) ||
format->load( name, out ) )
return( -1 );
@ -274,11 +283,11 @@ im_format_read( const char *name, IMAGE *out )
}
int
im_format_write( IMAGE *im, const char *name )
vips_format_write( IMAGE *im, const char *name )
{
im_format_t *format;
VipsFormatClass *format;
if( !(format = im_format_for_name( name )) ||
if( !(format = vips_format_for_name( name )) ||
format->save( im, name ) )
return( -1 );

View File

@ -583,23 +583,37 @@ im_analyze2vips( const char *filename, IMAGE *out )
static const char *analyze_suffs[] = { ".img", ".hdr", NULL };
static im_format_flags
static VipsFormatFlags
analyze_flags( const char *filename )
{
return( IM_FORMAT_FLAG_PARTIAL );
return( VIPS_FORMAT_FLAG_PARTIAL );
}
void
im__analyze_register( void )
/* analyze format adds no new members.
*/
typedef VipsFormat VipsFormatAnalyze;
typedef VipsFormatClass VipsFormatAnalyzeClass;
static void
vips_format_analyze_class_init( VipsFormatAnalyzeClass *class )
{
im_format_register(
"analyze", /* internal name */
_( "Analyze 6.0" ), /* i18n'd visible name */
analyze_suffs, /* Allowed suffixes */
isanalyze, /* is_a */
analyze2vips_header, /* Load header only */
im_analyze2vips, /* Load */
NULL, /* Save */
analyze_flags /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "analyze";
object_class->description = _( "Analyze 6.0" );
format_class->is_a = isanalyze;
format_class->header = analyze2vips_header;
format_class->load = im_analyze2vips;
format_class->get_flags = analyze_flags;
format_class->suffs = analyze_suffs;
}
static void
vips_format_analyze_init( VipsFormatAnalyze *object )
{
}
G_DEFINE_TYPE( VipsFormatAnalyze, vips_format_analyze, VIPS_TYPE_FORMAT );

View File

@ -318,17 +318,29 @@ csv2vips_header( const char *filename, IMAGE *out )
static const char *csv_suffs[] = { ".csv", NULL };
void
im__csv_register( void )
/* csv format adds no new members.
*/
typedef VipsFormat VipsFormatCsv;
typedef VipsFormatClass VipsFormatCsvClass;
static void
vips_format_csv_class_init( VipsFormatCsvClass *class )
{
im_format_register(
"csv", /* internal name */
_( "CSV" ), /* i18n'd visible name */
csv_suffs, /* Allowed suffixes */
NULL, /* is_a */
csv2vips_header, /* Load header only */
im_csv2vips, /* Load */
im_vips2csv, /* Save */
NULL /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "csv";
object_class->description = _( "CSV" );
format_class->header = csv2vips_header;
format_class->load = im_csv2vips;
format_class->save = im_vips2csv;
format_class->suffs = csv_suffs;
}
static void
vips_format_csv_init( VipsFormatCsv *object )
{
}
G_DEFINE_TYPE( VipsFormatCsv, vips_format_csv, VIPS_TYPE_FORMAT );

View File

@ -449,31 +449,44 @@ isexr( const char *filename )
static const char *exr_suffs[] = { ".exr", NULL };
static im_format_flags
static VipsFormatFlags
exr_flags( const char *filename )
{
im_format_flags flags;
VipsFormatFlags flags;
flags = 0;
if( isexrtiled( filename ) )
flags |= IM_FORMAT_FLAG_PARTIAL;
flags |= VIPS_FORMAT_FLAG_PARTIAL;
return( flags );
}
void
im__exr_register( void )
/* exr format adds no new members.
*/
typedef VipsFormat VipsFormatExr;
typedef VipsFormatClass VipsFormatExrClass;
static void
vips_format_exr_class_init( VipsFormatExrClass *class )
{
im_format_register(
"exr", /* internal name */
_( "OpenEXR" ), /* i18n'd visible name */
exr_suffs, /* Allowed suffixes */
isexr, /* is_a */
exr2vips_header, /* Load header only */
im_exr2vips, /* Load */
NULL, /* Save */
exr_flags /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "exr";
object_class->description = _( "OpenEXR" );
format_class->is_a = isexr;
format_class->header = exr2vips_header;
format_class->load = im_exr2vips;
format_class->get_flags = exr_flags;
format_class->suffs = exr_suffs;
}
static void
vips_format_exr_init( VipsFormatExr *object )
{
}
G_DEFINE_TYPE( VipsFormatExr, vips_format_exr, VIPS_TYPE_FORMAT );
#endif /*HAVE_OPENEXR*/

View File

@ -720,19 +720,32 @@ jpeg2vips_header( const char *name, IMAGE *out )
static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL };
void
im__jpeg_register( void )
/* jpeg format adds no new members.
*/
typedef VipsFormat VipsFormatJpeg;
typedef VipsFormatClass VipsFormatJpegClass;
static void
vips_format_jpeg_class_init( VipsFormatJpegClass *class )
{
im_format_register(
"jpeg", /* internal name */
_( "JPEG" ), /* i18n'd visible name */
jpeg_suffs, /* Allowed suffixes */
isjpeg, /* is_a */
jpeg2vips_header, /* Load header only */
im_jpeg2vips, /* Load */
im_vips2jpeg, /* Save */
NULL /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "jpeg";
object_class->description = _( "JPEG" );
format_class->is_a = isjpeg;
format_class->header = jpeg2vips_header;
format_class->load = im_jpeg2vips;
format_class->save = im_vips2jpeg;
format_class->suffs = jpeg_suffs;
}
static void
vips_format_jpeg_init( VipsFormatJpeg *object )
{
}
G_DEFINE_TYPE( VipsFormatJpeg, vips_format_jpeg, VIPS_TYPE_FORMAT );
#endif /*HAVE_JPEG*/

View File

@ -657,22 +657,36 @@ ismagick( const char *filename )
static const char *magick_suffs[] = { NULL };
void
im__magick_register( void )
{
im_format_t *format;
/* magick format adds no new members.
*/
typedef VipsFormat VipsFormatMagick;
typedef VipsFormatClass VipsFormatMagickClass;
format = im_format_register(
"magick", /* internal name */
_( "libMagick-supported" ),/* i18n'd visible name */
magick_suffs, /* Allowed suffixes */
ismagick, /* is_a */
magick2vips_header, /* Load header only */
im_magick2vips, /* Load */
NULL, /* Save */
NULL /* Flags */
);
im_format_set_priority( format, -1000 );
static void
vips_format_magick_class_init( VipsFormatMagickClass *class )
{
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "magick";
object_class->description = _( "libMagick-supported" );
format_class->is_a = ismagick;
format_class->header = magick2vips_header;
format_class->load = im_magick2vips;
format_class->suffs = magick_suffs;
/* This can be very slow :-( Use our own jpeg/tiff/png etc. loaders in
* preference if we can.
*/
format_class->priority = -1000;
}
static void
vips_format_magick_init( VipsFormatMagick *object )
{
}
G_DEFINE_TYPE( VipsFormatMagick, vips_format_magick, VIPS_TYPE_FORMAT );
#endif /*HAVE_MAGICK*/

View File

@ -383,19 +383,32 @@ ispng( const char *filename )
static const char *png_suffs[] = { ".png", NULL };
void
im__png_register( void )
/* png format adds no new members.
*/
typedef VipsFormat VipsFormatPng;
typedef VipsFormatClass VipsFormatPngClass;
static void
vips_format_png_class_init( VipsFormatPngClass *class )
{
im_format_register(
"png", /* internal name */
_( "PNG" ), /* i18n'd visible name */
png_suffs, /* Allowed suffixes */
ispng, /* is_a */
png2vips_header, /* Load header only */
im_png2vips, /* Load */
im_vips2png, /* Save */
NULL /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "png";
object_class->description = _( "PNG" );
format_class->is_a = ispng;
format_class->header = png2vips_header;
format_class->load = im_png2vips;
format_class->save = im_vips2png;
format_class->suffs = png_suffs;
}
static void
vips_format_png_init( VipsFormatPng *object )
{
}
G_DEFINE_TYPE( VipsFormatPng, vips_format_png, VIPS_TYPE_FORMAT );
#endif /*HAVE_PNG*/

View File

@ -489,31 +489,46 @@ isppm( const char *filename )
/* ppm flags function.
*/
static im_format_flags
static VipsFormatFlags
ppm_flags( const char *filename )
{
im_format_flags flags;
VipsFormatFlags flags;
flags = 0;
if( isppmmmap( filename ) )
flags |= IM_FORMAT_FLAG_PARTIAL;
flags |= VIPS_FORMAT_FLAG_PARTIAL;
return( flags );
}
static const char *ppm_suffs[] = { ".ppm", ".pgm", ".pbm", NULL };
void
im__ppm_register( void )
/* ppm format adds no new members.
*/
typedef VipsFormat VipsFormatPpm;
typedef VipsFormatClass VipsFormatPpmClass;
static void
vips_format_ppm_class_init( VipsFormatPpmClass *class )
{
im_format_register(
"ppm", /* internal name */
_( "PPM/PBM/PNM" ), /* i18n'd visible name */
ppm_suffs, /* Allowed suffixes */
isppm, /* is_a */
ppm2vips_header, /* Load header only */
im_ppm2vips, /* Load */
im_vips2ppm, /* Save */
ppm_flags /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "ppm";
object_class->description = _( "PPM/PBM/PNM" );
format_class->is_a = isppm;
format_class->header = ppm2vips_header;
format_class->load = im_ppm2vips;
format_class->save = im_vips2ppm;
format_class->get_flags = ppm_flags;
format_class->suffs = ppm_suffs;
}
static void
vips_format_ppm_init( VipsFormatPpm *object )
{
}
G_DEFINE_TYPE( VipsFormatPpm, vips_format_ppm, VIPS_TYPE_FORMAT );

View File

@ -1538,33 +1538,47 @@ istifftiled( const char *filename )
/* TIFF flags function.
*/
static im_format_flags
static VipsFormatFlags
tiff_flags( const char *filename )
{
im_format_flags flags;
VipsFormatFlags flags;
flags = 0;
if( istifftiled( filename ) )
flags |= IM_FORMAT_FLAG_PARTIAL;
flags |= VIPS_FORMAT_FLAG_PARTIAL;
return( flags );
}
static const char *tiff_suffs[] = { ".tif", ".tiff", NULL };
void
im__tiff_register( void )
/* tiff format adds no new members.
*/
typedef VipsFormat VipsFormatTiff;
typedef VipsFormatClass VipsFormatTiffClass;
static void
vips_format_tiff_class_init( VipsFormatTiffClass *class )
{
im_format_register(
"tiff", /* internal name */
_( "TIFF" ), /* i18n'd visible name */
tiff_suffs, /* Allowed suffixes */
istiff, /* is_a */
tiff2vips_header, /* Load header only */
im_tiff2vips, /* Load */
im_vips2tiff, /* Save */
tiff_flags /* Flags */
);
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFormatClass *format_class = (VipsFormatClass *) class;
object_class->nickname = "tiff";
object_class->description = _( "TIFF" );
format_class->is_a = istiff;
format_class->header = tiff2vips_header;
format_class->load = im_tiff2vips;
format_class->save = im_vips2tiff;
format_class->get_flags = tiff_flags;
format_class->suffs = tiff_suffs;
}
static void
vips_format_tiff_init( VipsFormatTiff *object )
{
}
G_DEFINE_TYPE( VipsFormatTiff, vips_format_tiff, VIPS_TYPE_FORMAT );
#endif /*HAVE_TIFF*/

View File

@ -344,7 +344,7 @@ IMAGE *
im_open( const char *filename, const char *mode )
{
IMAGE *im;
im_format_t *format;
VipsFormatClass *format;
/* Pass in a nonsense name for argv0 ... this init world is only here
* for old programs which are missing an im_init_world() call. We must
@ -370,8 +370,9 @@ im_open( const char *filename, const char *mode )
switch( mode[0] ) {
case 'r':
if( (format = im_format_for_file( filename )) ) {
if( strcmp( format->name, "vips" ) == 0 ) {
if( (format = vips_format_for_file( filename )) ) {
if( strcmp( VIPS_OBJECT_CLASS( format )->nickname,
"vips" ) == 0 ) {
if( !(im = im_open_vips( filename )) )
return( NULL );
}
@ -388,8 +389,9 @@ im_open( const char *filename, const char *mode )
break;
case 'w':
if( (format = im_format_for_name( filename )) ) {
if( strcmp( format->name, "vips" ) == 0 )
if( (format = vips_format_for_name( filename )) ) {
if( strcmp( VIPS_OBJECT_CLASS( format )->nickname,
"vips" ) == 0 )
im = im_openout( filename );
else {
if( !(im = im_open( "im_open:lw:1", "p" )) )

View File

@ -245,7 +245,7 @@ im_hash_table_map( GHashTable *hash, VSListMap2Fn fn, void *a, void *b )
/* Map over all a type's children.
*/
void *
im_type_map( GType base, VTypeMap2Fn fn, void *a, void *b )
vips_type_map( GType base, VipsTypeMap2 fn, void *a, void *b )
{
GType *child;
guint n_children;
@ -264,7 +264,7 @@ im_type_map( GType base, VTypeMap2Fn fn, void *a, void *b )
/* Loop over all the concrete subtypes of a base type.
*/
void *
im_type_map_concrete_all( GType base, VTypeMapFn fn, void *a )
vips_type_map_concrete_all( GType base, VipsTypeMap fn, void *a )
{
void *result;
@ -272,69 +272,83 @@ im_type_map_concrete_all( GType base, VTypeMapFn fn, void *a )
if( !G_TYPE_IS_ABSTRACT( base ) )
result = fn( base, a );
if( !result )
result = im_type_map( base,
(VTypeMap2Fn) im_type_map_concrete_all, fn, a );
result = vips_type_map( base,
(VipsTypeMap2) vips_type_map_concrete_all, fn, a );
return( result );
}
static GType
test_name( GType type, const char *nickname )
/* Loop over all the subclasses of a base type.
*/
void *
vips_class_map_concrete_all( GType type, VipsClassMap fn, void *a )
{
GTypeClass *class;
VipsObjectClass *vips_class;
void *result;
/* Does this class exist? Try to create if not.
*/
if( !(class = g_type_class_peek( type )) )
/* We don't unref, so the class is never finalized. This will
* make the peek work next time around and save us from
* constantly building and destroying classes.
result = NULL;
if( !G_TYPE_IS_ABSTRACT( type ) ) {
GTypeClass *class;
/* Does this class exist? Try to create if not.
*/
if( !(class = g_type_class_ref( type )) )
return( 0 );
if( !(class = g_type_class_peek( type )) )
/* We don't unref, so the class is never finalized.
* This will make the peek work next time around and
* save us from constantly building and destroying
* classes.
*/
if( !(class = g_type_class_ref( type )) ) {
im_error( "vips_class_map_concrete_all",
"%s", _( "unable to build class" ) );
return( NULL );
}
if( !VIPS_IS_OBJECT_CLASS( class ) )
return( 0 );
vips_class = VIPS_OBJECT_CLASS( class );
if( strcasecmp( vips_class->nickname, nickname ) != 0 )
return( 0 );
result = fn( VIPS_OBJECT_CLASS( class ), a );
}
if( !result )
result = vips_type_map( type,
(VipsTypeMap2) vips_class_map_concrete_all, fn, a );
return( type );
return( result );
}
/* Find a GType ... search below base, return the first match on a nickname or
static void *
test_name( VipsObjectClass *class, const char *nickname )
{
if( strcasecmp( class->nickname, nickname ) != 0 )
return( class );
/* Check the class name too, why not.
*/
if( strcasecmp( G_OBJECT_CLASS_NAME( class ), nickname ) != 0 )
return( class );
return( NULL );
}
/* Find a class ... search below base, return the first match on a nickname or
* a name.
*/
GType
im_type_find( const char *basename, const char *nickname )
VipsObjectClass *
vips_class_find( const char *basename, const char *nickname )
{
VipsObjectClass *class;
GType base;
GType type;
if( !(base = g_type_from_name( basename )) ) {
im_error( "im_type_find",
_( "base type \"%s\" not found" ), basename );
return( 0 );
im_error( "vips_class_find",
_( "base class \"%s\" not found" ), basename );
return( NULL );
}
/* Users can pass the real name instead of a nickname, provided the
* real name names a subclass of base.
*/
if( (type = g_type_from_name( nickname )) )
if( g_type_is_a( type, base ) )
return( type );
if( !(class = vips_class_map_concrete_all( base,
(VipsClassMap) test_name, (void *) nickname )) ) {
im_error( "vips_class_find",
_( "class \"%s\" not found" ), nickname );
return( NULL );
}
/* Nope, need to search.
*/
if( (type = (GType) im_type_map_concrete_all( base,
(VTypeMapFn) test_name, (void *) nickname )) )
return( type );
im_error( "im_type_find",
_( "type \"%s\" not found" ), nickname );
return( 0 );
return( class );
}
/* Like strncpy(), but always NULL-terminate, and don't pad with NULLs.

View File

@ -164,11 +164,12 @@ list_function( im_function *func )
}
static void *
list_format( im_format_t *format )
list_format( VipsFormatClass *format )
{
const char **p;
printf( "%-20s - ", format->name_user );
printf( "%-20s - ",
VIPS_OBJECT_CLASS( format )->description );
printf( "(" );
for( p = format->suffs; *p; p++ ) {
@ -186,8 +187,8 @@ list_format( im_format_t *format )
printf( "load " );
if( format->save )
printf( "save " );
if( format->flags )
printf( "flags " );
if( format->get_flags )
printf( "get_flags " );
printf( "\n" );
return( NULL );
@ -199,7 +200,7 @@ print_list( const char *name )
if( strcmp( name, "packages" ) == 0 )
im_map_packages( (VSListMap2Fn) list_package, NULL );
else if( strcmp( name, "formats" ) == 0 )
im_format_map( (VSListMap2Fn) list_format, NULL, NULL );
vips_format_map( (VSListMap2Fn) list_format, NULL, NULL );
else {
if( map_name( name, list_function ) )
error_exit( "unknown package \"%s\"", name );