From b84bf6d4f4427b9b43485aac5ea5ae3875661fd8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 13 Nov 2018 17:29:36 +0000 Subject: [PATCH] check read order for strip tiffs double-check seq is working, related to https://github.com/libvips/libvips/issues/1158 --- libvips/foreign/tiff2vips.c | 24 ++++++++++++++++++++++-- libvips/foreign/tiffload.c | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index e73cd476..11546d5b 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -319,6 +319,10 @@ typedef struct _Rtiff { * strips or tiles interleaved. */ tdata_t contig_buf; + + /* The Y we are reading at. Used to verify strip read is sequential. + */ + int y_pos; } Rtiff; /* Test for field exists. @@ -492,6 +496,7 @@ rtiff_new( VipsImage *out, int page, int n, gboolean autorotate ) rtiff->memcpy = FALSE; rtiff->plane_buf = NULL; rtiff->contig_buf = NULL; + rtiff->y_pos = 0; g_signal_connect( out, "close", G_CALLBACK( rtiff_close_cb ), rtiff ); @@ -1825,8 +1830,9 @@ rtiff_stripwise_generate( VipsRegion *or, int y; #ifdef DEBUG - printf( "tiff2vips: read_stripwise_generate: top = %d, height = %d\n", + printf( "rtiff_stripwise_generate: top = %d, height = %d\n", r->top, r->height ); + printf( "rtiff_stripwise_generate: y_top = %d\n", rtiff->y_pos ); #endif /*DEBUG*/ /* We're inside a tilecache where tiles are the full image width, so @@ -1846,6 +1852,15 @@ rtiff_stripwise_generate( VipsRegion *or, g_assert( r->height == VIPS_MIN( rows_per_strip, 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 != rtiff->y_pos ) { + vips_error( "tiff2vips", + _( "out of order read at line %d" ), rtiff->y_pos ); + return( -1 ); + } + VIPS_GATE_START( "rtiff_stripwise_generate: work" ); y = 0; @@ -1943,12 +1958,17 @@ rtiff_stripwise_generate( VipsRegion *or, } y += hit.height; + rtiff->y_pos += hit.height; } /* Shut down the input file as soon as we can. */ - if( r->top + y >= or->im->Ysize ) + if( rtiff->y_pos >= or->im->Ysize ) { +#ifdef DEBUG + printf( "rtiff_stripwise_generate: early shutdown\n" ); +#endif /*DEBUG*/ rtiff_free( rtiff ); + } VIPS_GATE_STOP( "rtiff_stripwise_generate: work" ); diff --git a/libvips/foreign/tiffload.c b/libvips/foreign/tiffload.c index f7aeaef9..cd517a64 100644 --- a/libvips/foreign/tiffload.c +++ b/libvips/foreign/tiffload.c @@ -253,7 +253,7 @@ vips_foreign_load_tiff_buffer_get_flags( VipsForeignLoad *load ) VipsForeignFlags flags; flags = 0; - if( vips__istifftiled_buffer( buffer->buf->data, buffer->buf->length ) ) + if( vips__istifftiled_buffer( buffer->buf->data, buffer->buf->length ) ) flags |= VIPS_FOREIGN_PARTIAL; else flags |= VIPS_FOREIGN_SEQUENTIAL;