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 );
+}
+