From 1ef32179dafea446ad5b1965ebcfbac5a16ff6d3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 6 Aug 2013 11:43:41 +0100 Subject: [PATCH 1/4] lock on area tracking --- libvips/iofuncs/type.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 84ecf351..00fe374d 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -37,9 +37,9 @@ */ /* + */ #define VIPS_DEBUG #define DEBUG - */ #ifdef HAVE_CONFIG_H #include @@ -150,7 +150,7 @@ vips_area_copy( VipsArea *area ) { g_mutex_lock( area->lock ); - g_assert( area->count >= 0 ); + g_assert( area->count > 0 ); area->count += 1; @@ -192,12 +192,17 @@ vips_area_unref( VipsArea *area ) g_free( area ); - if( vips__leak ) + if( vips__leak ) { + g_mutex_lock( vips__global_lock ); vips_area_all = g_slist_remove( vips_area_all, area ); + g_mutex_unlock( vips__global_lock ); + } #ifdef DEBUG + g_mutex_lock( vips__global_lock ); printf( "vips_area_unref: free .. total = %d\n", g_slist_length( vips_area_all ) ); + g_mutex_unlock( vips__global_lock ); #endif /*DEBUG*/ } else @@ -230,13 +235,18 @@ vips_area_new( VipsCallbackFn free_fn, void *data ) area->type = 0; area->sizeof_type = 0; - if( vips__leak ) + if( vips__leak ) { + g_mutex_lock( vips__global_lock ); vips_area_all = g_slist_prepend( vips_area_all, area ); + g_mutex_unlock( vips__global_lock ); + } #ifdef DEBUG + g_mutex_lock( vips__global_lock ); printf( "vips_area_new: %p count = %d (%d in total)\n", area, area->count, g_slist_length( vips_area_all ) ); + g_mutex_unlock( vips__global_lock ); #endif /*DEBUG*/ return( area ); From ba602022857fa5e342ded10a7306f8abb874420d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 6 Aug 2013 12:02:11 +0100 Subject: [PATCH 2/4] better type leak checks --- libvips/include/vips/internal.h | 4 +++ libvips/include/vips/type.h | 1 + libvips/iofuncs/init.c | 4 ++- libvips/iofuncs/type.c | 55 +++++++++++++++++++++++++++------ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 087eda39..fe94f108 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -75,6 +75,10 @@ extern int vips__fatal; */ extern int vips__progress; +/* Leak check on exit. + */ +extern int vips__leak; + /* A string giving the image size (in bytes of uncompressed image) above which * we decompress to disc on open. */ diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index 21da4807..1d6abb9b 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -91,6 +91,7 @@ typedef struct _VipsArea { VipsArea *vips_area_copy( VipsArea *area ); void vips_area_unref( VipsArea *area ); +void vips__type_leak( void ); VipsArea *vips_area_new( VipsCallbackFn free_fn, void *data ); VipsArea *vips_area_new_blob( VipsCallbackFn free_fn, diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 9954a224..a1467444 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -96,7 +96,7 @@ static char *vips__argv0 = NULL; /* Leak check on exit. */ -static int vips__leak = 0; +int vips__leak = 0; /** * vips_get_argv0: @@ -327,6 +327,8 @@ vips_leak( void ) vips_buf_appends( &buf, "\n" ); fprintf( stderr, "%s", vips_buf_all( &buf ) ); + + vips__type_leak(); } /** diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 59002656..c2303173 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -5,6 +5,8 @@ * * 27/10/11 * - from header.c + * 16/7/13 + * - leakcheck VipsArea */ /* @@ -35,9 +37,9 @@ */ /* + */ #define VIPS_DEBUG #define DEBUG - */ #ifdef HAVE_CONFIG_H #include @@ -141,16 +143,14 @@ vips_thing_get_type( void ) * strings. */ -#ifdef DEBUG -static int vips_area_number = 0; -#endif /*DEBUG*/ +static GSList *vips_area_all = NULL; VipsArea * vips_area_copy( VipsArea *area ) { g_mutex_lock( area->lock ); - g_assert( area->count >= 0 ); + g_assert( area->count > 0 ); area->count += 1; @@ -176,6 +176,12 @@ vips_area_unref( VipsArea *area ) printf( "vips_area_unref: %p count = %d\n", area, area->count ); #endif /*DEBUG*/ + if( vips__leak ) { + g_mutex_lock( vips__global_lock ); + g_assert( g_slist_find( vips_area_all, area ) ); + g_mutex_unlock( vips__global_lock ); + } + if( area->count == 0 ) { if( area->free_fn && area->data ) { area->free_fn( area->data, area ); @@ -189,10 +195,17 @@ vips_area_unref( VipsArea *area ) g_free( area ); + if( vips__leak ) { + g_mutex_lock( vips__global_lock ); + vips_area_all = g_slist_remove( vips_area_all, area ); + g_mutex_unlock( vips__global_lock ); + } + #ifdef DEBUG - vips_area_number -= 1; + g_mutex_lock( vips__global_lock ); printf( "vips_area_unref: free .. total = %d\n", - vips_area_number ); + g_slist_length( vips_area_all ) ); + g_mutex_unlock( vips__global_lock ); #endif /*DEBUG*/ } else @@ -225,15 +238,39 @@ vips_area_new( VipsCallbackFn free_fn, void *data ) area->type = 0; area->sizeof_type = 0; + if( vips__leak ) { + g_mutex_lock( vips__global_lock ); + vips_area_all = g_slist_prepend( vips_area_all, area ); + g_mutex_unlock( vips__global_lock ); + } + #ifdef DEBUG - vips_area_number += 1; + g_mutex_lock( vips__global_lock ); printf( "vips_area_new: %p count = %d (%d in total)\n", - area, area->count, vips_area_number ); + area, area->count, + g_slist_length( vips_area_all ) ); + g_mutex_unlock( vips__global_lock ); #endif /*DEBUG*/ return( area ); } +void +vips__type_leak( void ) +{ + if( vips_area_all ) { + GSList *p; + + printf( "VipsArea leaks:\n" ); + for( p = vips_area_all; p; p = p->next ) { + VipsArea *area = (VipsArea *) p->data; + + printf( "\t%p count = %d\n", area, area->count ); + } + printf( "%d in total\n", g_slist_length( vips_area_all ) ); + } +} + /** * vips_area_new_blob: * @free_fn: (scope async): @data will be freed with this function From 497cf55fc0bfad5d3030a9513472e3499946ccd1 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 6 Aug 2013 12:58:07 +0100 Subject: [PATCH 3/4] don't output transparency ifrom openslide openslide now always outputs solid colours, helps vips_flatten() convert to RGB for jpg tile save correctly --- libvips/foreign/openslide2vips.c | 16 ++++++++++++++-- libvips/iofuncs/type.c | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libvips/foreign/openslide2vips.c b/libvips/foreign/openslide2vips.c index 97afbb52..6baa62c1 100644 --- a/libvips/foreign/openslide2vips.c +++ b/libvips/foreign/openslide2vips.c @@ -37,6 +37,8 @@ * 11/10/12 * - look for tile-width and tile-height properties * - use threaded tile cache + * 6/8/13 + * - always output solid (not transparent) pixels */ /* @@ -259,6 +261,7 @@ readslide_new( const char *filename, VipsImage *out, return( NULL ); } + vips_image_init_fields( out, w, h, 4, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_RGB, 1.0, 1.0 ); @@ -331,6 +334,15 @@ vips__openslide_generate( VipsRegion *out, /* Convert from ARGB to RGBA and undo premultiplication. Since we are * inside a cache, we know buf must be continuous. + * + * We throw away transparency. Formats like Mirax use transparent + bg + * colour for areas with no useful pixels. But if we output + * transparent pixels and then convert to RGB for jpeg write later, we + * would have to pass the bg colour down the pipe somehow. The + * structure of dzsave makes this tricky. + * + * We could output plain RGB instead, but that would break + * compatibility with older vipses. */ for( i = 0; i < n; i++ ) { uint32_t *p = buf + i; @@ -342,7 +354,7 @@ vips__openslide_generate( VipsRegion *out, out[0] = 255 * ((x >> 16) & 255) / a; out[1] = 255 * ((x >> 8) & 255) / a; out[2] = 255 * (x & 255) / a; - out[3] = a; + out[3] = 255; } else { /* Use background color. @@ -350,7 +362,7 @@ vips__openslide_generate( VipsRegion *out, out[0] = (bg >> 16) & 255; out[1] = (bg >> 8) & 255; out[2] = bg & 255; - out[3] = 0; + out[3] = 255; } } diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index c2303173..7295778f 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -37,9 +37,9 @@ */ /* - */ #define VIPS_DEBUG #define DEBUG + */ #ifdef HAVE_CONFIG_H #include From 8a72c0742c604b9706d0924eca031aafc9141580 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 6 Aug 2013 13:00:59 +0100 Subject: [PATCH 4/4] oops --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index f3acde07..ccd18b73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - lower priority for Matlab load to reduce segvs from Mat_Open(), thanks Michael - null-terminate libexif strings, thanks Mike +- openslide always outputs solid pixels 28/6/13 started 7.34.1 - fix morphological operators on non-uchar images