From 5ca62be716c4b4ef869eec82a948f247d1ddfcb8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 15 Aug 2008 21:45:18 +0000 Subject: [PATCH] clean up loadable formats --- ChangeLog | 1 + TODO | 18 ++- include/vips/Makefile.am | 1 + include/vips/dispatch.h | 44 ------ include/vips/format.h | 87 ++++++++++ include/vips/internal.h | 10 ++ include/vips/proto.h | 19 --- include/vips/vips.h | 1 + libsrc/format/Makefile.am | 2 +- libsrc/format/format.c | 205 ++++++++++++++++++++++++ libsrc/format/format_dispatch.c | 190 ---------------------- libsrc/format/im_analyze2vips.c | 30 +++- libsrc/format/im_csv2vips.c | 21 ++- libsrc/format/im_exr2vips.c | 73 ++++++--- libsrc/format/im_jpeg2vips.c | 47 ++++-- libsrc/format/im_magick2vips.c | 43 ++++- libsrc/format/im_png2vips.c | 37 ++++- libsrc/format/im_ppm2vips.c | 52 +++++- libsrc/format/im_tiff2vips.c | 102 ++++++++++-- libsrc/format/is_a.c | 271 -------------------------------- libsrc/iofuncs/package.c | 168 -------------------- libsrc/iofuncs/predicate.c | 22 +++ libsrc/iofuncs/util.c | 25 +++ 23 files changed, 706 insertions(+), 763 deletions(-) create mode 100644 include/vips/format.h create mode 100644 libsrc/format/format.c delete mode 100644 libsrc/format/is_a.c diff --git a/ChangeLog b/ChangeLog index a3ef67c0..0a71337e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ - oops, format sort order was reversed - im_filename_suffix() includes "." in suffix - merge back into trunk for 7.15.1 +- remove im_ispng(), im_png2vips_header() etc. & friends 7/3/08 started 7.15.0 - MAGIC constants should be tagged as unsigned diff --git a/TODO b/TODO index 668b3844..ffa64de4 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,19 @@ -- is_a.c should be broken out into the respective loaders? that's how it - wouldbe for plugns +- check man pages for im_isjpeg(), im_jpeg2vips_header() etc. + +- operations and jesper's types should all use the new register/unregister + model + + support backwards compat by calling im_operation_register() automatically + if we see a package_table symbol + + package.c needs to have the format_table stuff removed + + plugin init + + const char *g_module_check_init (GModule *) + + null for success, or errormsg + - something in vips.c to list the available formats, like diff --git a/include/vips/Makefile.am b/include/vips/Makefile.am index b2108620..cc0d5c90 100644 --- a/include/vips/Makefile.am +++ b/include/vips/Makefile.am @@ -7,6 +7,7 @@ pkginclude_HEADERS = \ colour.h \ debug.h \ dispatch.h \ + format.h \ fmask.h \ mosaic.h \ proto.h \ diff --git a/include/vips/dispatch.h b/include/vips/dispatch.h index 08fac6cf..751823f7 100644 --- a/include/vips/dispatch.h +++ b/include/vips/dispatch.h @@ -145,44 +145,6 @@ typedef struct { im_function **table; /* Array of function descriptors */ } im_package; -/* 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; - -/* 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 { - 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; - -/* A set of VIPS formats forming a format package. - */ -typedef struct { - char *name; /* Package name (eg "magick") */ - int nfuncs; /* Number of formats in package */ - im_format **table; /* Array of formats */ -} im_format_package; - /* Externs for dispatch. */ @@ -312,12 +274,6 @@ im_function *im_find_function( const char *name ); im_package *im_find_package( const char *name ); im_package *im_package_of_function( const char *name ); -/* Map over and find formats. - */ -void *im_map_formats( VSListMap2Fn fn, void *a, void *b ); -im_format *im_format_for_file( const char *filename ); -im_format *im_format_for_name( const char *filename ); - /* Allocate space for, and free im_object argument lists. */ int im_free_vargv( im_function *fn, im_object *vargv ); diff --git a/include/vips/format.h b/include/vips/format.h new file mode 100644 index 00000000..d0092c47 --- /dev/null +++ b/include/vips/format.h @@ -0,0 +1,87 @@ +/* Suppprted image formats. + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifndef IM_FORMAT_H +#define IM_FORMAT_H + +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus*/ + +/* 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; + +/* 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 { + 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; + +/* Register/unregister formats. + */ +im_format *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 *format, int priority ); +void im_format_unregister( im_format *format ); + +/* Map over and find formats. + */ +void *im_format_map( VSListMap2Fn fn, void *a, void *b ); +im_format *im_format_for_file( const char *filename ); +im_format *im_format_for_name( const char *filename ); + +#ifdef __cplusplus +} +#endif /*__cplusplus*/ + +#endif /*IM_FORMAT_H*/ diff --git a/include/vips/internal.h b/include/vips/internal.h index d2cc40a5..93bcccfd 100644 --- a/include/vips/internal.h +++ b/include/vips/internal.h @@ -63,6 +63,7 @@ void im__write_2byte( unsigned char **to, unsigned char *from ); int im__ftruncate( int fd, gint64 pos ); int im__seek( int fd, gint64 pos ); +int im__get_bytes( const char *filename, unsigned char buf[], int len ); int im__open_image_file( const char * ); void im__format_init( void ); @@ -78,6 +79,15 @@ int im__handle_eval( IMAGE *im, int w, int h ); int im__end_eval( IMAGE *im ); int im__time_destroy( IMAGE *im ); +void im__tiff_register( void ); +void im__jpeg_register( void ); +void im__png_register( void ); +void im__csv_register( void ); +void im__ppm_register( void ); +void im__analyze_register( void ); +void im__exr_register( void ); +void im__magick_register( void ); + extern int im__read_test; extern int im__mmap_limit; extern GMutex *im__global_lock; diff --git a/include/vips/proto.h b/include/vips/proto.h index 6c57d8d9..0bed801b 100644 --- a/include/vips/proto.h +++ b/include/vips/proto.h @@ -144,18 +144,7 @@ int im_ispoweroftwo( int ); int im_existsf( const char *name, ... ) __attribute__((format(printf, 1, 2))); -int im_istiff( const char * ); -int im_istifftiled( const char * ); -int im_istiffpyramid( const char * ); -int im_isjpeg( const char * ); int im_isvips( const char * ); -int im_isexr( const char * ); -int im_isexrtiled( const char *name ); -int im_isppm( const char * ); -int im_isppmmmap( const char *filename ); -int im_ispng( const char * ); -int im_ismagick( const char * ); -int im_isanalyze( const char *filename ); int im_add_close_callback( IMAGE *, im_callback_fn, void *, void * ); int im_add_preclose_callback( IMAGE *, im_callback_fn, void *, void * ); @@ -482,29 +471,21 @@ int im_system( IMAGE *im, const char *cmd, char **out ); int im_print( const char *message ); int im_thresh( IMAGE *, IMAGE *, double ); int im_jpeg2vips( const char *, IMAGE * ); -int im_jpeg2vips_header( const char *, IMAGE * ); int im_vips2jpeg( IMAGE *, const char * ); int im_vips2mimejpeg( IMAGE *, int ); int im_vips2bufjpeg( IMAGE *, IMAGE *, int, char **, int * ); int im_vips2tiff( IMAGE *, const char * ); int im_bernd( const char *, int, int, int, int ); int im_tiff2vips( const char *, IMAGE * ); -int im_tiff2vips_header( const char *, IMAGE * ); int im_tile_cache( IMAGE *, IMAGE *, int, int, int ); int im_magick2vips( const char *, IMAGE * ); -int im_magick2vips_header( const char *, IMAGE * ); int im_png2vips( const char *, IMAGE * ); -int im_png2vips_header( const char *, IMAGE * ); int im_exr2vips( const char *, IMAGE * ); -int im_exr2vips_header( const char *, IMAGE * ); int im_ppm2vips( const char *, IMAGE * ); -int im_ppm2vips_header( const char *, IMAGE * ); int im_vips2ppm( IMAGE *, const char * ); int im_analyze2vips( const char *filename, IMAGE *out ); -int im_analyze2vips_header( const char *filename, IMAGE *out ); int im_vips2csv( IMAGE *in, const char *filename ); int im_csv2vips( const char *filename, IMAGE *out ); -int im_csv2vips_header( const char *filename, IMAGE *out ); int im_vips2png( IMAGE *, const char * ); int im_raw2vips( const char *filename, IMAGE *out, int width, int height, int bpp, int offset ); diff --git a/include/vips/vips.h b/include/vips/vips.h index 505f93a8..2c962dbc 100644 --- a/include/vips/vips.h +++ b/include/vips/vips.h @@ -493,6 +493,7 @@ typedef struct { #include #include /* #include */ +#include #include #include #include diff --git a/libsrc/format/Makefile.am b/libsrc/format/Makefile.am index a80a6d17..0fdf0471 100644 --- a/libsrc/format/Makefile.am +++ b/libsrc/format/Makefile.am @@ -2,8 +2,8 @@ noinst_LTLIBRARIES = libformat.la libformat_la_SOURCES = \ dbh.h \ + format.c \ format_dispatch.c \ - is_a.c \ im_analyze2vips.c \ im_csv2vips.c \ im_exr2vips.c \ diff --git a/libsrc/format/format.c b/libsrc/format/format.c new file mode 100644 index 00000000..d6ac6171 --- /dev/null +++ b/libsrc/format/format.c @@ -0,0 +1,205 @@ +/* VIPS function dispatch tables for image format load/save. + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include + +#include +#include + +#ifdef WITH_DMALLOC +#include +#endif /*WITH_DMALLOC*/ + +/* List of loaded formats. + */ +static GSList *format_list = NULL; + +static gint +format_compare( im_format *a, im_format *b ) +{ + return( b->priority - a->priority ); +} + +/* Sort the format list after a change. + */ +static void +format_sort( void ) +{ + format_list = g_slist_sort( format_list, + (GCompareFunc) format_compare ); +} + +/* Register/unregister formats. + */ +im_format *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 *format; + + if( !(format = IM_NEW( NULL, im_format )) ) + 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 *format, int priority ) +{ + g_assert( format ); + + format->priority = priority; + format_sort(); +} + +void im_format_unregister( im_format *format ) +{ + format_list = g_slist_remove( format_list, format ); +} + +/* Called on startup: register the base vips formats. + */ +void +im__format_init( void ) +{ + im__jpeg_register(); + im__png_register(); + im__csv_register(); + im__ppm_register(); + im__analyze_register(); + im__exr_register(); + im__magick_register(); + im__tiff_register(); +} + +/* 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 *format, + const char *filename, const char *name ) +{ + if( format->is_a ) { + if( format->is_a( name ) ) + return( format ); + } + else if( im_filename_suffix_match( name, format->suffs ) ) + return( format ); + + return( NULL ); +} + +im_format * +im_format_for_file( const char *filename ) +{ + char name[FILENAME_MAX]; + char options[FILENAME_MAX]; + im_format *format; + + /* Break any options off the name ... eg. "fred.tif:jpeg,tile" + * etc. + */ + im_filename_split( filename, name, options ); + + if( !im_existsf( "%s", name ) ) { + im_error( "im_format_for_file", + _( "\"%s\" is not readable" ), name ); + return( NULL ); + } + + format = (im_format *) im_format_map( + (VSListMap2Fn) format_for_file_sub, + (void *) filename, (void *) name ); + + if( !format ) { + im_error( "im_format_for_file", + _( "\"%s\" is not in a supported format" ), name ); + return( NULL ); + } + + return( format ); +} + +/* Can we write this filename with this format? Ignore formats without a save + * method. + */ +static void * +format_for_name_sub( im_format *format, + const char *filename, const char *name ) +{ + if( format->save && + im_filename_suffix_match( name, format->suffs ) ) + return( format ); + + return( NULL ); +} + +im_format * +im_format_for_name( const char *filename ) +{ + char name[FILENAME_MAX]; + char options[FILENAME_MAX]; + + /* Break any options off the name ... eg. "fred.tif:jpeg,tile" + * etc. + */ + im_filename_split( filename, name, options ); + + return( (im_format *) im_format_map( + (VSListMap2Fn) format_for_name_sub, + (void *) filename, (void *) name ) ); +} + diff --git a/libsrc/format/format_dispatch.c b/libsrc/format/format_dispatch.c index c19207c0..e5778f7a 100644 --- a/libsrc/format/format_dispatch.c +++ b/libsrc/format/format_dispatch.c @@ -415,193 +415,3 @@ im_package im__format = { IM_NUMBER( list ), list }; - -/* TIFF flags function. - */ -static im_format_flags -tiff_flags( const char *filename ) -{ - im_format_flags flags; - - flags = 0; - if( im_istifftiled( filename ) ) - flags |= IM_FORMAT_FLAG_PARTIAL; - - return( flags ); -} - -/* OpenEXR flags function. - */ -static im_format_flags -exr_flags( const char *filename ) -{ - im_format_flags flags; - - flags = 0; - if( im_isexrtiled( filename ) ) - flags |= IM_FORMAT_FLAG_PARTIAL; - - return( flags ); -} - -/* ppm flags function. - */ -static im_format_flags -ppm_flags( const char *filename ) -{ - im_format_flags flags; - - flags = 0; - if( im_isppmmmap( filename ) ) - flags |= IM_FORMAT_FLAG_PARTIAL; - - return( flags ); -} - -/* Analyze flags function. - */ -static im_format_flags -analyze_flags( const char *filename ) -{ - return( IM_FORMAT_FLAG_PARTIAL ); -} - -/* Suffix sets. - */ -static const char *tiff_suffs[] = { ".tif", ".tiff", NULL }; -static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL }; -static const char *png_suffs[] = { ".png", NULL }; -static const char *csv_suffs[] = { ".csv", NULL }; -static const char *ppm_suffs[] = { ".ppm", ".pgm", ".pbm", NULL }; -static const char *exr_suffs[] = { ".exr", NULL }; -static const char *analyze_suffs[] = { ".img", ".hdr", NULL }; -static const char *magick_suffs[] = { NULL }; - -/* VIPS image formats. - */ -static im_format jpeg_desc = { - "jpeg", /* internal name */ - N_( "JPEG" ), /* i18n'd visible name */ - 0, /* Priority */ - jpeg_suffs, /* Allowed suffixes */ - im_isjpeg, /* is_a */ - im_jpeg2vips_header, /* Load header only */ - im_jpeg2vips, /* Load */ - im_vips2jpeg, /* Save */ - NULL /* Flags */ -}; - -static im_format tiff_desc = { - "tiff", /* internal name */ - N_( "TIFF" ), /* i18n'd visible name */ - 0, /* Priority */ - tiff_suffs, /* Allowed suffixes */ - im_istiff, /* is_a */ - im_tiff2vips_header, /* Load header only */ - im_tiff2vips, /* Load */ - im_vips2tiff, /* Save */ - tiff_flags /* Flags */ -}; - -static im_format png_desc = { - "png", /* internal name */ - N_( "PNG" ), /* i18n'd visible name */ - 0, /* Priority */ - png_suffs, /* Allowed suffixes */ - im_ispng, /* is_a */ - im_png2vips_header, /* Load header only */ - im_png2vips, /* Load */ - im_vips2png, /* Save */ - NULL /* Flags */ -}; - -static im_format csv_desc = { - "csv", /* internal name */ - N_( "CSV" ), /* i18n'd visible name */ - 0, /* Priority */ - csv_suffs, /* Allowed suffixes */ - NULL, /* is_a */ - im_csv2vips_header, /* Load header only */ - im_csv2vips, /* Load */ - im_vips2csv, /* Save */ - NULL /* Flags */ -}; - -static im_format ppm_desc = { - "ppm", /* internal name */ - N_( "PPM/PBM/PNM" ), /* i18n'd visible name */ - 0, /* Priority */ - ppm_suffs, /* Allowed suffixes */ - im_isppm, /* is_a */ - im_ppm2vips_header, /* Load header only */ - im_ppm2vips, /* Load */ - im_vips2ppm, /* Save */ - ppm_flags /* Flags */ -}; - -static im_format analyze_desc = { - "analyze", /* internal name */ - N_( "Analyze 6.0" ), /* i18n'd visible name */ - 0, /* Priority */ - analyze_suffs, /* Allowed suffixes */ - im_isanalyze, /* is_a */ - im_analyze2vips_header, /* Load header only */ - im_analyze2vips, /* Load */ - NULL, /* Save */ - analyze_flags /* Flags */ -}; - -static im_format exr_desc = { - "exr", /* internal name */ - N_( "OpenEXR" ), /* i18n'd visible name */ - 0, /* Priority */ - exr_suffs, /* Allowed suffixes */ - im_isexr, /* is_a */ - im_exr2vips_header, /* Load header only */ - im_exr2vips, /* Load */ - NULL, /* Save */ - exr_flags /* Flags */ -}; - -static im_format magick_desc = { - "magick", /* internal name */ - N_( "libMagick-supported" ), /* i18n'd visible name */ - -1000, /* Priority */ - magick_suffs, /* Allowed suffixes */ - im_ismagick, /* is_a */ - im_magick2vips_header, /* Load header only */ - im_magick2vips, /* Load */ - NULL, /* Save */ - NULL /* Flags */ -}; - -/* Package up all these formats. - */ -static im_format *format_list[] = { -#ifdef HAVE_JPEG - &jpeg_desc, -#endif /*HAVE_JPEG*/ -#ifdef HAVE_TIFF - &tiff_desc, -#endif /*HAVE_TIFF*/ -#ifdef HAVE_PNG - &png_desc, -#endif /*HAVE_PNG*/ -#ifdef HAVE_OPENEXR - &exr_desc, -#endif /*HAVE_OPENEXR*/ - &ppm_desc, - &analyze_desc, - &csv_desc, -#ifdef HAVE_MAGICK - &magick_desc -#endif /*HAVE_MAGICK*/ -}; - -/* Package of format. - */ -im_format_package im__format_format = { - "format", - IM_NUMBER( format_list ), - format_list -}; diff --git a/libsrc/format/im_analyze2vips.c b/libsrc/format/im_analyze2vips.c index d5f9eeb2..ca9a825f 100644 --- a/libsrc/format/im_analyze2vips.c +++ b/libsrc/format/im_analyze2vips.c @@ -484,8 +484,8 @@ attach_meta( IMAGE *out, struct dsr *d ) } } -int -im_isanalyze( const char *filename ) +static int +isanalyze( const char *filename ) { char header[FILENAME_MAX]; char image[FILENAME_MAX]; @@ -511,8 +511,8 @@ im_isanalyze( const char *filename ) return( 1 ); } -int -im_analyze2vips_header( const char *filename, IMAGE *out ) +static int +analyze2vips_header( const char *filename, IMAGE *out ) { char header[FILENAME_MAX]; char image[FILENAME_MAX]; @@ -581,3 +581,25 @@ im_analyze2vips( const char *filename, IMAGE *out ) return( 0 ); } +static const char *analyze_suffs[] = { ".img", ".hdr", NULL }; + +static im_format_flags +analyze_flags( const char *filename ) +{ + return( IM_FORMAT_FLAG_PARTIAL ); +} + +void +im__analyze_register( void ) +{ + im_format_register( + "analyze", /* internal name */ + N_( "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 */ + ); +} diff --git a/libsrc/format/im_csv2vips.c b/libsrc/format/im_csv2vips.c index 8f07076e..437e0434 100644 --- a/libsrc/format/im_csv2vips.c +++ b/libsrc/format/im_csv2vips.c @@ -298,8 +298,8 @@ im_csv2vips( const char *filename, IMAGE *out ) /* We can't just read the header of a CSV. Instead, we read to a temp image, * then copy just the header to the output. */ -int -im_csv2vips_header( const char *filename, IMAGE *out ) +static int +csv2vips_header( const char *filename, IMAGE *out ) { IMAGE *t; @@ -314,3 +314,20 @@ im_csv2vips_header( const char *filename, IMAGE *out ) return( 0 ); } + +static const char *csv_suffs[] = { ".csv", NULL }; + +void +im__csv_register( void ) +{ + im_format_register( + "csv", /* internal name */ + N_( "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 */ + ); +} diff --git a/libsrc/format/im_exr2vips.c b/libsrc/format/im_exr2vips.c index f5188c60..41b929e4 100644 --- a/libsrc/format/im_exr2vips.c +++ b/libsrc/format/im_exr2vips.c @@ -69,19 +69,7 @@ im_exr2vips( const char *name, IMAGE *out ) return( -1 ); } -int -im_exr2vips_header( const char *name, IMAGE *out ) -{ - im_error( "im_exr2vips_header", _( "OpenEXR support disabled" ) ); - return( -1 ); -} - -int -im_isexrtiled( const char *name ) -{ - im_error( "im_isexrtiled", _( "OpenEXR support disabled" ) ); - return( -1 ); -} +int im__exr_register( void ); #else /*HAVE_OPENEXR*/ @@ -92,6 +80,7 @@ im_isexrtiled( const char *name ) #include #include +#include #include @@ -199,7 +188,7 @@ read_new( const char *name, IMAGE *out ) /* Read a OpenEXR file (header) into a VIPS (header). */ static int -exr2vips_header( Read *read, IMAGE *out ) +read_header( Read *read, IMAGE *out ) { /* @@ -218,13 +207,13 @@ exr2vips_header( Read *read, IMAGE *out ) /* Read a OpenEXR file header into a VIPS header. */ -int -im_exr2vips_header( const char *name, IMAGE *out ) +static int +exr2vips_header( const char *name, IMAGE *out ) { Read *read; if( !(read = read_new( name, out )) || - exr2vips_header( read, out ) ) + read_header( read, out ) ) return( -1 ); return( 0 ); @@ -232,8 +221,8 @@ im_exr2vips_header( const char *name, IMAGE *out ) /* Test for tiled EXR. */ -int -im_isexrtiled( const char *name ) +static int +isexrtiled( const char *name ) { Read *read; int tiled; @@ -350,7 +339,7 @@ seq_start( IMAGE *out, void *a, void *b ) static int exr2vips_tiles( Read *read, IMAGE *out ) { - if( exr2vips_header( read, out ) || + if( read_header( read, out ) || im_poutcheck( out ) || im_demand_hint( out, IM_SMALLTILE, NULL ) || im_generate( out, seq_start, fill_region, NULL, read, NULL ) ) @@ -375,7 +364,7 @@ exr2vips_lines( Read *read, IMAGE *out ) if( !(imf_buffer = IM_ARRAY( out, width, ImfRgba )) || !(vips_buffer = IM_ARRAY( out, 4 * width, float )) || - exr2vips_header( read, out ) || + read_header( read, out ) || im_outcheck( out ) || im_setupout( out ) ) return( -1 ); @@ -447,4 +436,46 @@ im_exr2vips( const char *name, IMAGE *out ) return( 0 ); } +static int +isexr( const char *filename ) +{ + unsigned char buf[4]; + + if( im__get_bytes( filename, buf, 4 ) ) + if( buf[0] == 0x76 && buf[1] == 0x2f && + buf[2] == 0x31 && buf[3] == 0x01 ) + return( 1 ); + + return( 0 ); +} + +static const char *exr_suffs[] = { ".exr", NULL }; + +static im_format_flags +exr_flags( const char *filename ) +{ + im_format_flags flags; + + flags = 0; + if( isexrtiled( filename ) ) + flags |= IM_FORMAT_FLAG_PARTIAL; + + return( flags ); +} + +void +im__exr_register( void ) +{ + im_format_register( + "exr", /* internal name */ + N_( "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 */ + ); +} + #endif /*HAVE_OPENEXR*/ diff --git a/libsrc/format/im_jpeg2vips.c b/libsrc/format/im_jpeg2vips.c index a557df84..2079f887 100644 --- a/libsrc/format/im_jpeg2vips.c +++ b/libsrc/format/im_jpeg2vips.c @@ -64,14 +64,6 @@ #include -int -im_jpeg2vips_header( const char *name, IMAGE *out ) -{ - im_error( "im_jpeg2vips_header", _( "JPEG support disabled" ) ); - - return( -1 ); -} - int im_jpeg2vips( const char *name, IMAGE *out ) { @@ -80,6 +72,11 @@ im_jpeg2vips( const char *name, IMAGE *out ) return( -1 ); } +void +im__jpeg_register( void ) +{ +} + #else /*HAVE_JPEG*/ #include @@ -104,6 +101,7 @@ im_jpeg2vips( const char *name, IMAGE *out ) #include #include +#include /* jpeglib includes jconfig.h, which can define HAVE_STDLIB_H ... which we * also define. Make sure it's turned off. @@ -705,10 +703,39 @@ im_jpeg2vips( const char *name, IMAGE *out ) return( jpeg2vips( name, out, FALSE ) ); } -int -im_jpeg2vips_header( const char *name, IMAGE *out ) +static int +isjpeg( const char *filename ) +{ + unsigned char buf[2]; + + if( im__get_bytes( filename, buf, 2 ) ) + if( (int) buf[0] == 0xff && (int) buf[1] == 0xd8 ) + return( 1 ); + + return( 0 ); +} + +static int +jpeg2vips_header( const char *name, IMAGE *out ) { return( jpeg2vips( name, out, TRUE ) ); } +static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL }; + +void +im__jpeg_register( void ) +{ + im_format_register( + "jpeg", /* internal name */ + N_( "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 */ + ); +} + #endif /*HAVE_JPEG*/ diff --git a/libsrc/format/im_magick2vips.c b/libsrc/format/im_magick2vips.c index feda6c01..1dac93fe 100644 --- a/libsrc/format/im_magick2vips.c +++ b/libsrc/format/im_magick2vips.c @@ -69,10 +69,8 @@ im_magick2vips( const char *filename, IMAGE *im ) } int -im_magick2vips_header( const char *filename, IMAGE *im ) +im__magick_register( void ) { - im_error( "im_magick2vips", _( "libMagick support disabled" ) ); - return( -1 ); } #else /*HAVE_MAGICK*/ @@ -619,8 +617,8 @@ im_magick2vips( const char *filename, IMAGE *im ) return( 0 ); } -int -im_magick2vips_header( const char *filename, IMAGE *im ) +static int +magick2vips_header( const char *filename, IMAGE *im ) { Read *read; @@ -647,4 +645,39 @@ im_magick2vips_header( const char *filename, IMAGE *im ) return( 0 ); } +static int +ismagick( const char *filename ) +{ + IMAGE *im; + int result; + + if( !(im = im_open( "dummy", "p" )) ) + return( -1 ); + result = magick2vips_header( filename, im ); + im_clear_error_string(); + im_close( im ); + + return( result == 0 ); +} + +static const char *magick_suffs[] = { NULL }; + +void +im__magick_register( void ) +{ + im_format *format; + + format = im_format_register( + "magick", /* internal name */ + N_( "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 ); +} + #endif /*HAVE_MAGICK*/ diff --git a/libsrc/format/im_png2vips.c b/libsrc/format/im_png2vips.c index a0d91ea8..fab52f23 100644 --- a/libsrc/format/im_png2vips.c +++ b/libsrc/format/im_png2vips.c @@ -60,11 +60,9 @@ im_png2vips( const char *name, IMAGE *out ) return( -1 ); } -int -im_png2vips_header( const char *name, IMAGE *out ) +void +im__png_register( void ) { - im_error( "im_png2vips_header", _( "PNG support disabled" ) ); - return( -1 ); } #else /*HAVE_PNG*/ @@ -74,6 +72,7 @@ im_png2vips_header( const char *name, IMAGE *out ) #include #include +#include #include @@ -336,8 +335,8 @@ png2vips( Read *read, int header_only ) /* Read a PNG file header into a VIPS header. */ -int -im_png2vips_header( const char *name, IMAGE *out ) +static int +png2vips_header( const char *name, IMAGE *out ) { Read *read; @@ -378,4 +377,30 @@ im_png2vips( const char *name, IMAGE *out ) return( 0 ); } +static int +ispng( const char *filename ) +{ + unsigned char buf[8]; + + return( im__get_bytes( filename, buf, 8 ) && + !png_sig_cmp( buf, 0, 8 ) ); +} + +static const char *png_suffs[] = { ".png", NULL }; + +void +im__png_register( void ) +{ + im_format_register( + "png", /* internal name */ + N_( "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 */ + ); +} + #endif /*HAVE_PNG*/ diff --git a/libsrc/format/im_ppm2vips.c b/libsrc/format/im_ppm2vips.c index e8490fc6..51c90483 100644 --- a/libsrc/format/im_ppm2vips.c +++ b/libsrc/format/im_ppm2vips.c @@ -59,6 +59,7 @@ #include #include +#include #ifdef WITH_DMALLOC #include @@ -387,8 +388,8 @@ parse_ppm( FILE *fp, const char *filename, IMAGE *out ) return( read_ascii( fp, out ) ); } -int -im_ppm2vips_header( const char *filename, IMAGE *out ) +static int +ppm2vips_header( const char *filename, IMAGE *out ) { FILE *fp; int bits; @@ -416,8 +417,8 @@ im_ppm2vips_header( const char *filename, IMAGE *out ) /* Can this PPM file be read with a mmap? */ -int -im_isppmmmap( const char *filename ) +static int +isppmmmap( const char *filename ) { IMAGE *im; FILE *fp; @@ -473,3 +474,46 @@ im_ppm2vips( const char *filename, IMAGE *out ) return( 0 ); } + +static int +isppm( const char *filename ) +{ + unsigned char buf[2]; + + if( im__get_bytes( filename, buf, 2 ) ) + if( buf[0] == 'P' && (buf[1] >= '1' || buf[1] <= '6') ) + return( 1 ); + + return( 0 ); +} + +/* ppm flags function. + */ +static im_format_flags +ppm_flags( const char *filename ) +{ + im_format_flags flags; + + flags = 0; + if( isppmmmap( filename ) ) + flags |= IM_FORMAT_FLAG_PARTIAL; + + return( flags ); +} + +static const char *ppm_suffs[] = { ".ppm", ".pgm", ".pbm", NULL }; + +void +im__ppm_register( void ) +{ + im_format_register( + "ppm", /* internal name */ + N_( "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 */ + ); +} diff --git a/libsrc/format/im_tiff2vips.c b/libsrc/format/im_tiff2vips.c index 6d5211e2..ce5a34da 100644 --- a/libsrc/format/im_tiff2vips.c +++ b/libsrc/format/im_tiff2vips.c @@ -101,6 +101,8 @@ * - set IM_META_RESOLUTION_UNIT * 17/4/08 * - allow CMYKA (thanks Doron) + * 15/8/08 + * - reorganise for image format system */ /* @@ -149,17 +151,9 @@ im_tiff2vips( const char *tiffile, IMAGE *im ) return( -1 ); } -int -im_istiffpyramid( const char *name ) +void +im__tiff_register( void ) { - return( 0 ); -} - -int -im_tiff2vips_header( const char *tiffile, IMAGE *im ) -{ - im_error( "im_tiff2vips", _( "TIFF support disabled" ) ); - return( -1 ); } #else /*HAVE_TIFF*/ @@ -170,6 +164,7 @@ im_tiff2vips_header( const char *tiffile, IMAGE *im ) #include #include +#include #include #include @@ -1422,8 +1417,12 @@ get_directory( const char *filename, int page ) return( tif ); } -int -im_istiffpyramid( const char *name ) +/* + + FIXME ... Unused for now, perhaps if we add another format flag. + +static int +istiffpyramid( const char *name ) { TIFF *tif; @@ -1431,14 +1430,14 @@ im_istiffpyramid( const char *name ) TIFFSetWarningHandler( (TIFFErrorHandler) im__thandler_warning ); if( (tif = get_directory( name, 2 )) ) { - /* We can see page 2 ... assume it is. - */ + // We can see page 2 ... assume it is. TIFFClose( tif ); return( 1 ); } return( 0 ); } + */ int im_tiff2vips( const char *filename, IMAGE *out ) @@ -1475,8 +1474,8 @@ im_tiff2vips( const char *filename, IMAGE *out ) /* Just parse the header. */ -int -im_tiff2vips_header( const char *filename, IMAGE *out ) +static int +tiff2vips_header( const char *filename, IMAGE *out ) { ReadTiff *rtiff; @@ -1499,4 +1498,75 @@ im_tiff2vips_header( const char *filename, IMAGE *out ) return( 0 ); } +static int +istiff( const char *filename ) +{ + unsigned char buf[2]; + + if( im__get_bytes( filename, buf, 2 ) ) + if( (buf[0] == 'M' && buf[1] == 'M') || + (buf[0] == 'I' && buf[1] == 'I') ) + return( 1 ); + + return( 0 ); +} + +static int +istifftiled( const char *filename ) +{ + TIFF *tif; + int tiled; + + /* Override the default TIFF error handler. + */ + TIFFSetErrorHandler( (TIFFErrorHandler) im__thandler_error ); + TIFFSetWarningHandler( (TIFFErrorHandler) im__thandler_warning ); + +#ifdef BINARY_OPEN + if( !(tif = TIFFOpen( filename, "rb" )) ) { +#else /*BINARY_OPEN*/ + if( !(tif = TIFFOpen( filename, "r" )) ) { +#endif /*BINARY_OPEN*/ + /* Not a TIFF file ... return False. + */ + im_clear_error_string(); + return( 0 ); + } + tiled = TIFFIsTiled( tif ); + TIFFClose( tif ); + + return( tiled ); +} + +/* TIFF flags function. + */ +static im_format_flags +tiff_flags( const char *filename ) +{ + im_format_flags flags; + + flags = 0; + if( istifftiled( filename ) ) + flags |= IM_FORMAT_FLAG_PARTIAL; + + return( flags ); +} + +static const char *tiff_suffs[] = { ".tif", ".tiff", NULL }; + +void +im__tiff_register( void ) +{ + im_format_register( + "tiff", /* internal name */ + N_( "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 */ + ); +} + #endif /*HAVE_TIFF*/ diff --git a/libsrc/format/is_a.c b/libsrc/format/is_a.c deleted file mode 100644 index 69934b8a..00000000 --- a/libsrc/format/is_a.c +++ /dev/null @@ -1,271 +0,0 @@ -/* Test various predicates. - * - * J.Cupitt, 8/4/93. - * 13/10/95 JC - * - ANSIfied - * - im_ispoweroftwo() added - * 14/11/96 Jc - * - im_isjpeg() added - * 25/3/97 JC - * - im_isvips() added - * 14/4/97 JC - * - im_istifftiled() added - * 29/10/98 JC - * - im_isMSBfirst() and im_amiMSBfirst() added - * 16/6/99 JC - * - added im_existsf() - * 22/11/00 JC - * - added im_isppm() - * 23/4/01 JC - * - HAVE_TIFF turns on TIFFness - * 19/10/02 HB - * - PNG added - * 1/5/06 - * - added exr - * 3/8/07 - * - cleanups - * 22/5/08 - * - now just formats - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#ifdef HAVE_UNISTD_H -#include -#endif /*HAVE_UNISTD_H*/ -#include -#include -#include - -#include - -#ifdef HAVE_TIFF -#include -#endif /*HAVE_TIFF*/ - -#ifdef HAVE_PNG -#include -#endif /*HAVE_PNG*/ - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Read a few bytes from the start of a file. For sniffing file types. - */ -static int -get_bytes( const char *filename, unsigned char buf[], int len ) -{ - int fd; - - /* File may not even exist (for tmp images for example!) - * so no hasty messages. And the file might be truncated, so no error - * on read either. - */ -#ifdef BINARY_OPEN - if( (fd = open( filename, O_RDONLY | O_BINARY )) == -1 ) -#else /*BINARY_OPEN*/ - if( (fd = open( filename, O_RDONLY )) == -1 ) -#endif /*BINARY_OPEN*/ - return( 0 ); - if( read( fd, buf, len ) != len ) { - close( fd ); - return( 0 ); - } - close( fd ); - - return( 1 ); -} - -int -im_istiff( const char *filename ) -{ - unsigned char buf[2]; - - if( get_bytes( filename, buf, 2 ) ) - if( (buf[0] == 'M' && buf[1] == 'M') || - (buf[0] == 'I' && buf[1] == 'I') ) - return( 1 ); - - return( 0 ); -} - -#ifdef HAVE_PNG -int -im_ispng( const char *filename ) -{ - unsigned char buf[8]; - - return( get_bytes( filename, buf, 8 ) && - !png_sig_cmp( buf, 0, 8 ) ); -} -#else /*HAVE_PNG*/ -int -im_ispng( const char *filename ) -{ - return( 0 ); -} -#endif /*HAVE_PNG*/ - -#ifdef HAVE_MAGICK -int -im_ismagick( const char *filename ) -{ - IMAGE *im; - int result; - - if( !(im = im_open( "dummy", "p" )) ) - return( -1 ); - result = im_magick2vips_header( filename, im ); - im_clear_error_string(); - im_close( im ); - - return( result == 0 ); -} -#else /*HAVE_MAGICK*/ -int -im_ismagick( const char *filename ) -{ - return( 0 ); -} -#endif /*HAVE_MAGICK*/ - -int -im_isppm( const char *filename ) -{ - unsigned char buf[2]; - - if( get_bytes( filename, buf, 2 ) ) - if( buf[0] == 'P' && (buf[1] >= '1' || buf[1] <= '6') ) - return( 1 ); - - return( 0 ); -} - -#ifdef HAVE_TIFF - -/* Handle TIFF errors here. - */ -static void -vhandle( char *module, char *fmt, ... ) -{ - va_list ap; - - im_error( "im_istifftiled", _( "TIFF error in \"%s\": " ), module ); - - va_start( ap, fmt ); - im_verrormsg( fmt, ap ); - va_end( ap ); -} - -int -im_istifftiled( const char *filename ) -{ - TIFF *tif; - int tiled; - - /* Override the default TIFF error handler. - */ - TIFFSetErrorHandler( (TIFFErrorHandler) vhandle ); - -#ifdef BINARY_OPEN - if( !(tif = TIFFOpen( filename, "rb" )) ) { -#else /*BINARY_OPEN*/ - if( !(tif = TIFFOpen( filename, "r" )) ) { -#endif /*BINARY_OPEN*/ - /* Not a TIFF file ... return False. - */ - im_clear_error_string(); - return( 0 ); - } - tiled = TIFFIsTiled( tif ); - TIFFClose( tif ); - - return( tiled ); -} - -#else /*HAVE_TIFF*/ - -int -im_istifftiled( const char *filename ) -{ - return( 0 ); -} - -#endif /*HAVE_TIFF*/ - -int -im_isjpeg( const char *filename ) -{ - unsigned char buf[2]; - - if( get_bytes( filename, buf, 2 ) ) - if( (int) buf[0] == 0xff && (int) buf[1] == 0xd8 ) - return( 1 ); - - return( 0 ); -} - -int -im_isvips( const char *filename ) -{ - unsigned char buf[4]; - - if( get_bytes( filename, buf, 4 ) ) { - if( buf[0] == 0x08 && buf[1] == 0xf2 && - buf[2] == 0xa6 && buf[3] == 0xb6 ) - /* SPARC-order VIPS image. - */ - return( 1 ); - else if( buf[3] == 0x08 && buf[2] == 0xf2 && - buf[1] == 0xa6 && buf[0] == 0xb6 ) - /* INTEL-order VIPS image. - */ - return( 1 ); - } - - return( 0 ); -} - -int -im_isexr( const char *filename ) -{ - unsigned char buf[4]; - - if( get_bytes( filename, buf, 4 ) ) - if( buf[0] == 0x76 && buf[1] == 0x2f && - buf[2] == 0x31 && buf[3] == 0x01 ) - return( 1 ); - - return( 0 ); -} - diff --git a/libsrc/iofuncs/package.c b/libsrc/iofuncs/package.c index 8c5b1dbc..518f8388 100644 --- a/libsrc/iofuncs/package.c +++ b/libsrc/iofuncs/package.c @@ -74,8 +74,6 @@ extern im_package im__other; extern im_package im__relational; extern im_package im__video; -extern im_format_package im__format_format; - /* im_guess_prefix() args. */ static im_arg_desc guess_prefix_args[] = { @@ -459,67 +457,12 @@ static im_package *built_in[] = { &im__relational, &im__video }; - -/* List of loaded formats. - */ -static GSList *format_list = NULL; - -static gint -format_compare( im_format *a, im_format *b ) -{ - return( b->priority - a->priority ); -} - -/* Sort the format list after a change. - */ -static void -format_sort( void ) -{ - format_list = g_slist_sort( format_list, - (GCompareFunc) format_compare ); -} - -/* Remove a package of formats. - */ -static void -format_remove( im_format_package *format ) -{ - int i; - - for( i = 0; i < format->nfuncs; i++ ) - format_list = g_slist_remove( format_list, format->table[i] ); - format_sort(); -} - -/* Add a package of formats. - */ -static void -format_add( im_format_package *format ) -{ - int i; - - for( i = 0; i < format->nfuncs; i++ ) - /* Append so we keep the ordering where possible. - */ - format_list = g_slist_append( format_list, format->table[i] ); - format_sort(); -} - -/* Called on startup: add the base vips formats. - */ -void -im__format_init( void ) -{ - format_add( &im__format_format ); -} - /* How we represent a loaded plugin. */ typedef struct _Plugin { GModule *module; /* As loaded by g_module_open() */ char *name; /* Name we loaded */ im_package *pack; /* Package table */ - im_format_package *format; /* Package format table */ } Plugin; /* List of loaded plugins. @@ -533,8 +476,6 @@ plugin_free( Plugin *plug ) { char *name = plug->name ? plug->name : ""; - if( plug->format ) - format_remove( plug->format ); if( plug->module ) { if( !g_module_close( plug->module ) ) { im_error( "plugin", @@ -574,7 +515,6 @@ im_load_plugin( const char *name ) plug->module = NULL; plug->name = NULL; plug->pack = NULL; - plug->format = NULL; plugin_list = g_slist_prepend( plugin_list, plug ); /* Attach name. @@ -609,12 +549,6 @@ im_load_plugin( const char *name ) return( NULL ); } - /* The format table is optional. - */ - if( !g_module_symbol( plug->module, - "format_table", (gpointer *) ((void *) &plug->format) ) ) - plug->format = NULL; - /* Sanity check. */ if( !plug->pack->name || plug->pack->nfuncs < 0 || @@ -625,28 +559,11 @@ im_load_plugin( const char *name ) return( NULL ); } - if( plug->format ) { - if( !plug->format->name || plug->format->nfuncs < 0 || - plug->format->nfuncs > 10000 ) { - - im_error( "plugin", - _( "corrupted format table in plugin \"%s\"" ), - name ); - plugin_free( plug ); - - return( NULL ); - } - } #ifdef DEBUG printf( "added package \"%s\" ...\n", plug->pack->name ); #endif /*DEBUG*/ - /* Add any formats to our format list and sort again. - */ - if( plug->format ) - format_add( plug->format ); - return( plug->pack ); } @@ -819,91 +736,6 @@ im_package_of_function( const char *name ) return( pack ); } -/* Map a function over all formats. - */ -void * -im_map_formats( 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 *format, - const char *filename, const char *name ) -{ - if( format->is_a ) { - if( format->is_a( name ) ) - return( format ); - } - else if( im_filename_suffix_match( name, format->suffs ) ) - return( format ); - - return( NULL ); -} - -im_format * -im_format_for_file( const char *filename ) -{ - char name[FILENAME_MAX]; - char options[FILENAME_MAX]; - im_format *format; - - /* Break any options off the name ... eg. "fred.tif:jpeg,tile" - * etc. - */ - im_filename_split( filename, name, options ); - - if( !im_existsf( "%s", name ) ) { - im_error( "im_format_for_file", - _( "\"%s\" is not readable" ), name ); - return( NULL ); - } - - format = (im_format *) im_map_formats( - (VSListMap2Fn) format_for_file_sub, - (void *) filename, (void *) name ); - - if( !format ) { - im_error( "im_format_for_file", - _( "\"%s\" is not in a supported format" ), name ); - return( NULL ); - } - - return( format ); -} - -/* Can we write this filename with this format? Ignore formats without a save - * method. - */ -static void * -format_for_name_sub( im_format *format, - const char *filename, const char *name ) -{ - if( format->save && - im_filename_suffix_match( name, format->suffs ) ) - return( format ); - - return( NULL ); -} - -im_format * -im_format_for_name( const char *filename ) -{ - char name[FILENAME_MAX]; - char options[FILENAME_MAX]; - - /* Break any options off the name ... eg. "fred.tif:jpeg,tile" - * etc. - */ - im_filename_split( filename, name, options ); - - return( (im_format *) im_map_formats( - (VSListMap2Fn) format_for_name_sub, - (void *) filename, (void *) name ) ); -} - /* Free any store we allocated for the argument list. */ int diff --git a/libsrc/iofuncs/predicate.c b/libsrc/iofuncs/predicate.c index 287b9631..65b3d228 100644 --- a/libsrc/iofuncs/predicate.c +++ b/libsrc/iofuncs/predicate.c @@ -75,6 +75,7 @@ #include #include +#include #ifdef WITH_DMALLOC #include @@ -331,3 +332,24 @@ im_ispoweroftwo( int p ) else return( 0 ); } + +int +im_isvips( const char *filename ) +{ + unsigned char buf[4]; + + if( im__get_bytes( filename, buf, 4 ) ) { + if( buf[0] == 0x08 && buf[1] == 0xf2 && + buf[2] == 0xa6 && buf[3] == 0xb6 ) + /* SPARC-order VIPS image. + */ + return( 1 ); + else if( buf[3] == 0x08 && buf[2] == 0xf2 && + buf[1] == 0xa6 && buf[0] == 0xb6 ) + /* INTEL-order VIPS image. + */ + return( 1 ); + } + + return( 0 ); +} diff --git a/libsrc/iofuncs/util.c b/libsrc/iofuncs/util.c index df5ca395..cd5f5a8b 100644 --- a/libsrc/iofuncs/util.c +++ b/libsrc/iofuncs/util.c @@ -47,6 +47,7 @@ #ifdef HAVE_UNISTD_H #include #endif /*HAVE_UNISTD_H*/ +#include #ifdef OS_WIN32 #include @@ -1012,4 +1013,28 @@ im_isnative( im_arch_type arch ) abort(); } +/* Read a few bytes from the start of a file. For sniffing file types. + */ +int +im__get_bytes( const char *filename, unsigned char buf[], int len ) +{ + int fd; + /* File may not even exist (for tmp images for example!) + * so no hasty messages. And the file might be truncated, so no error + * on read either. + */ +#ifdef BINARY_OPEN + if( (fd = open( filename, O_RDONLY | O_BINARY )) == -1 ) +#else /*BINARY_OPEN*/ + if( (fd = open( filename, O_RDONLY )) == -1 ) +#endif /*BINARY_OPEN*/ + return( 0 ); + if( read( fd, buf, len ) != len ) { + close( fd ); + return( 0 ); + } + close( fd ); + + return( 1 ); +}