clean up loadable formats

This commit is contained in:
John Cupitt 2008-08-15 21:45:18 +00:00
parent 0fb1fae5c7
commit 5ca62be716
23 changed files with 706 additions and 763 deletions

View File

@ -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

18
TODO
View File

@ -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

View File

@ -7,6 +7,7 @@ pkginclude_HEADERS = \
colour.h \
debug.h \
dispatch.h \
format.h \
fmask.h \
mosaic.h \
proto.h \

View File

@ -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 );

87
include/vips/format.h Normal file
View File

@ -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*/

View File

@ -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;

View File

@ -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 );

View File

@ -493,6 +493,7 @@ typedef struct {
#include <vips/proto.h>
#include <vips/colour.h>
/* #include <vips/vector.h> */
#include <vips/format.h>
#include <vips/dispatch.h>
#include <vips/region.h>
#include <vips/semaphore.h>

View File

@ -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 \

205
libsrc/format/format.c Normal file
View File

@ -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 <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <vips/vips.h>
#include <vips/internal.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#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 ) );
}

View File

@ -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
};

View File

@ -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 */
);
}

View File

@ -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 */
);
}

View File

@ -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 <vips/vips.h>
#include <vips/thread.h>
#include <vips/internal.h>
#include <ImfCRgbaFile.h>
@ -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*/

View File

@ -64,14 +64,6 @@
#include <vips/vips.h>
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 <stdio.h>
@ -104,6 +101,7 @@ im_jpeg2vips( const char *name, IMAGE *out )
#include <vips/vips.h>
#include <vips/vbuf.h>
#include <vips/internal.h>
/* 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*/

View File

@ -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*/

View File

@ -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 <stdlib.h>
#include <vips/vips.h>
#include <vips/internal.h>
#include <png.h>
@ -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*/

View File

@ -59,6 +59,7 @@
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/internal.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
@ -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 */
);
}

View File

@ -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 <assert.h>
#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/thread.h>
#include <tiffio.h>
@ -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*/

View File

@ -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 <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /*HAVE_UNISTD_H*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vips/vips.h>
#ifdef HAVE_TIFF
#include <tiffio.h>
#endif /*HAVE_TIFF*/
#ifdef HAVE_PNG
#include <png.h>
#endif /*HAVE_PNG*/
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#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 );
}

View File

@ -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 : "<unknown>";
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

View File

@ -75,6 +75,7 @@
#include <limits.h>
#include <vips/vips.h>
#include <vips/internal.h>
#ifdef WITH_DMALLOC
#include <dmalloc.h>
@ -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 );
}

View File

@ -47,6 +47,7 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /*HAVE_UNISTD_H*/
#include <fcntl.h>
#ifdef OS_WIN32
#include <windows.h>
@ -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 );
}