diff --git a/libvips/include/vips/debug.h b/libvips/include/vips/debug.h index 808edbf9..14fdea21 100644 --- a/libvips/include/vips/debug.h +++ b/libvips/include/vips/debug.h @@ -66,9 +66,6 @@ extern "C" { G_STMT_START { ; } G_STMT_END #endif /*VIPS_DEBUG_GREEN*/ -int im_image_sanity( VipsImage *im ); -void im_image_sanity_all( void ); - #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index e1ea346b..07f8a31e 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -196,8 +196,6 @@ int im__munmap( void *start, size_t length ); int im__write( int, const void *, size_t ); void im__change_suffix( const char *name, char *out, int mx, const char *new_suff, const char **olds, int nolds ); -void im__print_all( void ); -void im__print_one( int ); int im__trigger_callbacks( GSList *cblist ); int im__close( VipsImage * ); int im__fft_sp( float *rvec, float *ivec, int logrows, int logcols ); diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index 2d1f22f3..949970ab 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -212,6 +212,11 @@ struct _VipsObjectClass { */ void (*print)( VipsObject *, VipsBuf * ); + /* Sanity-check the object. Print messages and stuff. + * Handy for debugging. + */ + void (*sanity)( VipsObject *, VipsBuf * ); + /* Just before close, everything is still alive. */ void (*preclose)( VipsObject * ); @@ -252,6 +257,7 @@ void vips_object_preclose( VipsObject *object ); int vips_object_build( VipsObject *object ); void vips_object_print_class( VipsObjectClass *klass ); void vips_object_print( VipsObject *object ); +gboolean vips_object_sanity( VipsObject *object ); GType vips_object_get_type( void ); @@ -283,6 +289,9 @@ void vips_object_local_cb( VipsObject *vobject, GObject *gobject ); g_signal_connect( V, "close", \ G_CALLBACK( vips_object_local_cb ), G ); +void vips_object_print_all( void ); +void vips_object_sanity_all( void ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index e73194b7..a35a8663 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -189,6 +189,10 @@ extern "C" { #define im__region_no_ownership vips__region_no_ownership +#define im_image_sanity( I ) (!vips_object_sanity( VIPS_OBJECT( I ) )) +#define im_image_sanity_all vips_object_sanity_all +#define im__print_all vips_object_print_all + /* Compat functions. */ diff --git a/libvips/iofuncs/Makefile.am b/libvips/iofuncs/Makefile.am index 988c2e30..528f5034 100644 --- a/libvips/iofuncs/Makefile.am +++ b/libvips/iofuncs/Makefile.am @@ -6,7 +6,6 @@ libiofuncs_la_SOURCES = \ meta.c \ base64.h \ base64.c \ - debug.c \ dispatch_types.c \ error.c \ image.c \ diff --git a/libvips/iofuncs/check.c b/libvips/iofuncs/check.c index a6ee2a48..8027d2a8 100644 --- a/libvips/iofuncs/check.c +++ b/libvips/iofuncs/check.c @@ -175,7 +175,7 @@ convert_otom( IMAGE *im ) int im_incheck( IMAGE *im ) { - g_assert( !im_image_sanity( im ) ); + g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); #ifdef DEBUG_IO printf( "im_incheck: old-style input for %s\n", im->filename ); @@ -407,7 +407,7 @@ im_rwcheck( IMAGE *im ) int im_pincheck( IMAGE *im ) { - g_assert( !im_image_sanity( im ) ); + g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); #ifdef DEBUG_IO printf( "im_pincheck: enabling partial input for %s\n", im->filename ); diff --git a/libvips/iofuncs/debug.c b/libvips/iofuncs/debug.c deleted file mode 100644 index 2bd066e2..00000000 --- a/libvips/iofuncs/debug.c +++ /dev/null @@ -1,73 +0,0 @@ -/* debug.c: support for debugging - * - * 24/10/95 JC - * - first version - * 24/2/05 - * - print more mem allocation info - * 2/10/09 - * - im_image_sanity() moved here - * - im_printdesc() moved here - * 5/3/11 - * - vips8 rewrite - */ - -/* - - 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 -#include - -#ifdef WITH_DMALLOC -#include -#endif /*WITH_DMALLOC*/ - -/* Print something about all current objects. - */ -void -im__print_all( void ) -{ - vips_object_map( (VSListMap2Fn) vips_object_print, NULL, NULL ); -} - -int -im_image_sanity( IMAGE *im ) -{ - return( 0 ); -} - -void -im_image_sanity_all( void ) -{ -} diff --git a/libvips/iofuncs/im_generate.c b/libvips/iofuncs/im_generate.c index 7745ed1f..76075065 100644 --- a/libvips/iofuncs/im_generate.c +++ b/libvips/iofuncs/im_generate.c @@ -362,7 +362,7 @@ im_generate( IMAGE *im, { int res; - g_assert( !im_image_sanity( im ) ); + g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); if( !im->hint_set ) { vips_error( "im_generate", diff --git a/libvips/iofuncs/im_histlin.c b/libvips/iofuncs/im_histlin.c index b108e5bf..2184e869 100644 --- a/libvips/iofuncs/im_histlin.c +++ b/libvips/iofuncs/im_histlin.c @@ -150,9 +150,8 @@ im_updatehist( IMAGE *out, const char *name, int argc, char *argv[] ) { int i; char txt[IM_MAX_LINE]; - VipsBuf buf; + VipsBuf buf = VIPS_BUF_STATIC( txt ); - vips_buf_init_static( &buf, txt, IM_MAX_LINE ); vips_buf_appends( &buf, name ); for( i = 0; i < argc; i++ ) { diff --git a/libvips/iofuncs/im_setupout.c b/libvips/iofuncs/im_setupout.c index fe250402..90034f08 100644 --- a/libvips/iofuncs/im_setupout.c +++ b/libvips/iofuncs/im_setupout.c @@ -88,7 +88,7 @@ int im_setupout( IMAGE *im ) { - g_assert( !im_image_sanity( im ) ); + g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) { vips_error( "im_setupout", diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index e2becca0..40ed606f 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -31,8 +31,8 @@ */ /* - */ #define VIPS_DEBUG + */ #ifdef HAVE_CONFIG_H #include @@ -448,6 +448,64 @@ vips_image_print( VipsObject *object, VipsBuf *buf ) VIPS_OBJECT_CLASS( vips_image_parent_class )->print( object, buf ); } +static void * +vips_image_sanity_upstream( VipsImage *im_up, VipsImage *im_down ) +{ + if( !g_slist_find( im_up->downstream, im_down ) || + !g_slist_find( im_down->upstream, im_up ) ) + return( im_up ); + + return( NULL ); +} + +static void * +vips_image_sanity_downstream( VipsImage *im_down, VipsImage *im_up ) +{ + return( vips_image_sanity_upstream( im_up, im_down ) ); +} + +static void +vips_image_sanity( VipsObject *object, VipsBuf *buf ) +{ + VipsImage *image = VIPS_IMAGE( object ); + + if( !image->filename ) + vips_buf_appends( buf, "NULL filename\n" ); + + /* All -1 means im has been inited but never used. + */ + if( image->Xsize != -1 || + image->Ysize != -1 || + image->Bands != -1 || + image->BandFmt != -1 ) { + if( image->Xsize <= 0 || + image->Ysize <= 0 || + image->Bands <= 0 ) + vips_buf_appends( buf, "bad dimensions\n" ); + if( image->BandFmt < -1 || + image->BandFmt > VIPS_FORMAT_DPCOMPLEX || + (image->Coding != -1 && + image->Coding != VIPS_CODING_NONE && + image->Coding != VIPS_CODING_LABQ && + image->Coding != VIPS_CODING_RAD) || + image->Type > VIPS_INTERPRETATION_GREY16 || + image->dtype > VIPS_IMAGE_PARTIAL || + image->dhint > VIPS_DEMAND_STYLE_ANY ) + vips_buf_appends( buf, "bad enum\n" ); + if( image->Xres < 0 || image->Xres < 0 ) + vips_buf_appends( buf, "bad resolution\n" ); + } + + if( im_slist_map2( image->upstream, + (VSListMap2Fn) vips_image_sanity_upstream, image, NULL ) ) + vips_buf_appends( buf, "upstream broken\n" ); + if( im_slist_map2( image->downstream, + (VSListMap2Fn) vips_image_sanity_downstream, image, NULL ) ) + vips_buf_appends( buf, "downstream broken\n" ); + + VIPS_OBJECT_CLASS( vips_image_parent_class )->sanity( object, buf ); +} + static gboolean vips_format_is_vips( VipsFormatClass *format ) { @@ -983,6 +1041,7 @@ vips_image_class_init( VipsImageClass *class ) vobject_class->description = _( "VIPS image class" ); vobject_class->print = vips_image_print; + vobject_class->sanity = vips_image_sanity; vobject_class->build = vips_image_build; class->invalidate = vips_image_real_invalidate; @@ -1286,7 +1345,8 @@ vips_image_preeval( VipsImage *image ) vips_object_print( VIPS_OBJECT( image ) ); #endif /*VIPS_DEBUG*/ - g_assert( !im_image_sanity( image->progress ) ); + g_assert( vips_object_sanity( + VIPS_OBJECT( image->progress ) ) ); (void) vips_progress_add( image->progress ); @@ -1309,7 +1369,8 @@ vips_image_eval( VipsImage *image, int w, int h ) vips_object_print( VIPS_OBJECT( image ) ); #endif /*VIPS_DEBUG*/ - g_assert( !im_image_sanity( image->progress ) ); + g_assert( vips_object_sanity( + VIPS_OBJECT( image->progress ) ) ); progress->run = g_timer_elapsed( progress->start, NULL ); progress->npels += w * h; @@ -1333,7 +1394,8 @@ vips_image_posteval( VipsImage *image ) vips_object_print( VIPS_OBJECT( image ) ); #endif /*VIPS_DEBUG*/ - g_assert( !im_image_sanity( image->progress ) ); + g_assert( vips_object_sanity( + VIPS_OBJECT( image->progress ) ) ); g_signal_emit( image->progress, vips_image_signals[SIG_POSTEVAL], 0, image->time ); diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 994f8a8c..dc6dd8f3 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -30,10 +30,10 @@ */ /* - */ #define DEBUG #define VIPS_DEBUG #define DEBUG_REF + */ #ifdef HAVE_CONFIG_H #include @@ -136,10 +136,9 @@ vips_object_build( VipsObject *object ) void vips_object_print_class( VipsObjectClass *class ) { - VipsBuf buf; char str[1000]; + VipsBuf buf = VIPS_BUF_STATIC( str ); - vips_buf_init_static( &buf, str, 1000 ); class->print_class( class, &buf ); printf( "%s\n", vips_buf_all( &buf ) ); } @@ -148,15 +147,31 @@ void vips_object_print( VipsObject *object ) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); - VipsBuf buf; char str[1000]; + VipsBuf buf = VIPS_BUF_STATIC( str ); vips_object_print_class( class ); - vips_buf_init_static( &buf, str, 1000 ); class->print( object, &buf ); printf( "%s\n", vips_buf_all( &buf ) ); } +gboolean +vips_object_sanity( VipsObject *object ) +{ + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); + char str[1000]; + VipsBuf buf = VIPS_BUF_STATIC( str ); + + class->sanity( object, &buf ); + if( !vips_buf_is_empty( &buf ) ) { + printf( "sanity failure: " ); + vips_object_print( object ); + printf( "%s\n", vips_buf_all( &buf ) ); + } + + return( TRUE ); +} + /* Extra stuff we track for properties to do our argument handling. */ @@ -772,6 +787,11 @@ vips_object_real_print( VipsObject *object, VipsBuf *buf ) vips_buf_appendf( buf, " (%p)", object ); } +static void +vips_object_real_sanity( VipsObject *object, VipsBuf *buf ) +{ +} + static void transform_string_double( const GValue *src_value, GValue *dest_value ) { @@ -798,6 +818,7 @@ vips_object_class_init( VipsObjectClass *class ) class->build = vips_object_real_build; class->print_class = vips_object_real_print_class; class->print = vips_object_real_print; + class->sanity = vips_object_real_sanity; class->nickname = "object"; class->description = _( "VIPS base class" ); @@ -1195,3 +1216,31 @@ vips_object_unref( VipsObject *obj ) return( 0 ); } + +static void * +vips_object_print_all_cb( VipsObject *object ) +{ + vips_object_print( object ); + + return( NULL ); +} + +void +vips_object_print_all( void ) +{ + vips_object_map( (VSListMap2Fn) vips_object_print_all_cb, NULL, NULL ); +} + +static void * +vips_object_sanity_all_cb( VipsObject *object ) +{ + (void) vips_object_sanity( object ); + + return( NULL ); +} + +void +vips_object_sanity_all( void ) +{ + vips_object_map( (VSListMap2Fn) vips_object_sanity_all_cb, NULL, NULL ); +} diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index b02f2089..ea383967 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -70,11 +70,11 @@ */ /* - */ #define DEBUG_MOVE #define DEBUG_ENVIRONMENT 1 #define DEBUG_CREATE #define DEBUG + */ #ifdef HAVE_CONFIG_H #include diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index 7ae86db3..84762b8e 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -338,7 +338,7 @@ vips_sink_tile( VipsImage *im, Sink sink; int result; - g_assert( !im_image_sanity( im ) ); + g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); /* We don't use this, but make sure it's set in case any old binaries * are expecting it. diff --git a/libvips/iofuncs/sinkmemory.c b/libvips/iofuncs/sinkmemory.c index ca8c89a2..56964e67 100644 --- a/libvips/iofuncs/sinkmemory.c +++ b/libvips/iofuncs/sinkmemory.c @@ -190,7 +190,7 @@ vips_sink_memory( VipsImage *im ) Sink sink; int result; - g_assert( !im_image_sanity( im ) ); + g_assert( vips_object_sanity( VIPS_OBJECT( im ) ) ); /* We don't use this, but make sure it's set in case any old binaries * are expecting it.