diff --git a/libvips/conversion/extract.c b/libvips/conversion/extract.c index f3c6c68d..ebb3290c 100644 --- a/libvips/conversion/extract.c +++ b/libvips/conversion/extract.c @@ -137,7 +137,8 @@ vips_extract_area_build( VipsObject *object ) VipsConversion *conversion = VIPS_CONVERSION( object ); VipsExtractArea *extract = (VipsExtractArea *) object; - if( VIPS_OBJECT_CLASS( vips_extract_area_parent_class )->build( object ) ) + if( VIPS_OBJECT_CLASS( vips_extract_area_parent_class )-> + build( object ) ) return( -1 ); if( extract->left + extract->width > extract->in->Xsize || diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 1056a4f7..2df24ed5 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -45,8 +45,8 @@ */ /* -#define VIPS_DEBUG */ +#define VIPS_DEBUG #ifdef HAVE_CONFIG_H #include @@ -65,7 +65,7 @@ /* Stall threads that run ahead for this long, in seconds. */ -#define STALL_TIME (0.1) +#define STALL_TIME (1.0) typedef struct _VipsSequential { VipsConversion parent_instance; @@ -133,8 +133,9 @@ vips_sequential_generate( VipsRegion *or, return( -1 ); } - if( r->top > sequential->y_pos && - sequential->y_pos > 0 ) { + if( r->top > sequential->y_pos + //&& sequential->y_pos > 0 + ) { GTimeVal time; /* We have started reading (y_pos > 0) and this request is for @@ -145,8 +146,15 @@ vips_sequential_generate( VipsRegion *or, STALL_TIME, g_thread_self() ); g_get_current_time( &time ); g_time_val_add( &time, STALL_TIME * 1000000 ); - g_cond_timed_wait( sequential->ready, - sequential->lock, &time ); + + /* Exit the loop on timeout or condition passes. We have to + * be wary of spurious wakeups. + */ + while( r->top > sequential->y_pos ) + if( !g_cond_timed_wait( sequential->ready, + sequential->lock, &time ) ) + break; + VIPS_DEBUG_MSG( "thread %p awake again ...\n", g_thread_self() ); } diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index 0fce2bb0..f5a50d47 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -124,6 +124,7 @@ typedef struct { VipsImage *out; FILE *fp; + int y_pos; png_structp pPng; png_infop pInfo; png_bytep *row_pointer; @@ -149,6 +150,7 @@ read_new( const char *name, VipsImage *out ) read->name = vips_strdup( VIPS_OBJECT( out ), name ); read->out = out; read->fp = NULL; + read->y_pos = 0; read->pPng = NULL; read->pInfo = NULL; read->row_pointer = NULL; @@ -405,9 +407,9 @@ png2vips_generate( VipsRegion *or, int y; #ifdef DEBUG +#endif /*DEBUG*/ printf( "png2vips_generate: line %d, %d rows\n", r->top, r->height ); -#endif /*DEBUG*/ /* We're inside a tilecache where tiles are the full image width, so * this should always be true. @@ -421,10 +423,23 @@ png2vips_generate( VipsRegion *or, */ g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) ); + /* And check that y_pos is correct. It should be, since we are inside + * a vips_sequential(). + */ + if( r->top != read->y_pos ) { + printf( "png2vips_generate: y_pos == %d, top == %d\n", + read->y_pos, r->top ); + g_assert( r->top == read->y_pos ); + } + if( setjmp( png_jmpbuf( read->pPng ) ) ) { #ifdef DEBUG - printf( "png2vips_generate: failing in setjmp\n" ); #endif /*DEBUG*/ + printf( "png2vips_generate: failing in setjmp\n" ); + printf( "png2vips_generate: line %d, %d rows\n", + r->top, r->height ); + printf( "png2vips_generate: file %s\n", read->name ); + printf( "png2vips_generate: thread %p\n", g_thread_self() ); return( -1 ); } @@ -433,6 +448,8 @@ png2vips_generate( VipsRegion *or, png_bytep q = (png_bytep) VIPS_REGION_ADDR( or, 0, r->top + y ); png_read_row( read->pPng, q, NULL ); + + read->y_pos += 1; } return( 0 ); @@ -460,7 +477,7 @@ vips__png_isinterlaced( const char *filename ) } int -vips__png_read( const char *name, VipsImage *out ) +vips__png_read( const char *filename, VipsImage *out ) { VipsImage **t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( out ), 3 ); @@ -469,10 +486,10 @@ vips__png_read( const char *name, VipsImage *out ) int interlace_type; #ifdef DEBUG - printf( "png2vips: reading \"%s\"\n", name ); + printf( "vips__png_read: reading \"%s\"\n", filename ); #endif /*DEBUG*/ - if( !(read = read_new( name, out )) ) + if( !(read = read_new( filename, out )) ) return( -1 ); interlace_type = png_get_interlace_type( read->pPng, read->pInfo ); @@ -501,7 +518,7 @@ vips__png_read( const char *name, VipsImage *out ) } #ifdef DEBUG - printf( "png2vips: done\n" ); + printf( "vips__png_read: done\n" ); #endif /*DEBUG*/ return( 0 ); @@ -718,6 +735,10 @@ vips__png_write( VipsImage *in, const char *filename, { Write *write; +#ifdef DEBUG + printf( "vips__png_write: writing \"%s\"\n", filename ); +#endif /*DEBUG*/ + if( !(write = write_new( in )) ) return( -1 ); @@ -738,6 +759,10 @@ vips__png_write( VipsImage *in, const char *filename, write_finish( write ); +#ifdef DEBUG + printf( "vips__png_write: done\n" ); +#endif /*DEBUG*/ + return( 0 ); } diff --git a/libvips/resample/shrink.c b/libvips/resample/shrink.c index 698e0d6e..b504b906 100644 --- a/libvips/resample/shrink.c +++ b/libvips/resample/shrink.c @@ -63,8 +63,8 @@ */ /* -#define DEBUG */ +#define DEBUG #ifdef HAVE_CONFIG_H #include