From 241187146f1ceda34cc27e0b5b4ee8ec33504c47 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 Feb 2011 18:07:09 +0000 Subject: [PATCH] debug.c makes it by removing most of it, argh. add _sanity() as an object mthod. --- TODO | 2 + libvips/include/vips/util.h | 7 + libvips/iofuncs/debug.c | 468 ++---------------------------------- 3 files changed, 31 insertions(+), 446 deletions(-) diff --git a/TODO b/TODO index 371e3da9..58cb460b 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,7 @@ - image->progress needs renaming, perhaps image->progress_signal? +- im_sanity() should become a method on VipsObject, see debug.c + - pre/post/close should be on VipsObject, not VipsImage diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 1da73ea1..bddf08f7 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -155,6 +155,13 @@ G_STMT_START { \ #define VIPS_ENUM_NICK( ENUM, VALUE ) \ (g_enum_get_value( g_type_class_ref( ENUM ), VALUE )->value_nick) +/* Given a string, look up the value. Look up as a nick first, then try as a + * name. + */ +#define VIPS_ENUM_VALUE( ENUM, STR ) \ + (g_enum_get_value_by_nick( g_type_class_ref( ENUM ), STR ) || \ + g_enum_get_value_by_name( g_type_class_ref( ENUM ), STR )) + /* strtok replacement. */ char *im__break_token( char *str, char *brk ); diff --git a/libvips/iofuncs/debug.c b/libvips/iofuncs/debug.c index e2788960..ded31415 100644 --- a/libvips/iofuncs/debug.c +++ b/libvips/iofuncs/debug.c @@ -45,481 +45,57 @@ #include #include -#include -#include +#include #ifdef WITH_DMALLOC #include #endif /*WITH_DMALLOC*/ -/* Track all open images in this. - */ -GSList *im__open_images = NULL; - -static const char *im_Type[] = { - "IM_TYPE_MULTIBAND", /* 0 */ - "IM_TYPE_B_W", /* 1 */ - "LUMINACE", /* 2 */ - "XRAY", /* 3 */ - "IR", /* 4 */ - "YUV", /* 5 */ - "RED_ONLY", /* 6 */ - "GREEN_ONLY", /* 7 */ - "BLUE_ONLY", /* 8 */ - "POWER_SPECTRUM", /* 9 */ - "IM_TYPE_HISTOGRAM", /* 10 */ - "LUT", /* 11 */ - "IM_TYPE_XYZ", /* 12 */ - "IM_TYPE_LAB", /* 13 */ - "CMC", /* 14 */ - "IM_TYPE_CMYK", /* 15 */ - "IM_TYPE_LABQ", /* 15 */ - "IM_TYPE_RGB", /* 17 */ - "IM_TYPE_UCS", /* 18 */ - "IM_TYPE_LCH", /* 19 */ - "IM_TYPE_LABS", /* 20 */ - "", /* 21 */ - "IM_TYPE_sRGB", /* 22 */ - "IM_TYPE_YXY", /* 23 */ - "IM_TYPE_FOURIER", /* 24 */ - "IM_TYPE_RGB16", /* 25 */ - "IM_TYPE_GREY16" /* 26 */ -}; - -static const char *im_BandFmt[] = { - "IM_BANDFMT_UCHAR", - "IM_BANDFMT_CHAR", - "IM_BANDFMT_USHORT", - "IM_BANDFMT_SHORT", - "IM_BANDFMT_UINT", - "IM_BANDFMT_INT", - "IM_BANDFMT_FLOAT", - "IM_BANDFMT_COMPLEX", - "IM_BANDFMT_DOUBLE", - "IM_BANDFMT_DPCOMPLEX" -}; - -static const char *im_Coding[] = { - "IM_CODING_NONE", - "COLQUANT8", - "IM_CODING_LABQ", - "IM_CODING_LABQ_COMPRESSED", - "RGB_COMPRESSED", - "LUM_COMPRESSED", - "IM_CODING_RAD" -}; - -static const char *im_Compression[] = { - "NO_COMPRESSION", - "TCSF_COMPRESSION", - "JPEG_COMPRESSION" -}; - -static const char *im_dtype[] = { - "IM_NONE", - "IM_SETBUF", - "IM_SETBUF_FOREIGN", - "IM_OPENIN", - "IM_MMAPIN", - "IM_MMAPINRW", - "IM_OPENOUT", - "IM_PARTIAL" -}; - -static const char *im_dhint[] = { - "IM_SMALLTILE", - "IM_FATSTRIP", - "IM_THINSTRIP", - "IM_ANY" -}; - -/* Stuff to decode an enum. - */ -typedef struct _EnumTable { - const char *error; /* eg. "" */ - const char **names; /* eg. {"IM_CODING_NONE",..} */ - int nnames; -} EnumTable; - -static EnumTable enumType = { - N_( "" ), - im_Type, - VIPS_NUMBER( im_Type ) -}; - -static EnumTable enumBandFmt = { - N_( "" ), - im_BandFmt, - VIPS_NUMBER( im_BandFmt ) -}; - -static EnumTable enumCoding = { - N_( "" ), - im_Coding, - VIPS_NUMBER( im_Coding ) -}; - -static EnumTable enumCompression = { - N_( "" ), - im_Compression, - VIPS_NUMBER( im_Compression ) -}; - -static EnumTable enumdtype = { - N_( "" ), - im_dtype, - VIPS_NUMBER( im_dtype ) -}; - -static EnumTable enumdhint = { - N_( "" ), - im_dhint, - VIPS_NUMBER( im_dhint ) -}; - -static const char * -enum2char( EnumTable *etable, int n ) -{ - if( n < 0 || n > etable->nnames ) - return( _( etable->error ) ); - else - return( etable->names[n] ); -} - -static int -char2enum( EnumTable *etable, const char *name ) -{ - int i; - - for( i = 0; i < etable->nnames; i++ ) - if( g_ascii_strcasecmp( etable->names[i], name ) == 0 ) - return( i ); - - vips_error( "char2enum", "%s", _( etable->error ) ); - - return( -1 ); -} - -/* Prettyprint various header fields. +/* Prettyprint various header fields. Just for vips7 compat, use + * VIPS_ENUM_VALUE() instead. */ const char *im_Type2char( VipsInterpretation type ) - { return( enum2char( &enumType, type ) ); } -const char *im_BandFmt2char( VipsBandFmt fmt ) - { return( enum2char( &enumBandFmt, fmt ) ); } + { return( VIPS_ENUM_STRING( VIPS_TYPE_INTERPRETATION, type ) ); } +const char *im_BandFmt2char( VipsBandFormat format ) + { return( VIPS_ENUM_STRING( VIPS_TYPE_BAND_FORMAT, format ) ); } const char *im_Coding2char( VipsCoding coding ) - { return( enum2char( &enumCoding, coding ) ); } -const char *im_Compression2char( int n ) - { return( enum2char( &enumCompression, n ) ); } -const char *im_dtype2char( im_desc_type n ) - { return( enum2char( &enumdtype, n ) ); } + { return( VIPS_ENUM_STRING( VIPS_TYPE_CODING, coding ) ); } +const char *im_dtype2char( VipsImageType n ) + { return( VIPS_ENUM_STRING( VIPS_TYPE_IMAGE_TYPE, n ) ); } const char *im_dhint2char( VipsDemandStyle style ) - { return( enum2char( &enumdhint, style ) ); } + { return( VIPS_ENUM_STRING( VIPS_TYPE_DEMAND_STYLE, style ) ); } int im_char2Type( const char *str ) - { return( char2enum( &enumType, str ) ); } + { return( VIPS_ENUM_VALUE( VIPS_TYPE_INTERPRETATION, str ) ); } int im_char2BandFmt( const char *str ) - { return( char2enum( &enumBandFmt, str ) ); } + { return( VIPS_ENUM_VALUE( VIPS_TYPE_BAND_FORMAT, str ) ); } int im_char2Coding( const char *str ) - { return( char2enum( &enumCoding, str ) ); } -int im_char2Compression( const char *str ) - { return( char2enum( &enumCompression, str ) ); } -im_desc_type im_char2dtype( const char *str ) - { return( char2enum( &enumdtype, str ) ); } -im_demand_type im_char2dhint( const char *str ) - { return( char2enum( &enumdhint, str ) ); } + { return( VIPS_ENUM_VALUE( VIPS_TYPE_CODING, str ) ); } +int im_char2dtype( const char *str ) + { return( VIPS_ENUM_VALUE( VIPS_TYPE_IMAGE_TYPE, str ) ); } +int im_char2dhint( const char *str ) + { return( VIPS_ENUM_VALUE( VIPS_TYPE_DEMAND_STYLE, str ) ); } -static void * -add_unique( REGION *r, gint64 *total, GSList **seen ) -{ - if( r->type == IM_REGION_BUFFER && - r->buffer && - !g_slist_find( *seen, r->buffer ) ) { - *seen = g_slist_prepend( *seen, r->buffer ); - *total += r->buffer->bsize; - } - - return( NULL ); -} - -/* Print a one-line description of an image, with an index. +/* Totally useless now. */ -static void * -print_one_line( IMAGE *im, int *n, gint64 *total ) -{ - gint64 size; +const char *im_Compression2char( int n ) { return( "NONE" ); } +int im_char2Compression( const char *str ) { return( -1 ); } - printf( "%d, %p, %s, %s, %d, %d, %d, %s, ", - *n, - im, - im_dtype2char( im->dtype ), - im->filename, - im->Xsize, im->Ysize, im->Bands, - im_BandFmt2char( im->BandFmt ) ); - *n += 1; - - size = 0; - if( im->dtype == IM_SETBUF && im->data ) { - size = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize; - } - *total += size; - printf( "%" G_GINT64_FORMAT ", ", size ); - - printf( "%d, ", g_slist_length( im->regions ) ); - - size = 0; - if( im->regions ) { - GSList *seen; - - seen = NULL; - (void) im_slist_map2( im->regions, - (VSListMap2Fn) add_unique, &size, &seen ); - g_slist_free( seen ); - } - *total += size; - printf( "%" G_GINT64_FORMAT "\n", size ); - - return( NULL ); -} - -static void * -add_virtual( IMAGE *im, gint64 *total, void *dummy ) -{ - *total += im__image_pixel_length( im ); - - return( NULL ); -} - -/* Print one line for each open descriptor. +/* Print something about all current objects. */ void im__print_all( void ) { - if( im__open_images ) { - int n; - gint64 total; - - n = 0; - total = 0; - printf( "n, p, dtype, file, xsize, ysize, bands, fmt, " ); - printf( "isize, nreg, rsize\n" ); - (void) im_slist_map2( im__open_images, - (VSListMap2Fn) print_one_line, &n, &total ); - if( total ) - printf( "\n\t*** all-image total = %" G_GINT64_FORMAT - " real bytes\n", - total ); - - total = 0; - (void) im_slist_map2( im__open_images, - (VSListMap2Fn) add_virtual, &total, NULL ); - if( total ) - printf( "\n\t*** virtual total = %" G_GINT64_FORMAT - " bytes\n", - total ); - } - - im__print_renders(); -} - -static void * -print_field_fn( IMAGE *im, const char *field, GValue *value ) -{ - const char *extra; - char *str_value; - - str_value = g_strdup_value_contents( value ); - printf( "%s: %s", field, str_value ); - g_free( str_value ); - - /* Replace NULL static strings with "(null)". - */ -#define NN( X ) ((X) ? (X) : "(null)") - - /* Look for known enums and decode them. - */ - extra = NULL; - if( strcmp( field, "Coding" ) == 0 ) - extra = NN( im_Coding2char( g_value_get_int( value ) ) ); - else if( strcmp( field, "BandFmt" ) == 0 ) - extra = NN( im_BandFmt2char( g_value_get_int( value ) ) ); - else if( strcmp( field, "Type" ) == 0 ) - extra = NN( im_Type2char( g_value_get_int( value ) ) ); - else if( strcmp( field, "Compression" ) == 0 ) - extra = NN( im_Compression2char( g_value_get_int( value ) ) ); - - if( extra ) - printf( " - %s", extra ); - - printf( "\n" ); - - return( NULL ); -} - -static void * -print_region( REGION *reg, void *a, void *b ) -{ - printf( "Region defined for area at %dx%d size %dx%d\n", - reg->valid.left, reg->valid.top, - reg->valid.width, reg->valid.height ); - if( reg->seq ) - printf( "sequence in progress on region\n" ); - if( reg->buffer ) - printf( "local memory allocated\n" ); - - return( NULL ); -} - -void -im_printdesc( IMAGE *image ) -{ - if( !image ) { - printf( "NULL descriptor\n" ); - return; - } - - printf( "IMAGE* %p\n", image ); - - if( im_isMSBfirst( image ) ) - printf( "SPARC (MSB first) " ); - else - printf( "Intel (LSB first) " ); - printf( "byte order image, on a " ); - if( im_amiMSBfirst() ) - printf( "SPARC (MSB first) " ); - else - printf( "Intel (LSB first) " ); - printf( "byte order machine\n" ); - - (void) im_header_map( image, (im_header_map_fn) print_field_fn, NULL ); - - printf( "Hist: %s", im_history_get( image ) ); - - /* Print other (non-header) fields. - */ - if( image->generate ) - printf( "generate function attached\n" ); - if( image->regions ) { - printf( "%d regions present\n", - g_slist_length( image->regions ) ); - im_slist_map2( image->regions, - (VSListMap2Fn) print_region, NULL, NULL ); - } - if( image->kill ) - printf( "kill flag set\n" ); - if( image->closing ) - printf( "closing flag set\n" ); - if( image->close_pending ) - printf( "close_pending flag set\n" ); - -#ifdef DEBUG - /* Can't get these with im_header_get(), so only show for debugging. - */ - printf( "dhint: %s\n", im_dhint2char( image->dhint ) ); - printf( "dtype: %s\n", im_dtype2char( image->dtype ) ); -#endif /*DEBUG*/ -} - -/* Debugging: given an index, print everything we know about that descriptor. - */ -void -im__print_one( int n ) -{ - IMAGE *im = g_slist_nth_data( im__open_images, n ); - - if( !im ) { - printf( "bad index: %d\n", n ); - return; - } - - im_printdesc( im ); -} - -static void * -sanity_upstream( IMAGE *im_up, IMAGE *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 * -sanity_downstream( IMAGE *im_down, IMAGE *im_up ) -{ - return( sanity_upstream( im_up, im_down ) ); -} - -/* Test an image for sanity. We could add many more tests here. - */ -static const char * -image_sanity( IMAGE *im ) -{ - if( !im ) - return( "NULL descriptor" ); - if( !im->filename ) - return( "NULL filename" ); - - g_mutex_lock( im__global_lock ); - if( !g_slist_find( im__open_images, im ) ) { - g_mutex_unlock( im__global_lock ); - return( "not on open image list" ); - } - g_mutex_unlock( im__global_lock ); - - /* All -1 means im has been inited but never used. - */ - if( im->Xsize != -1 || - im->Ysize != -1 || - im->Bands != -1 || - im->BandFmt != -1 ) { - if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) - return( "bad dimensions" ); - if( im->BandFmt < -1 || im->BandFmt > IM_BANDFMT_DPCOMPLEX || - (im->Coding != -1 && - im->Coding != IM_CODING_NONE && - im->Coding != IM_CODING_LABQ && - im->Coding != IM_CODING_RAD) || - im->Type > IM_TYPE_GREY16 ) - return( "bad enum value" ); - if( im->dtype > IM_PARTIAL || - im->dhint > IM_ANY ) - return( "bad enum value" ); - if( im->Xres < 0 || im->Xres < 0 ) - return( "bad resolution" ); - } - - if( im_slist_map2( im->upstream, - (VSListMap2Fn) sanity_upstream, im, NULL ) ) - return( "upstream broken" ); - if( im_slist_map2( im->downstream, - (VSListMap2Fn) sanity_downstream, im, NULL ) ) - return( "downstream broken" ); - - return( NULL ); + vips_object_map( (VSListMap2Fn) vips_object_print, NULL, NULL ); } int im_image_sanity( IMAGE *im ) { - const char *msg; - - if( (msg = image_sanity( im )) ) { - im_warn( "im_image_sanity", "%p", im ); - im_warn( "im_image_sanity", "\"%s\" %s", - im ? (im->filename ? im->filename : "") : "", - msg ); - im_printdesc( im ); - - return( -1 ); - } - return( 0 ); } void im_image_sanity_all( void ) { - g_assert( im_slist_map2( im__open_images, - (VSListMap2Fn) im_image_sanity, NULL, NULL ) == 0 ); }