diff --git a/ChangeLog b/ChangeLog index e5d90a26..70bf3200 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,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 diff --git a/libvips/foreign/openslide2vips.c b/libvips/foreign/openslide2vips.c index 3d86cb2c..a2a7760b 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 */ /* @@ -263,6 +265,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 ); @@ -335,6 +338,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; @@ -346,7 +358,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. @@ -354,7 +366,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/include/vips/internal.h b/libvips/include/vips/internal.h index 6638d35f..7ecb9973 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -79,6 +79,10 @@ extern int vips__leak; */ 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/type.c b/libvips/iofuncs/type.c index 84ecf351..c2303173 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; @@ -176,8 +176,11 @@ vips_area_unref( VipsArea *area ) printf( "vips_area_unref: %p count = %d\n", area, area->count ); #endif /*DEBUG*/ - if( vips__leak ) + 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 ) { @@ -192,12 +195,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 +238,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 );