From f9adf20874910c4b7a421fc670d036d9052be96e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 12 Oct 2009 15:27:18 +0000 Subject: [PATCH] gtkdoc comments for check --- ChangeLog | 2 +- TODO | 12 +- doc/reference/libvips-docs.sgml.in | 3 +- libvips/deprecated/rename.c | 34 + libvips/include/vips/Makefile.am | 1 + libvips/include/vips/check.h | 75 ++ libvips/include/vips/deprecated.h | 8 + libvips/include/vips/generate.h | 8 + libvips/include/vips/proto.h | 46 -- libvips/include/vips/util.h | 6 + libvips/include/vips/vips.h | 1 + libvips/iofuncs/Makefile.am | 5 +- libvips/iofuncs/check.c | 1075 ++++++++++++++++++++++++++++ libvips/iofuncs/header.c | 3 +- libvips/iofuncs/im_iocheck.c | 321 --------- libvips/iofuncs/im_makerw.c | 86 --- libvips/iofuncs/im_piocheck.c | 200 ------ libvips/iofuncs/im_render.c | 86 ++- libvips/iofuncs/predicate.c | 504 ------------- libvips/iofuncs/type.c | 352 --------- libvips/iofuncs/util.c | 86 +++ 21 files changed, 1378 insertions(+), 1536 deletions(-) create mode 100644 libvips/include/vips/check.h create mode 100644 libvips/iofuncs/check.c delete mode 100644 libvips/iofuncs/im_iocheck.c delete mode 100644 libvips/iofuncs/im_makerw.c delete mode 100644 libvips/iofuncs/im_piocheck.c delete mode 100644 libvips/iofuncs/predicate.c delete mode 100644 libvips/iofuncs/type.c diff --git a/ChangeLog b/ChangeLog index 73435bde..8fbc55aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -51,7 +51,7 @@ - added im_flood_other() as start of simple segmentation operator - added im_segment() - im_printlines(), im_debugim() deprecated (use im_vips2csv() instead) -- meta, header, callback, error, region gtkdocs +- meta, header, callback, error, region, check, generate gtkdocs - removed printlines tool, vips2csv is much better - removed other useless tools as well: debugim, binfile - fix up addr calcs on 64-bit machines with >2gb images and inplace ops diff --git a/TODO b/TODO index d53cc726..b9f6b7e4 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,11 @@ +- memory.c + +- more stuff from util.c? too much to do it all now + + + + + - load 500 jpegs, shrink, save VM use is huge, ouch, could we use a bit less? @@ -12,11 +20,7 @@ - VipsFormat next? where should we document the im_vip2jpeg() options? -- more stuff from util.c? too much to do it all now -- im_render()? - -- memory.c - constant images: diff --git a/doc/reference/libvips-docs.sgml.in b/doc/reference/libvips-docs.sgml.in index 528e72fc..6c788d8a 100644 --- a/doc/reference/libvips-docs.sgml.in +++ b/doc/reference/libvips-docs.sgml.in @@ -19,11 +19,12 @@ Core VIPS API + - + diff --git a/libvips/deprecated/rename.c b/libvips/deprecated/rename.c index df94a5b2..1d27e833 100644 --- a/libvips/deprecated/rename.c +++ b/libvips/deprecated/rename.c @@ -184,3 +184,37 @@ im_extract( IMAGE *in, IMAGE *out, IMAGE_BOX *box ) box->xstart, box->ystart, box->xsize, box->ysize, box->chsel, 1 ) ); } + +/* The public proto has this in the argument. + */ +typedef void (*notify_fn)( IMAGE *, Rect *, void * ); + +int +im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask, + int width, int height, int max, + int fps, int steps, + int priority, + notify_fn notify, void *client ) +{ + return( im_render_priority( in, out, mask, + width, height, max, + priority, + notify, client ) ); +} + +int +im_render( IMAGE *in, IMAGE *out, IMAGE *mask, + int width, int height, int max, + notify_fn notify, void *client ) +{ + return( im_render_priority( in, out, mask, + width, height, max, + 0, + notify, client ) ); +} + +int +im_makerw( IMAGE *im ) +{ + return( im_rwcheck( im ) ); +} diff --git a/libvips/include/vips/Makefile.am b/libvips/include/vips/Makefile.am index 11cfddc4..d036bffe 100644 --- a/libvips/include/vips/Makefile.am +++ b/libvips/include/vips/Makefile.am @@ -11,6 +11,7 @@ pkginclude_HEADERS = \ error.h \ fmask.h \ mosaic.h \ + check.h \ interpolate.h \ object.h \ almostdeprecated.h \ diff --git a/libvips/include/vips/check.h b/libvips/include/vips/check.h new file mode 100644 index 00000000..10d481a0 --- /dev/null +++ b/libvips/include/vips/check.h @@ -0,0 +1,75 @@ +/* check images for various properties + * + * J.Cupitt, 8/4/93 + */ + +/* + + 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_CHECK_H +#define IM_CHECK_H + +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus*/ + +int im_rwcheck( IMAGE *im ); +int im_iocheck( IMAGE *in, IMAGE *out ); +int im_incheck( IMAGE *im ); +int im_outcheck( IMAGE *im ); +int im_piocheck( IMAGE *in, IMAGE *out ); +int im_pincheck( IMAGE *im ); +int im_poutcheck( IMAGE *im ); + +int im_check_uncoded( const char *domain, IMAGE *im ); +int im_check_known_coded( const char *domain, IMAGE *im ); +int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_noncomplex( const char *domain, IMAGE *im ); +int im_check_complex( const char *domain, IMAGE *im ); +int im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ); +int im_check_mono( const char *domain, IMAGE *im ); +int im_check_int( const char *domain, IMAGE *im ); +int im_check_same_size( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_same_bands( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_same_format( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_vector( const char *domain, int n, IMAGE *im ); + +gboolean im_isuint( IMAGE *im ); +gboolean im_isint( IMAGE *im ); +gboolean im_isfloat( IMAGE *im ); +gboolean im_isscalar( IMAGE *im ); +gboolean im_iscomplex( IMAGE *im ); + +gboolean im_isfile( IMAGE *im ); +gboolean im_ispartial( IMAGE *im ); + +gboolean im_isMSBfirst( IMAGE *im ); + +#ifdef __cplusplus +} +#endif /*__cplusplus*/ + +#endif /*IM_CHECK_H*/ diff --git a/libvips/include/vips/deprecated.h b/libvips/include/vips/deprecated.h index dbcd6528..a4445139 100644 --- a/libvips/include/vips/deprecated.h +++ b/libvips/include/vips/deprecated.h @@ -285,6 +285,14 @@ int im_cmulnorm( IMAGE *in1, IMAGE *in2, IMAGE *out ); int im_fav4( IMAGE **, IMAGE * ); int im_gadd( double, IMAGE *, double, IMAGE *, double, IMAGE *); int im_litecor( IMAGE *, IMAGE *, IMAGE *, int, double ); +int im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask, + int width, int height, int max, + int fps, int steps, + int priority, + void (*notify)( IMAGE *, Rect *, void * ), void *client ); +int im_render( IMAGE *in, IMAGE *out, IMAGE *mask, + int width, int height, int max, + void (*notify)( IMAGE *, Rect *, void * ), void *client ); /* Renamed operations. */ diff --git a/libvips/include/vips/generate.h b/libvips/include/vips/generate.h index e3685b44..ef7fb2b2 100644 --- a/libvips/include/vips/generate.h +++ b/libvips/include/vips/generate.h @@ -82,6 +82,14 @@ typedef void (*im_wrapmany_fn)( void **in, void *out, int width, int im_wrapmany( IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b ); +/* Async rendering. + */ +int im_render_priority( IMAGE *in, IMAGE *out, IMAGE *mask, + int width, int height, int max, + int priority, + void (*notify)( IMAGE *, Rect *, void * ), void *client ); +int im_cache( IMAGE *in, IMAGE *out, int width, int height, int max ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/proto.h b/libvips/include/vips/proto.h index 88609692..fbe1c5c0 100644 --- a/libvips/include/vips/proto.h +++ b/libvips/include/vips/proto.h @@ -87,13 +87,6 @@ IMAGE *im_open_header( const char * ); void *im_malloc( IMAGE *im, size_t sz ); int im_free( void * ); -int im_rwcheck( IMAGE * ); -int im_iocheck( IMAGE *, IMAGE * ); -int im_incheck( IMAGE * ); -int im_outcheck( IMAGE * ); -int im_piocheck( IMAGE *, IMAGE * ); -int im_pincheck( IMAGE * ); -int im_poutcheck( IMAGE * ); int im_cp_desc( IMAGE *, IMAGE * ); int im_cp_descv( IMAGE *out, IMAGE *in1, ... ) __attribute__((sentinel)); @@ -101,35 +94,6 @@ int im_cp_desc_array( IMAGE *out, IMAGE *in[] ); int im_setupout( IMAGE * ); int im_writeline( int, IMAGE *, PEL * ); -int im_isuint( IMAGE * ); -int im_isint( IMAGE * ); -int im_isfloat( IMAGE * ); -int im_isscalar( IMAGE * ); -int im_iscomplex( IMAGE * ); -int im_isfile( IMAGE * ); -int im_ispartial( IMAGE * ); -int im_isMSBfirst( IMAGE * ); -int im_amiMSBfirst( void ); - -int im_check_uncoded( const char *domain, IMAGE *im ); -int im_check_known_coded( const char *domain, IMAGE *im ); -int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_noncomplex( const char *domain, IMAGE *im ); -int im_check_complex( const char *domain, IMAGE *im ); -int im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ); -int im_check_mono( const char *domain, IMAGE *im ); -int im_check_int( const char *domain, IMAGE *im ); -int im_check_same_size( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_same_bands( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_same_format( const char *domain, IMAGE *im1, IMAGE *im2 ); -int im_check_vector( const char *domain, int n, IMAGE *im ); - -int im_ispoweroftwo( int ); - -int im_existsf( const char *name, ... ) - __attribute__((format(printf, 1, 2))); -int im_isvips( const char * ); - int im_bits_of_fmt( VipsBandFmt fmt ); int im_unmapfile( IMAGE * ); @@ -137,16 +101,6 @@ void im_initdesc( IMAGE *, int, int, int, int, int, int, int, float, float, int, int ); -int im_render( IMAGE *in, IMAGE *out, IMAGE *mask, - int width, int height, int max, - void (*notify)( IMAGE *, Rect *, void * ), void *client ); -int im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask, - int width, int height, int max, - int fps, int steps, - int priority, - void (*notify)( IMAGE *, Rect *, void * ), void *client ); -int im_cache( IMAGE *in, IMAGE *out, int width, int height, int max ); - /* morphology */ int im_dilate( IMAGE *in, IMAGE *out, INTMASK *m ); diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 4266b677..b631bfb5 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -246,6 +246,12 @@ const char *vips__token_must( const char *buffer, VipsToken *token, const char *vips__token_need( const char *buffer, VipsToken need_token, char *string, int size ); +int im_existsf( const char *name, ... ) + __attribute__((format(printf, 1, 2))); +int im_ispoweroftwo( int p ); +int im_isvips( const char *filename ); +int im_amiMSBfirst( void ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index faf11cd3..78b33366 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -133,6 +133,7 @@ typedef struct im__DOUBLEMASK { #include #include #include +#include #include #include #include diff --git a/libvips/iofuncs/Makefile.am b/libvips/iofuncs/Makefile.am index 1a5649a2..e4e2f666 100644 --- a/libvips/iofuncs/Makefile.am +++ b/libvips/iofuncs/Makefile.am @@ -19,14 +19,11 @@ libiofuncs_la_SOURCES = \ im_image.c \ im_init.c \ im_initdesc.c \ - im_iocheck.c \ im_iterate.c \ - im_makerw.c \ im_mapfile.c \ im_open.c \ im_open_vips.c \ im_partial.c \ - im_piocheck.c \ im_prepare.c \ im_render.c \ im_setbuf.c \ @@ -37,8 +34,8 @@ libiofuncs_la_SOURCES = \ im_wrapmany.c \ im_writeline.c \ memory.c \ + check.c \ package.c \ - predicate.c \ header.c \ region.c \ rect.c \ diff --git a/libvips/iofuncs/check.c b/libvips/iofuncs/check.c new file mode 100644 index 00000000..57b86ca5 --- /dev/null +++ b/libvips/iofuncs/check.c @@ -0,0 +1,1075 @@ +/* check IMAGEs in various ways + * + * im_iocheck() + * Copyright: Nicos Dessipris + * Written on: 12/02/1990 + * Modified on : + * 15/4/93 JC + * - im_incheck(), im_outcheck() added. + * - type field now checked. + * 10/6/93 JC + * - auto-fallback to old-style input added + * 6/6/95 JC + * - revised and improved fallback code + * + * im_rwcheck() + * Copyright: John Cupitt + * Written on: 17/6/92 + * Updated on: + * 15/4/93 + * - checks for partial images added + * - now uses type field + * 31/8/93 JC + * - returns ok for IM_MMAPINRW type files now too + * - returns -1 rather than 1 on error + * - ANSIfied + * 1/10/97 JC + * - moved here, and renamed im_rwcheck() + * 13/2/01 JC + * - im_image_sanity() checks added + * + * im_piocheck() + * 10/6/93 J.Cupitt + * - im_iocheck() adapted to make im_piocheck() + * - auto-rewind feature added + * 27/10/95 JC + * - im_pincheck() on a setbuf now zaps generate function so as not to + * confuse any later calls to im_prepare() or im_prepare_inplace() + * + * 12/10/09 + * - all the above rolled into this file + * - plus chunks of predicate.c + * - gtkdoc comments + */ + +/* + + 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 +#ifdef HAVE_UNISTD_H +#include +#endif /*HAVE_UNISTD_H*/ +#include +#include +#include +#ifdef HAVE_SYS_FILE_H +#include +#endif /*HAVE_SYS_FILE_H*/ + +#include +#include +#include + +#ifdef WITH_DMALLOC +#include +#endif /*WITH_DMALLOC*/ + +/** + * SECTION: check + * @short_description: test images for various properties + * @stability: Stable + * @see_also: image + * @include: vips/vips.h + * + * These functions perform simple checks on an #IMAGE, or indicate that you + * intend to use an #IMAGE in a certain way. + * + * im_incheck(), im_pincheck() and friends indicate the image IO style you + * intend to use, transforming the underlying #IMAGE structure if + * necessary. + * + * im_check_mono() and friends and convenience functions that test an #IMAGE + * for having various properties + * and signal an error if the condition is not met. They are useful for + * writing image processing operations which can only work on certain types of + * image. + */ + +/* Convert a partial to a setbuf. + */ +static int +convert_ptob( IMAGE *im ) +{ + IMAGE *t1; + + /* Change to IM_SETBUF. First, make a memory buffer and copy into that. + */ + if( !(t1 = im_open( "im_incheck:1", "t" )) ) + return( -1 ); + if( im_copy( im, t1 ) ) { + im_close( t1 ); + return( -1 ); + } + + /* Copy new stuff in. We can't im__close( im ) and free stuff, as this + * would kill of lots of regions and cause dangling pointers + * elsewhere. + */ + im->dtype = IM_SETBUF; + im->data = t1->data; + t1->data = NULL; + + /* Close temp image. + */ + if( im_close( t1 ) ) + return( -1 ); + + return( 0 ); +} + +/* Convert an openin to a mmapin. + */ +static int +convert_otom( IMAGE *im ) +{ + /* just mmap() the whole thing. + */ + if( im_mapfile( im ) ) + return( -1 ); + im->data = im->baseaddr + im->sizeof_header; + im->dtype = IM_MMAPIN; + + return( 0 ); +} + +/** + * im_incheck: + * @im: image to check + * + * Check that an image is readable via the IM_IMAGE_ADDR() macro. If it isn't, + * try to transform it so that IM_IMAGE_ADDR() can work. + * + * See also: im_outcheck(), im_pincheck(), im_rwcheck(), IM_IMAGE_ADDR(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_incheck( IMAGE *im ) +{ + g_assert( !im_image_sanity( im ) ); + +#ifdef DEBUG_IO + printf( "im_incheck: old-style input for %s\n", im->filename ); +#endif/*DEBUG_IO*/ + + switch( im->dtype ) { + case IM_SETBUF: + case IM_SETBUF_FOREIGN: + /* Should have been written to. + */ + if( !im->data ) { + im_error( "im_incheck", + "%s", _( "no image data" ) ); + return( -1 ); + } + + break; + + case IM_MMAPIN: + case IM_MMAPINRW: + /* Can read from all these, in principle anyway. + */ + break; + + case IM_PARTIAL: +#ifdef DEBUG_IO + printf( "im_incheck: converting partial image to WIO\n" ); +#endif/*DEBUG_IO*/ + + /* Change to a setbuf, so our caller can use it. + */ + if( convert_ptob( im ) ) + return( -1 ); + + break; + + case IM_OPENIN: +#ifdef DEBUG_IO + printf( "im_incheck: converting openin image for old-style input\n" ); +#endif/*DEBUG_IO*/ + + /* Change to a MMAPIN. + */ + if( convert_otom( im ) ) + return( -1 ); + + break; + + case IM_OPENOUT: + /* Close file down and reopen as im_mmapin. + */ +#ifdef DEBUG_IO + printf( "im_incheck: auto-rewind of %s\n", im->filename ); +#endif/*DEBUG_IO*/ + if( im__close( im ) || im_openin( im ) ) { + im_error( "im_incheck", + _( "auto-rewind for %s failed" ), + im->filename ); + return( -1 ); + } + + break; + + default: + im_error( "im_incheck", + "%s", _( "image not readable" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_outcheck: + * @im: image to check + * + * Check that an image is writeable by im_writeline(). If it isn't, + * try to transform it so that im_writeline() can work. + * + * Set the image properties (like size, type and so on), then call + * im_setupout(), then call im_writeline() for each scan line. + * + * See also: im_incheck(), im_poutcheck(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_outcheck( IMAGE *im ) +{ +#ifdef DEBUG_IO + printf( "im_outcheck: old-style output for %s\n", im->filename ); +#endif/*DEBUG_IO*/ + + switch( im->dtype ) { + case IM_PARTIAL: + /* Make sure nothing is attached. + */ + if( im->generate ) { + im_error( "im_outcheck", + "%s", _( "image already written" ) ); + return( -1 ); + } + + /* Cannot do old-style write to PARTIAL. Turn to SETBUF. + */ + im->dtype = IM_SETBUF; + + /* Fall through to SETBUF case. + */ + + case IM_SETBUF: + /* Check that it has not been im_setupout(). + */ + if( im->data ) { + im_error( "im_outcheck", + "%s", _( "image already written" ) ); + return( -1 ); + } + + break; + + case IM_OPENOUT: + case IM_SETBUF_FOREIGN: + /* Can write to this ok. + */ + break; + + default: + im_error( "im_outcheck", + "%s", _( "image not writeable" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_iocheck: + * @in: input image + * @out: output image + * + * A convenience function to check a pair of images for IO via IM_IMAGE_ADDR() + * and im_writeline(). + * + * See also: im_incheck(), im_outcheck(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_iocheck( IMAGE *in, IMAGE *out ) +{ + return( im_incheck( in ) || im_outcheck( out ) ); +} + +/** + * im_rwcheck: + * @im: image to make read-write + * + * Gets an image ready for an in-place operation, such as im_insertplace(). + * Operations like this both read and write with IM_IMAGE_ADDR(). + * + * See also: im_insertplace(), im_incheck(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_rwcheck( IMAGE *im ) +{ + /* Do an im_incheck(). This will rewind im_openout() files, and + * generate im_partial() files. + */ + if( im_incheck( im ) ) { + im_error( "im_rwcheck", + "%s", _( "unable to rewind file" ) ); + return( -1 ); + } + + /* Look at the type. + */ + switch( im->dtype ) { + case IM_SETBUF: + case IM_SETBUF_FOREIGN: + case IM_MMAPINRW: + /* No action necessary. + */ + break; + + case IM_MMAPIN: + /* Try to remap read-write. + */ + if( im_remapfilerw( im ) ) + return( -1 ); + + break; + + default: + im_error( "im_rwcheck", + "%s", _( "bad file type" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_pincheck: + * @im: image to check + * + * Check that an image is readable with im_prepare() and friends. If it isn't, + * try to transform the image so that im_prepare() can work. + * + * See also: im_incheck(), im_poutcheck(), im_prepare(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_pincheck( IMAGE *im ) +{ + g_assert( !im_image_sanity( im ) ); + +#ifdef DEBUG_IO + printf( "im_pincheck: enabling partial input for %s\n", im->filename ); +#endif /*DEBUG_IO*/ + + switch( im->dtype ) { + case IM_SETBUF: + case IM_SETBUF_FOREIGN: + /* Should have been written to. + */ + if( !im->data ) { + im_error( "im_pincheck", "%s", _( "no image data" ) ); + return( -1 ); + } + + /* Should be no generate functions now. + */ + im->start = NULL; + im->generate = NULL; + im->stop = NULL; + + break; + + case IM_PARTIAL: + /* Should have had generate functions attached. + */ + if( !im->generate ) { + im_error( "im_pincheck", "%s", _( "no image data" ) ); + return( -1 ); + } + + break; + + case IM_MMAPIN: + case IM_MMAPINRW: + case IM_OPENIN: + break; + + case IM_OPENOUT: + /* Close file down and reopen as im_mmapin. + */ +#ifdef DEBUG_IO + printf( "im_pincheck: auto-rewind of %s\n", im->filename ); +#endif/*DEBUG_IO*/ + if( im__close( im ) || im_openin( im ) ) { + im_error( "im_pincheck", + _( "auto-rewind for %s failed" ), + im->filename ); + return( -1 ); + } + + break; + + default: + im_error( "im_pincheck", "%s", _( "image not readable" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_poutcheck: + * @im: image to check + * + * Check that an image is writeable with im_generate(). If it isn't, + * try to transform the image so that im_generate() can work. + * + * See also: im_incheck(), im_poutcheck(), im_generate(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_poutcheck( IMAGE *im ) +{ + if( !im ) { + im_error( "im_poutcheck", "%s", _( "null image descriptor" ) ); + return( -1 ); + } + +#ifdef DEBUG_IO + printf( "im_pincheck: enabling partial output for %s\n", im->filename ); +#endif /*DEBUG_IO*/ + + switch( im->dtype ) { + case IM_SETBUF: + /* Check that it has not been im_setupout(). + */ + if( im->data ) { + im_error( "im_poutcheck", "%s", + _( "image already written" ) ); + return( -1 ); + } + + break; + + case IM_PARTIAL: + /* Make sure nothing is attached. + */ + if( im->generate ) { + im_error( "im_poutcheck", "%s", + _( "image already written" ) ); + return( -1 ); + } + + break; + + case IM_OPENOUT: + case IM_SETBUF_FOREIGN: + /* Okeydoke. Not much checking here. + */ + break; + + default: + im_error( "im_poutcheck", "%s", _( "image not writeable" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_piocheck: + * @in: input image + * @out: output image + * + * A convenience function to check a pair of images for IO via im_prepare() + * and im_generate(). + * + * See also: im_pincheck(), im_poutcheck(). + * + * Returns: 0 on succeess, or -1 on error. + */ +int +im_piocheck( IMAGE *in, IMAGE *out ) +{ + return( im_pincheck( in ) || im_poutcheck( out ) ); +} + +/** + * im_check_uncoded: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image is not coded. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_uncoded( const char *domain, IMAGE *im ) +{ + if( im->Coding != IM_CODING_NONE ) { + im_error( domain, "%s", _( "image must be uncoded" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_known_coded: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image is uncoded, LABQ coded or RAD coded. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_known_coded( const char *domain, IMAGE *im ) +{ + /* These all have codings that extract/ifthenelse/etc can ignore. + */ + if( im->Coding != IM_CODING_NONE && + im->Coding != IM_CODING_LABQ && + im->Coding != IM_CODING_RAD ) { + im_error( domain, "%s", _( "unknown image coding" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_bands_1orn: + * @domain: the originating domain for the error message + * @im1: first image to check + * @im2: second image to check + * + * Check that the images have the same number of bands, or that one of the + * images has just 1 band. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Bands != im2->Bands && + (im1->Bands != 1 && im2->Bands != 1) ) { + im_error( domain, "%s", + _( "images must have the same number of bands, " + "or one must be single-band" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_noncomplex: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image is not complex. + * Otherwise set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_noncomplex( const char *domain, IMAGE *im ) +{ + if( im_iscomplex( im ) ) { + im_error( domain, "%s", _( "image must be non-complex" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_complex: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image is complex. + * Otherwise set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_complex( const char *domain, IMAGE *im ) +{ + if( !im_iscomplex( im ) ) { + im_error( domain, "%s", _( "image must be complex" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_format: + * @domain: the originating domain for the error message + * @im: image to check + * @fmt: format to test for + * + * Check that the image has the specified format. + * Otherwise set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ) +{ + if( im->BandFmt != fmt ) { + im_error( domain, + _( "image must be %s" ), im_BandFmt2char( fmt ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_mono: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image has exactly one band. + * Otherwise set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_mono( const char *domain, IMAGE *im ) +{ + if( im->Bands != 1 ) { + im_error( domain, "%s", _( "image must one band" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_int: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image is in one of the integer formats. + * Otherwise set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_int( const char *domain, IMAGE *im ) +{ + if( !im_isint( im ) ) { + im_error( domain, "%s", _( "image must be integer" ) ); + return( -1 ); + } + + return( 0 ); +} + + +/** + * im_check_same_size: + * @domain: the originating domain for the error message + * @im1: first image to check + * @im2: second image to check + * + * Check that the images have the same size. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_same_size( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Xsize != im2->Xsize || im1->Ysize != im2->Ysize ) { + im_error( domain, "%s", _( "images must match in size" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_same_bands: + * @domain: the originating domain for the error message + * @im1: first image to check + * @im2: second image to check + * + * Check that the images have the same number of bands. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_same_bands( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->Bands != im2->Bands ) { + im_error( domain, "%s", + _( "images must have the same number of bands" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_same_format: + * @domain: the originating domain for the error message + * @im1: first image to check + * @im2: second image to check + * + * Check that the images have the same format. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_same_format( const char *domain, IMAGE *im1, IMAGE *im2 ) +{ + if( im1->BandFmt != im2->BandFmt ) { + im_error( domain, "%s", + _( "images must have the same band format" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_same_vector: + * @domain: the originating domain for the error message + * @im1: first image to check + * @im2: second image to check + * + * Check that the images have the same format. + * If not, set an error message + * and return non-zero. + * + * Returns: 0 if OK, -1 otherwise. + * + * See also: im_error(). + */ +int +im_check_vector( const char *domain, int n, IMAGE *im ) +{ + if( n != 1 && im->Bands != 1 && n != im->Bands ) { + im_error( domain, + _( "vector must have 1 or %d elements" ), im->Bands ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_isint: + * @im: image to test + * + * Return %TRUE if @im's #VipsBandFmt is one of the integer types. + */ +gboolean +im_isint( IMAGE *im ) +{ + switch( im->BandFmt ) { + case IM_BANDFMT_UCHAR: + case IM_BANDFMT_CHAR: + case IM_BANDFMT_USHORT: + case IM_BANDFMT_SHORT: + case IM_BANDFMT_UINT: + case IM_BANDFMT_INT: + return( 1 ); + + case IM_BANDFMT_FLOAT: + case IM_BANDFMT_DOUBLE: + case IM_BANDFMT_COMPLEX: + case IM_BANDFMT_DPCOMPLEX: + return( 0 ); + + default: + error_exit( "im_isint: unknown image BandFmt" ); + /*NOTREACHED*/ + return( -1 ); + } +} + +/** + * im_isuint: + * @im: image to test + * + * Return %TRUE if @im's #VipsBandFmt is one of the unsigned integer types. + */ +gboolean +im_isuint( IMAGE *im ) +{ + switch( im->BandFmt ) { + case IM_BANDFMT_UCHAR: + case IM_BANDFMT_USHORT: + case IM_BANDFMT_UINT: + return( 1 ); + + case IM_BANDFMT_INT: + case IM_BANDFMT_SHORT: + case IM_BANDFMT_CHAR: + case IM_BANDFMT_FLOAT: + case IM_BANDFMT_DOUBLE: + case IM_BANDFMT_COMPLEX: + case IM_BANDFMT_DPCOMPLEX: + return( 0 ); + + default: + error_exit( "im_isuint: unknown image BandFmt" ); + /*NOTREACHED*/ + return( -1 ); + } +} + + +/** + * im_isint: + * @im: image to test + * + * Return %TRUE if @im's #VipsBandFmt is one of the integer types. + */ +gboolean +im_isfloat( IMAGE *im ) +{ + switch( im->BandFmt ) { + case IM_BANDFMT_FLOAT: + case IM_BANDFMT_DOUBLE: + return( 1 ); + + case IM_BANDFMT_UCHAR: + case IM_BANDFMT_CHAR: + case IM_BANDFMT_USHORT: + case IM_BANDFMT_SHORT: + case IM_BANDFMT_UINT: + case IM_BANDFMT_INT: + case IM_BANDFMT_COMPLEX: + case IM_BANDFMT_DPCOMPLEX: + return( 0 ); + + default: + error_exit( "im_isfloat: unknown image BandFmt" ); + /*NOTREACHED*/ + return( -1 ); + } +} + +/** + * im_isscalar: + * @im: image to test + * + * Return %TRUE if @im's #VipsBandFmt is one of the non-complex types. + */ +gboolean +im_isscalar( IMAGE *im ) +{ + switch( im->BandFmt ) { + case IM_BANDFMT_UCHAR: + case IM_BANDFMT_CHAR: + case IM_BANDFMT_USHORT: + case IM_BANDFMT_SHORT: + case IM_BANDFMT_UINT: + case IM_BANDFMT_INT: + case IM_BANDFMT_FLOAT: + case IM_BANDFMT_DOUBLE: + return( 1 ); + + case IM_BANDFMT_COMPLEX: + case IM_BANDFMT_DPCOMPLEX: + return( 0 ); + + default: + error_exit( "im_isscalar: unknown image BandFmt" ); + /*NOTREACHED*/ + return( -1 ); + } +} + + +/** + * im_iscomplex: + * @im: image to test + * + * Return %TRUE if @im's #VipsBandFmt is one of the complex types. + */ +gboolean +im_iscomplex( IMAGE *im ) +{ + switch( im->BandFmt ) { + case IM_BANDFMT_COMPLEX: + case IM_BANDFMT_DPCOMPLEX: + return( 1 ); + + case IM_BANDFMT_UCHAR: + case IM_BANDFMT_CHAR: + case IM_BANDFMT_USHORT: + case IM_BANDFMT_SHORT: + case IM_BANDFMT_UINT: + case IM_BANDFMT_INT: + case IM_BANDFMT_FLOAT: + case IM_BANDFMT_DOUBLE: + return( 0 ); + + default: + error_exit( "im_iscomplex: unknown image BandFmt" ); + /*NOTREACHED*/ + return( -1 ); + } +} + +/** + * im_isMSBfirst: + * @im: image to test + * + * Return %TRUE if @im is in most-significant- + * byte first form. This is the byte order used on the SPARC + * architecture + * and others. + */ +gboolean +im_isMSBfirst( IMAGE *im ) +{ + if( im->magic == IM_MAGIC_SPARC ) + return( 1 ); + else + return( 0 ); +} + +/** + * im_isfile: + * @im: image to test + * + * Return %TRUE if @im represents a file on disc in some way. + */ +gboolean +im_isfile( IMAGE *im ) +{ + switch( im->dtype ) { + case IM_MMAPIN: + case IM_MMAPINRW: + case IM_OPENOUT: + case IM_OPENIN: + return( 1 ); + + case IM_PARTIAL: + case IM_SETBUF: + case IM_SETBUF_FOREIGN: + case IM_NONE: + return( 0 ); + + default: + error_exit( "im_isfile: corrupt IMAGE descriptor" ); + /*NOTREACHED*/ + return( -1 ); + } +} + +/** + * im_ispartial: + * @im: image to test + * + * Return %TRUE if @im represents a partial image (a delayed calculation). + */ +gboolean +im_ispartial( IMAGE *im ) +{ + switch( im->dtype ) { + case IM_PARTIAL: + return( 1 ); + + case IM_SETBUF: + case IM_SETBUF_FOREIGN: + case IM_MMAPIN: + case IM_MMAPINRW: + case IM_OPENIN: + case IM_OPENOUT: + case IM_NONE: + return( 0 ); + + default: + error_exit( "im_ispartial: corrupt IMAGE descriptor" ); + /*NOTREACHED*/ + return( -1 ); + } +} diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 8fcec6a8..e2fe423a 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -66,7 +66,8 @@ * SECTION: header * @short_description: get, set and walk image headers * @stability: Stable - * @see_also: meta + * @see_also: meta, + * check * @include: vips/vips.h * * These functions let you get at image header data (including metadata) in a diff --git a/libvips/iofuncs/im_iocheck.c b/libvips/iofuncs/im_iocheck.c deleted file mode 100644 index c16eae92..00000000 --- a/libvips/iofuncs/im_iocheck.c +++ /dev/null @@ -1,321 +0,0 @@ -/* @(#) Function which checks the structures imagein and imageout - * @(#) It returns a valid value only if ip and op are set properly - * @(#) Cases of returned integer value - * @(#) - * @(#) int im_iocheck(imagein, imageout) - * @(#) IMAGE *imagein, *imageout; - * @(#) - * @(#) Returns -1 on fail - * @(#) - * - * Copyright: Nicos Dessipris - * Written on: 12/02/1990 - * Modified on : - * 15/4/93 JC - * - im_incheck(), im_outcheck() added. - * - type field now checked. - * 10/6/93 JC - * - auto-fallback to old-style input added - * 6/6/95 JC - * - revised and improved fallback code - */ - -/* @(#) Try to make an IMAGE writeable. im_mmapin files become im_mmapinrw - * @(#) files, buffers are left alone and output files and partial images - * @(#) generate an error. - * @(#) - * @(#) int im_rwcheck( im ) - * @(#) IMAGE *im; - * @(#) - * @(#) Returns non-zero on error. - * @(#) - * Copyright: John Cupitt - * Written on: 17/6/92 - * Updated on: - * 15/4/93 - * - checks for partial images added - * - now uses type field - * 31/8/93 JC - * - returns ok for IM_MMAPINRW type files now too - * - returns -1 rather than 1 on error - * - ANSIfied - * 1/10/97 JC - * - moved here, and renamed im_rwcheck() - * 13/2/01 JC - * - im_image_sanity() checks added - */ - -/* - - 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 -#ifdef HAVE_UNISTD_H -#include -#endif /*HAVE_UNISTD_H*/ -#include -#include -#include -#ifdef HAVE_SYS_FILE_H -#include -#endif /*HAVE_SYS_FILE_H*/ - -#include -#include -#include - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Convert a partial to a setbuf. - */ -static int -convert_ptob( IMAGE *im ) -{ - IMAGE *t1; - - /* Change to IM_SETBUF. First, make a memory buffer and copy into that. - */ - if( !(t1 = im_open( "im_incheck:1", "t" )) ) - return( -1 ); - if( im_copy( im, t1 ) ) { - im_close( t1 ); - return( -1 ); - } - - /* Copy new stuff in. We can't im__close( im ) and free stuff, as this - * would kill of lots of regions and cause dangling pointers - * elsewhere. - */ - im->dtype = IM_SETBUF; - im->data = t1->data; - t1->data = NULL; - - /* Close temp image. - */ - if( im_close( t1 ) ) - return( -1 ); - - return( 0 ); -} - -/* Convert an openin to a mmapin. - */ -static int -convert_otom( IMAGE *im ) -{ - /* just mmap() the whole thing. - */ - if( im_mapfile( im ) ) - return( -1 ); - im->data = im->baseaddr + im->sizeof_header; - im->dtype = IM_MMAPIN; - - return( 0 ); -} - -/* Check that an image is readable by old-style VIPS functions. - */ -int -im_incheck( IMAGE *im ) -{ - g_assert( !im_image_sanity( im ) ); - -#ifdef DEBUG_IO - printf( "im_incheck: old-style input for %s\n", im->filename ); -#endif/*DEBUG_IO*/ - - switch( im->dtype ) { - case IM_SETBUF: - case IM_SETBUF_FOREIGN: - /* Should have been written to. - */ - if( !im->data ) { - im_error( "im_incheck", - "%s", _( "no image data" ) ); - return( -1 ); - } - - break; - - case IM_MMAPIN: - case IM_MMAPINRW: - /* Can read from all these, in principle anyway. - */ - break; - - case IM_PARTIAL: -#ifdef DEBUG_IO - printf( "im_incheck: converting partial image to WIO\n" ); -#endif/*DEBUG_IO*/ - - /* Change to a setbuf, so our caller can use it. - */ - if( convert_ptob( im ) ) - return( -1 ); - - break; - - case IM_OPENIN: -#ifdef DEBUG_IO - printf( "im_incheck: converting openin image for old-style input\n" ); -#endif/*DEBUG_IO*/ - - /* Change to a MMAPIN. - */ - if( convert_otom( im ) ) - return( -1 ); - - break; - - case IM_OPENOUT: - /* Close file down and reopen as im_mmapin. - */ -#ifdef DEBUG_IO - printf( "im_incheck: auto-rewind of %s\n", im->filename ); -#endif/*DEBUG_IO*/ - if( im__close( im ) || im_openin( im ) ) { - im_error( "im_incheck", - _( "auto-rewind for %s failed" ), - im->filename ); - return( -1 ); - } - - break; - - default: - im_error( "im_incheck", - "%s", _( "image not readable" ) ); - return( -1 ); - } - - return( 0 ); -} - -/* Check that an image is writeable. - */ -int -im_outcheck( IMAGE *im ) -{ -#ifdef DEBUG_IO - printf( "im_outcheck: old-style output for %s\n", im->filename ); -#endif/*DEBUG_IO*/ - - switch( im->dtype ) { - case IM_PARTIAL: - /* Make sure nothing is attached. - */ - if( im->generate ) { - im_error( "im_outcheck", - "%s", _( "image already written" ) ); - return( -1 ); - } - - /* Cannot do old-style write to PARTIAL. Turn to SETBUF. - */ - im->dtype = IM_SETBUF; - - /* Fall through to SETBUF case. - */ - - case IM_SETBUF: - /* Check that it has not been im_setupout(). - */ - if( im->data ) { - im_error( "im_outcheck", - "%s", _( "image already written" ) ); - return( -1 ); - } - - break; - - case IM_OPENOUT: - case IM_SETBUF_FOREIGN: - /* Can write to this ok. - */ - break; - - default: - im_error( "im_outcheck", - "%s", _( "image not writeable" ) ); - return( -1 ); - } - - return( 0 ); -} - -/* Check a pair of fds for IO. - */ -int -im_iocheck( IMAGE *in, IMAGE *out ) -{ - return( im_incheck( in ) || im_outcheck( out ) ); -} - -int -im_rwcheck( IMAGE *im ) -{ - /* Do an im_incheck(). This will rewind im_openout() files, and - * generate im_partial() files. - */ - if( im_incheck( im ) ) { - im_error( "im_rwcheck", - "%s", _( "unable to rewind file" ) ); - return( -1 ); - } - - /* Look at the type. - */ - switch( im->dtype ) { - case IM_SETBUF: - case IM_SETBUF_FOREIGN: - case IM_MMAPINRW: - /* No action necessary. - */ - break; - - case IM_MMAPIN: - /* Try to remap read-write. - */ - if( im_remapfilerw( im ) ) - return( -1 ); - - break; - - default: - im_error( "im_rwcheck", - "%s", _( "bad file type" ) ); - return( -1 ); - } - - return( 0 ); -} diff --git a/libvips/iofuncs/im_makerw.c b/libvips/iofuncs/im_makerw.c deleted file mode 100644 index f4bb86e7..00000000 --- a/libvips/iofuncs/im_makerw.c +++ /dev/null @@ -1,86 +0,0 @@ -/* @(#) Try to make an IMAGE writeable. im_mmapin files become im_mmapinrw - * @(#) files, buffers are left alone and output files and partial images - * @(#) generate an error. - * @(#) - * @(#) int im_makerw( im ) - * @(#) IMAGE *im; - * @(#) - * @(#) Returns non-zero on error. - * @(#) - * Copyright: John Cupitt - * Written on: 17/6/92 - * Updated on: - * 15/4/93 - * - checks for partial images added - * - now uses type field - * 31/8/93 JC - * - returns ok for IM_MMAPINRW type files now too - * - returns -1 rather than 1 on error - * - ANSIfied - */ - -/* - - 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 - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -int -im_makerw( IMAGE *im ) -{ - /* This will rewind im_openout() files, and generate im_partial() files. - */ - if( im_incheck( im ) ) { - im_error( "im_makerw", "%s", _( "unable to rewind file" ) ); - return( -1 ); - } - - switch( im->dtype ) { - case IM_SETBUF: - case IM_SETBUF_FOREIGN: - case IM_MMAPINRW: - break; - - case IM_MMAPIN: - if( im_remapfilerw( im ) ) - return( -1 ); - break; - - default: - im_error( "im_makerw", "%s", _( "bad file type" ) ); - return( -1 ); - } - - return( 0 ); -} diff --git a/libvips/iofuncs/im_piocheck.c b/libvips/iofuncs/im_piocheck.c deleted file mode 100644 index ac30925e..00000000 --- a/libvips/iofuncs/im_piocheck.c +++ /dev/null @@ -1,200 +0,0 @@ -/* @(#) Function which checks the structures imagein and imageout and gets - * @(#) ready for partial input. If a function calls this in its setup stage, - * @(#) we assume it is partial-ready. If it calls im_iocheck(), we fall back - * @(#) to old-style behaviour. - * @(#) - * @(#) int - * @(#) im_piocheck( imagein, imageout ) - * @(#) IMAGE *imagein, *imageout; - * @(#) - * @(#) int - * @(#) im_pincheck( imagein ) - * @(#) IMAGE *imagein; - * @(#) - * @(#) int - * @(#) im_piocheck( imageout ) - * @(#) IMAGE *imageout; - * @(#) - * @(#) Returns -1 on fail - * @(#) - * - * Copyright: Nicos Dessipris - * Written on: 12/02/1990 - * Modified on : - * 15/4/93 J.Cupitt - * - im_incheck(), im_outcheck() added. - * - type field now checked. - * 10/6/93 J.Cupitt - * - im_iocheck() adapted to make im_piocheck() - * - auto-rewind feature added - * 27/10/95 JC - * - im_pincheck() on a setbuf now zaps generate function so as not to - * confuse any later calls to im_prepare() or im_prepare_inplace() - */ - -/* - - 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 -#include - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Check that an image is readable. - */ -int -im_pincheck( IMAGE *im ) -{ - g_assert( !im_image_sanity( im ) ); - -#ifdef DEBUG_IO - printf( "im_pincheck: enabling partial input for %s\n", im->filename ); -#endif /*DEBUG_IO*/ - - switch( im->dtype ) { - case IM_SETBUF: - case IM_SETBUF_FOREIGN: - /* Should have been written to. - */ - if( !im->data ) { - im_error( "im_pincheck", "%s", _( "no image data" ) ); - return( -1 ); - } - - /* Should be no generate functions now. - */ - im->start = NULL; - im->generate = NULL; - im->stop = NULL; - - break; - - case IM_PARTIAL: - /* Should have had generate functions attached. - */ - if( !im->generate ) { - im_error( "im_pincheck", "%s", _( "no image data" ) ); - return( -1 ); - } - - break; - - case IM_MMAPIN: - case IM_MMAPINRW: - case IM_OPENIN: - break; - - case IM_OPENOUT: - /* Close file down and reopen as im_mmapin. - */ -#ifdef DEBUG_IO - printf( "im_pincheck: auto-rewind of %s\n", im->filename ); -#endif/*DEBUG_IO*/ - if( im__close( im ) || im_openin( im ) ) { - im_error( "im_pincheck", - _( "auto-rewind for %s failed" ), - im->filename ); - return( -1 ); - } - - break; - - default: - im_error( "im_pincheck", "%s", _( "image not readable" ) ); - return( -1 ); - } - - return( 0 ); -} - -/* Check that an image is writeable. - */ -int -im_poutcheck( IMAGE *im ) -{ - if( !im ) { - im_error( "im_poutcheck", "%s", _( "null image descriptor" ) ); - return( -1 ); - } - -#ifdef DEBUG_IO - printf( "im_pincheck: enabling partial output for %s\n", im->filename ); -#endif /*DEBUG_IO*/ - - switch( im->dtype ) { - case IM_SETBUF: - /* Check that it has not been im_setupout(). - */ - if( im->data ) { - im_error( "im_poutcheck", "%s", - _( "image already written" ) ); - return( -1 ); - } - - break; - - case IM_PARTIAL: - /* Make sure nothing is attached. - */ - if( im->generate ) { - im_error( "im_poutcheck", "%s", - _( "image already written" ) ); - return( -1 ); - } - - break; - - case IM_OPENOUT: - case IM_SETBUF_FOREIGN: - /* Okeydoke. Not much checking here. - */ - break; - - default: - im_error( "im_poutcheck", "%s", _( "image not writeable" ) ); - return( -1 ); - } - - return( 0 ); -} - -/* Check a pair of fds for IO. - */ -int -im_piocheck( IMAGE *in, IMAGE *out ) -{ - return( im_pincheck( in ) || im_poutcheck( out ) ); -} diff --git a/libvips/iofuncs/im_render.c b/libvips/iofuncs/im_render.c index 224e4cd1..82fab222 100644 --- a/libvips/iofuncs/im_render.c +++ b/libvips/iofuncs/im_render.c @@ -36,6 +36,9 @@ * 5/3/09 * - remove all the fading stuff, a bit useless and it adds * complexity + * 12/10/09 + * - gtkdoc comment + * - im_render(), im_render_fade() moved to deprecated */ /* @@ -1017,13 +1020,55 @@ mask_fill( REGION *out, void *seq, void *a, void *b ) return( 0 ); } -/* fps and steps are there for backwards compat only and no longer do - * anything. +/** + * im_render_priority: + * @in: input image + * @out: output image + * @mask: mask image indicating valid pixels + * @width: tile width + * @height: tile height + * @max: maximum tiles to cache + * @priority: rendering priority + * @notify: pixels are ready notification callback + * @client: client data for callback + * + * This operation renders @in in the background, making pixels available on + * @out as they are calculated. The @notify callback is run every time a new + * set of pixels are available. Calculated pixels are kept in a cache with + * tiles sized @width by @height pixels and at most @max tiles. + * If @max is -1, the cache is of unlimited size (up to the maximum image + * size). + * The @mask image s a one-band uchar image and has 255 for pixels which are + * currently in cache and 0 for uncalculated pixels. + * + * The pixel rendering system has a single global #im_threadgroup_t which is + * used for all currently active instances of im_render_priority(). As + * renderers are added and removed from the system, the threadgroup switches + * between renderers based on their priority setting. Zero means normal + * priority, negative numbers are low priority, positive numbers high + * priority. + * + * Calls to im_prepare() on @out return immediately and hold whatever is + * currently in cache for that #Rect (check @mask to see which parts of the + * #Rect are valid). Any pixels in the #Rect which are not in cache are added + * to a queue, and the @notify callback will trigger when those pixels are + * ready. + * + * The @notify callback is run from the background thread. In the callback, + * you need to somehow send a message to the main thread that the pixels are + * ready. In a glib-based application, this is easily done with g_idle_add(). + * + * If @notify is %NULL, then im_render_priority() runs synchronously. + * im_prepare() on @out will always block until the pixels have been + * calculated by the background #im_threadgroup_t. + * + * Returns: 0 on sucess, -1 on error. + * + * See also: im_cache(), im_prepare(). */ int -im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask, +im_render_priority( IMAGE *in, IMAGE *out, IMAGE *mask, int width, int height, int max, - int fps, int steps, int priority, notify_fn notify, void *client ) { @@ -1078,19 +1123,28 @@ im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask, return( 0 ); } -int -im_render( IMAGE *in, IMAGE *out, IMAGE *mask, - int width, int height, int max, notify_fn notify, void *client ) -{ - return( im_render_fade( in, out, mask, - width, height, max, 10, 0, 0, notify, client ) ); -} - +/** + * im_cache: + * @in: input image + * @out: output image + * @width: tile width + * @height: tile height + * @max: maximum tiles to cache + * + * im_cache() works exactly as im_copy(), except that calculated pixels are + * kept in a cache. If @in is the result of a large computation and you are + * expecting to reuse the result in a number of places, im_cache() can save a + * lot of time. + * + * im_cache() is a convenience function over im_render_priority(). + * + * See also: im_render_priority(), im_copy(), im_prepare_thread(). + */ int im_cache( IMAGE *in, IMAGE *out, int width, int height, int max ) { - if( im_render( in, out, NULL, width, height, max, NULL, NULL ) ) - return( -1 ); - - return( 0 ); + return( im_render_priority( in, out, NULL, + width, height, max, + 0, + NULL, NULL ) ); } diff --git a/libvips/iofuncs/predicate.c b/libvips/iofuncs/predicate.c deleted file mode 100644 index 958d2fa0..00000000 --- a/libvips/iofuncs/predicate.c +++ /dev/null @@ -1,504 +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 - * - image format stuff broken out - * 29/7/09 - * - check funcs added - */ - -/* - - 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 HAVE_SYS_PARAM_H -#include -#endif /*HAVE_SYS_PARAM_H*/ -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif /*HAVE_UNISTD_H*/ -#ifdef HAVE_IO_H -#include -#endif /*HAVE_IO_H*/ -#include -#include - -#include -#include -#include - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Test BandFmt. - */ -int -im_isint( IMAGE *im ) -{ - switch( im->BandFmt ) { - case IM_BANDFMT_UCHAR: - case IM_BANDFMT_CHAR: - case IM_BANDFMT_USHORT: - case IM_BANDFMT_SHORT: - case IM_BANDFMT_UINT: - case IM_BANDFMT_INT: - return( 1 ); - - case IM_BANDFMT_FLOAT: - case IM_BANDFMT_DOUBLE: - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_DPCOMPLEX: - return( 0 ); - - default: - error_exit( "im_isint: unknown image BandFmt" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -/* Test endianness of an image. SPARC is MSB first - */ -int -im_isMSBfirst( IMAGE *im ) -{ - if( im->magic == IM_MAGIC_SPARC ) - return( 1 ); - else - return( 0 ); -} - -/* Test this processor for endianness. True for SPARC order. - */ -int -im_amiMSBfirst( void ) -{ - int test; - unsigned char *p = (unsigned char *) &test; - - test = 0; - p[0] = 255; - - if( test == 255 ) - return( 0 ); - else - return( 1 ); -} - -int -im_isuint( IMAGE *im ) -{ - switch( im->BandFmt ) { - case IM_BANDFMT_UCHAR: - case IM_BANDFMT_USHORT: - case IM_BANDFMT_UINT: - return( 1 ); - - case IM_BANDFMT_INT: - case IM_BANDFMT_SHORT: - case IM_BANDFMT_CHAR: - case IM_BANDFMT_FLOAT: - case IM_BANDFMT_DOUBLE: - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_DPCOMPLEX: - return( 0 ); - - default: - error_exit( "im_isuint: unknown image BandFmt" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -int -im_isfloat( IMAGE *im ) -{ - switch( im->BandFmt ) { - case IM_BANDFMT_FLOAT: - case IM_BANDFMT_DOUBLE: - return( 1 ); - - case IM_BANDFMT_UCHAR: - case IM_BANDFMT_CHAR: - case IM_BANDFMT_USHORT: - case IM_BANDFMT_SHORT: - case IM_BANDFMT_UINT: - case IM_BANDFMT_INT: - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_DPCOMPLEX: - return( 0 ); - - default: - error_exit( "im_isfloat: unknown image BandFmt" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -int -im_isscalar( IMAGE *im ) -{ - switch( im->BandFmt ) { - case IM_BANDFMT_UCHAR: - case IM_BANDFMT_CHAR: - case IM_BANDFMT_USHORT: - case IM_BANDFMT_SHORT: - case IM_BANDFMT_UINT: - case IM_BANDFMT_INT: - case IM_BANDFMT_FLOAT: - case IM_BANDFMT_DOUBLE: - return( 1 ); - - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_DPCOMPLEX: - return( 0 ); - - default: - error_exit( "im_isscalar: unknown image BandFmt" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -int -im_iscomplex( IMAGE *im ) -{ - switch( im->BandFmt ) { - case IM_BANDFMT_COMPLEX: - case IM_BANDFMT_DPCOMPLEX: - return( 1 ); - - case IM_BANDFMT_UCHAR: - case IM_BANDFMT_CHAR: - case IM_BANDFMT_USHORT: - case IM_BANDFMT_SHORT: - case IM_BANDFMT_UINT: - case IM_BANDFMT_INT: - case IM_BANDFMT_FLOAT: - case IM_BANDFMT_DOUBLE: - return( 0 ); - - default: - error_exit( "im_iscomplex: unknown image BandFmt" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -/* Test for file exists. - */ -int -im_existsf( const char *name, ... ) -{ - va_list ap; - char buf1[PATH_MAX]; - - va_start( ap, name ); - (void) im_vsnprintf( buf1, PATH_MAX - 1, name, ap ); - va_end( ap ); - - /* Try that. - */ - if( !access( buf1, R_OK ) ) - return( 1 ); - - return( 0 ); -} - -/* True if this IMAGE is a disc file of some sort. - */ -int -im_isfile( IMAGE *im ) -{ - switch( im->dtype ) { - case IM_MMAPIN: - case IM_MMAPINRW: - case IM_OPENOUT: - case IM_OPENIN: - return( 1 ); - - case IM_PARTIAL: - case IM_SETBUF: - case IM_SETBUF_FOREIGN: - case IM_NONE: - return( 0 ); - - default: - error_exit( "im_isfile: corrupt IMAGE descriptor" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -/* True if this IMAGE is a partial of some sort. - */ -int -im_ispartial( IMAGE *im ) -{ - switch( im->dtype ) { - case IM_PARTIAL: - return( 1 ); - - case IM_SETBUF: - case IM_SETBUF_FOREIGN: - case IM_MMAPIN: - case IM_MMAPINRW: - case IM_OPENIN: - case IM_OPENOUT: - case IM_NONE: - return( 0 ); - - default: - error_exit( "im_ispartial: corrupt IMAGE descriptor" ); - /*NOTREACHED*/ - return( -1 ); - } -} - -/* True if an int is a power of two ... 1, 2, 4, 8, 16, 32, etc. Do with just - * integer arithmetic for portability. A previous Nicos version using doubles - * and log/log failed on x86 with rounding problems. Return 0 for not - * power of two, otherwise return the position of the set bit (numbering with - * bit 1 as the lsb). - */ -int -im_ispoweroftwo( int p ) -{ - int i, n; - - /* Count set bits. Could use a LUT, I guess. - */ - for( i = 0, n = 0; p; i++, p >>= 1 ) - if( p & 1 ) - n++; - - /* Should be just one set bit. - */ - if( n == 1 ) - /* Return position of bit. - */ - return( i ); - 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 ); -} - -int -im_check_uncoded( const char *domain, IMAGE *im ) -{ - if( im->Coding != IM_CODING_NONE ) { - im_error( domain, "%s", _( "image must be uncoded" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_known_coded( const char *domain, IMAGE *im ) -{ - /* These all have codings that extract/ifthenelse/etc can ignore. - */ - if( im->Coding != IM_CODING_NONE && - im->Coding != IM_CODING_LABQ && - im->Coding != IM_CODING_RAD ) { - im_error( domain, "%s", _( "unknown image coding" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ) -{ - if( im1->Bands != im2->Bands && - (im1->Bands != 1 && im2->Bands != 1) ) { - im_error( domain, "%s", - _( "images must have the same number of bands, " - "or one must be single-band" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_noncomplex( const char *domain, IMAGE *im ) -{ - if( im_iscomplex( im ) ) { - im_error( domain, "%s", _( "image must be non-complex" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_complex( const char *domain, IMAGE *im ) -{ - if( !im_iscomplex( im ) ) { - im_error( domain, "%s", _( "image must be complex" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ) -{ - if( im->BandFmt != fmt ) { - im_error( domain, - _( "image must be %s" ), im_BandFmt2char( fmt ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_mono( const char *domain, IMAGE *im ) -{ - if( im->Bands != 1 ) { - im_error( domain, "%s", _( "image must one band" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_int( const char *domain, IMAGE *im ) -{ - if( !im_isint( im ) ) { - im_error( domain, "%s", _( "image must be integer" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_same_size( const char *domain, IMAGE *im1, IMAGE *im2 ) -{ - if( im1->Xsize != im2->Xsize || im1->Ysize != im2->Ysize ) { - im_error( domain, "%s", _( "images must match in size" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_same_bands( const char *domain, IMAGE *im1, IMAGE *im2 ) -{ - if( im1->Bands != im2->Bands ) { - im_error( domain, "%s", - _( "images must have the same number of bands" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_same_format( const char *domain, IMAGE *im1, IMAGE *im2 ) -{ - if( im1->BandFmt != im2->BandFmt ) { - im_error( domain, "%s", - _( "images must have the same band format" ) ); - return( -1 ); - } - - return( 0 ); -} - -int -im_check_vector( const char *domain, int n, IMAGE *im ) -{ - if( n != 1 && im->Bands != 1 && n != im->Bands ) { - im_error( domain, - _( "vector must have 1 or %d elements" ), im->Bands ); - return( -1 ); - } - - return( 0 ); -} diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c deleted file mode 100644 index d3ca9e51..00000000 --- a/libvips/iofuncs/type.c +++ /dev/null @@ -1,352 +0,0 @@ -/* Define built-in VIPS types. - */ - -/* - - 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 - -#include - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Keep types in a GHashTable, indexed by name + type_param. - */ -static GHashTable *im_type_table = NULL; - -/* Keep operations in a GHashTable, indexed by name. - */ -static GHashTable *im_operation_table = NULL; - -static unsigned int -im_type_hash( im_type_t *type ) -{ - return( g_str_hash( type->name ) | - GPOINTER_TO_UINT( type->type_param ) ); -} - -static gboolean -im_type_equal( im_type_t *type1, im_type_t *type2 ) -{ - return( type1->type_param == type2->type_param && - g_str_equal( type1->name, type2->name ) ); -} - -im_type_t * -im_type_register( const char *name, - im_type_t *type_param, size_t size ) -{ - im_type_t *type; - - if( im_type_lookup( name, type_param ) ) { - im_error( "im_type_register", - _( "type name already registered" ) ); - return( NULL ); - } - - if( !(type = IM_NEW( NULL, im_type_t )) ) - return( NULL ); - type->name = name; - type->type_param = type_param; - type->size = size; - - if( !im_type_table ) - im_type_table = g_hash_table_new( - (GHashFunc) im_type_hash, - (GEqualFunc) im_type_equal ); - g_hash_table_insert( im_type_table, type, type ); - - return( type ); -} - -void * -im_type_map( VSListMap2Fn fn, void *a, void *b ) -{ - return( im_hash_table_map( im_type_table, fn, a, b ) ); -} - -im_type_t * -im_type_lookup( const char *name, im_type_t *type_param ) -{ - im_type_t tmp; - im_type_t *type; - - /* Look for this exact type. - */ - tmp.name = name; - tmp.type_param = type_param; - if( !(type = (im_type_t *) - g_hash_table_lookup( im_type_table, &tmp )) ) { - /* Not found. Look for just the name type, eg. "array". - */ - tmp.type_param = NULL; - if( (type = (im_type_t *) - g_hash_table_lookup( im_type_table, &tmp )) ) - /* Found it. Register a new compound type with this - * param. - */ - type = im_type_register( name, type_param, type->size ); - } - - return( type ); -} - -/* Register the base VIPS types. - */ -void -im__type_init( void ) -{ - im_type_register( IM_TYPE_NAME_DOUBLE, NULL, sizeof( double ) ); - im_type_register( IM_TYPE_NAME_INT, NULL, sizeof( int ) ); - im_type_register( IM_TYPE_NAME_COMPLEX, NULL, 2 * sizeof( double ) ); - im_type_register( IM_TYPE_NAME_STRING, NULL, 0 ); - im_type_register( IM_TYPE_NAME_IMASK, NULL, sizeof( im_value_mask_t ) ); - im_type_register( IM_TYPE_NAME_DMASK, NULL, sizeof( im_value_mask_t ) ); - im_type_register( IM_TYPE_NAME_IMAGE, NULL, 0 ); - im_type_register( IM_TYPE_NAME_DISPLAY, NULL, 0 ); - im_type_register( IM_TYPE_NAME_GVALUE, NULL, sizeof( GValue ) ); - im_type_register( IM_TYPE_NAME_ARRAY, - NULL, sizeof( im_value_array_t ) ); -} - -/* Allocate an im_value_t. - */ -static im_value_t * -im_value_new( im_type_t *type ) -{ - im_value_t *value; - - if( type->size ) { - if( !(value = im_malloc( NULL, type->size )) ) - return( NULL ); - memset( value, 0, type->size ); - } - else - value = NULL; - - return( value ); -} - -/* Free an im_value_t. - */ -static void -im_value_free( im_value_t *value, im_type_t *type ) -{ - if( type->size ) - IM_FREE( value ); -} - -/* Convenience functions to build and free various values. - */ -void -im_value_imask_free( im_value_mask_t *value ) -{ - IM_FREE( value->name ); - IM_FREEF( im_free_imask, value->mask ); -} - -void -im_value_dmask_free( im_value_mask_t *value ) -{ - IM_FREE( value->name ); - IM_FREEF( im_free_dmask, value->mask ); -} - -void -im_value_gvalue_free( GValue *value ) -{ - g_value_unset( value ); -} - -void -im_value_array_free( im_value_array_t *value, im_type_t *type ) -{ - int i; - - for( i = 0; i < value->n; i++ ) - im_value_free( value->array[i], type->type_param ); -} - -gboolean -im_value_mask_output_init( im_value_mask_t *value, const char *name ) -{ - if( !(value->name = im_strdup( NULL, name )) ) - return( FALSE ); - - return( TRUE ); -} - -gboolean -im_value_imask_input_init( im_value_mask_t *value, const char *name ) -{ - INTMASK *mask; - - if( !(mask = im_read_imask( name )) ) - return( FALSE ); - value->mask = (void *) mask; - if( !(value->name = im_strdup( NULL, name )) ) { - im_value_imask_free( value ); - return( FALSE ); - } - - return( TRUE ); -} - -/* Create arguments. - */ -im_argument_t * -im_argument_new( const char *name, im_type_t *type, im_argument_flags flags ) -{ - im_argument_t *argument; - - if( !(argument = IM_NEW( NULL, im_argument_t )) ) - return( NULL ); - argument->name = name; - argument->type = type; - argument->flags = flags; - - return( argument ); -} - -void -im_argument_free( im_argument_t *argument ) -{ - im_free( argument ); -} - -/* Register/iterate/lookup operations. - */ -void -im_operation_unregister( im_operation_t *operation ) -{ - int i; - - g_hash_table_remove( im_operation_table, operation->name ); - for( i = 0; i < operation->argc; i++ ) - IM_FREEF( im_argument_free, operation->argv[i] ); - IM_FREE( operation ); -} - -im_operation_t * -im_operation_register( const char *name, const char *desc, - im_operation_flags flags, im_operation_dispatch_fn disp, int argc ) -{ - im_operation_t *operation; - - if( im_operation_lookup( name ) ) { - im_error( "im_operation_register", - _( "operation name already registered" ) ); - return( NULL ); - } - - if( !(operation = IM_NEW( NULL, im_operation_t )) ) - return( NULL ); - operation->name = name; - operation->desc = desc; - operation->flags = flags; - operation->disp = disp; - operation->argc = argc; - operation->argv = NULL; - - if( !(operation->argv = IM_ARRAY( NULL, argc, im_argument_t * )) ) { - im_operation_unregister( operation ); - return( NULL ); - } - memset( operation->argv, 0, argc * sizeof( im_argument_t * ) ); - - if( !im_operation_table ) - im_operation_table = g_hash_table_new( - g_str_hash, g_str_equal ); - g_hash_table_insert( im_operation_table, (char *) name, operation ); - - return( operation ); -} - -im_operation_t * -im_operation_registerv( const char *name, const char *desc, - im_operation_flags flags, im_operation_dispatch_fn disp, ... ) -{ - im_operation_t *operation; - im_argument_t *argument; - va_list ap; - int argc; - int i; - - va_start( ap, disp ); - for( argc = 0; va_arg( ap, im_argument_t * ); argc++ ) - ; - va_end( ap ); - - operation = im_operation_register( name, desc, flags, disp, argc ); - va_start( ap, disp ); - for( i = 0; (argument = va_arg( ap, im_argument_t * )); i++ ) - operation->argv[i] = argument; - va_end( ap ); - - return( operation ); -} - -void * -im_operation_map( VSListMap2Fn fn, void *a, void *b ) -{ - return( im_hash_table_map( im_operation_table, fn, a, b ) ); -} - -im_operation_t * -im_operation_lookup( const char *name ) -{ - return( (im_operation_t *) - g_hash_table_lookup( im_operation_table, name ) ); -} - -static int -add_vec( im_value_t **argv ) -{ - return( im_add( argv[0], argv[1], argv[2] ) ); -} - -/* Make a sample operation. - */ -void -im__operation_init( void ) -{ - im_operation_registerv( "im_add", _( "add two images" ), - IM_FN_PIO | IM_FN_PTOP, - add_vec, - im_argument_new( "in1", IM_TYPE_IM, 0 ), - im_argument_new( "in2", IM_TYPE_IM, 0 ), - im_argument_new( "out", IM_TYPE_IM, IM_ARGUMENT_OUTPUT ), - NULL ); -} diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 28c3c80a..873808e3 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1391,3 +1391,89 @@ vips__token_need( const char *p, VipsToken need_token, return( p ); } + +/* Test for file exists. + */ +int +im_existsf( const char *name, ... ) +{ + va_list ap; + char buf1[PATH_MAX]; + + va_start( ap, name ); + (void) im_vsnprintf( buf1, PATH_MAX - 1, name, ap ); + va_end( ap ); + + /* Try that. + */ + if( !access( buf1, R_OK ) ) + return( 1 ); + + return( 0 ); +} + +/* True if an int is a power of two ... 1, 2, 4, 8, 16, 32, etc. Do with just + * integer arithmetic for portability. A previous Nicos version using doubles + * and log/log failed on x86 with rounding problems. Return 0 for not + * power of two, otherwise return the position of the set bit (numbering with + * bit 1 as the lsb). + */ +int +im_ispoweroftwo( int p ) +{ + int i, n; + + /* Count set bits. Could use a LUT, I guess. + */ + for( i = 0, n = 0; p; i++, p >>= 1 ) + if( p & 1 ) + n++; + + /* Should be just one set bit. + */ + if( n == 1 ) + /* Return position of bit. + */ + return( i ); + 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 ); +} + +/* Test this processor for endianness. True for SPARC order. + */ +int +im_amiMSBfirst( void ) +{ + int test; + unsigned char *p = (unsigned char *) &test; + + test = 0; + p[0] = 255; + + if( test == 255 ) + return( 0 ); + else + return( 1 ); +} +