im_format -> VipsFormat
This commit is contained in:
parent
c5de67a542
commit
9518a659ab
@ -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
19
TODO
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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*/
|
||||
|
@ -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*/
|
||||
|
@ -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*/
|
||||
|
@ -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*/
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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*/
|
||||
|
@ -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" )) )
|
||||
|
@ -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.
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user