sequential needs a strip size param

strip tiff can only read in strip-sized chunks
This commit is contained in:
John Cupitt 2012-08-24 16:06:29 +01:00
parent ee576d79b9
commit 89065b391a
5 changed files with 55 additions and 17 deletions

View File

@ -64,7 +64,7 @@ typedef struct _VipsSequential {
VipsConversion parent_instance;
VipsImage *in;
int tile_height;
gboolean trace;
/* Lock access to y_pos with this, use the cond to wake up stalled
@ -175,6 +175,7 @@ vips_sequential_build( VipsObject *object )
return( -1 );
if( vips_linecache( sequential->in, &t,
"tile_height", sequential->tile_height,
"strategy", VIPS_CACHE_SEQUENTIAL,
NULL ) )
return( -1 );
@ -221,6 +222,13 @@ vips_sequential_class_init( VipsSequentialClass *class )
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsSequential, trace ),
TRUE );
VIPS_ARG_INT( class, "tile_height", 3,
_( "Tile height" ),
_( "Tile height in pixels" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsSequential, tile_height ),
1, 1000000, 1 );
}
static void
@ -229,6 +237,7 @@ vips_sequential_init( VipsSequential *sequential )
sequential->trace = FALSE;
sequential->lock = g_mutex_new();
sequential->ready = g_cond_new();
sequential->tile_height = 1;
}
/**
@ -240,18 +249,23 @@ vips_sequential_init( VipsSequential *sequential )
* Optional arguments:
*
* @trace: trace requests
* @strip_height: height of cache strips
*
* This operation behaves rather like vips_copy() between images
* @in and @out, except that it checks that pixels are only requested
* top-to-bottom. If an out of order request is made, it throws an exception.
* top-to-bottom. If a thread makes an out of order request, it is stalled
* until the pack catches up.
*
* This operation is handy with tilecache for loading file formats which are
* This operation is useful for loading file formats which are
* strictly top-to-bottom, like PNG.
*
* If @trace is true, the operation will print diagnostic messages for each
* block of pixels which are processed. This can help find the cause of
* non-sequential accesses.
*
* @strip_height can be used to set the size of the tiles that
* vips_sequential() uses. The default value is 1.
*
* See also: vips_image_cache().
*
* Returns: 0 on success, -1 on error.

View File

@ -357,6 +357,13 @@ vips_block_cache_class_init( VipsBlockCacheClass *class )
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsBlockCache, in ) );
VIPS_ARG_INT( class, "tile_height", 3,
_( "Tile height" ),
_( "Tile height in pixels" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsBlockCache, tile_height ),
1, 1000000, 128 );
VIPS_ARG_ENUM( class, "strategy", 3,
_( "Strategy" ),
_( "Expected access pattern" ),
@ -538,13 +545,6 @@ vips_tile_cache_class_init( VipsTileCacheClass *class )
G_STRUCT_OFFSET( VipsBlockCache, tile_width ),
1, 1000000, 128 );
VIPS_ARG_INT( class, "tile_height", 3,
_( "Tile height" ),
_( "Tile height in pixels" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsBlockCache, tile_height ),
1, 1000000, 128 );
VIPS_ARG_INT( class, "max_tiles", 3,
_( "Max tiles" ),
_( "Maximum number of tiles to cache" ),
@ -646,7 +646,6 @@ vips_line_cache_build( VipsObject *object )
int tile_width;
int tile_height;
int nlines;
int nstrips;
VIPS_DEBUG_MSG( "vips_line_cache_build\n" );
@ -654,10 +653,9 @@ vips_line_cache_build( VipsObject *object )
build( object ) )
return( -1 );
/* Set the cache geometry from the image size ... a set of scanlines.
/* tile_height is set by a param, or defaulted below.
*/
block_cache->tile_width = block_cache->in->Xsize;
block_cache->tile_height = 1;
/* Enough lines for two complete buffers.
*
@ -665,7 +663,7 @@ vips_line_cache_build( VipsObject *object )
*/
vips_get_tile_size( block_cache->in,
&tile_width, &tile_height, &nlines );
block_cache->max_tiles = 2 * nlines;
block_cache->max_tiles = 2 * (1 + nlines / block_cache->tile_height);
VIPS_DEBUG_MSG( "vips_line_cache_build: max_tiles = %d\n",
block_cache->max_tiles );
@ -717,6 +715,7 @@ vips_line_cache_init( VipsLineCache *cache )
* Optional arguments:
*
* @strategy: hint expected access pattern #VipsCacheStrategy
* @tile_height: height of tiles in cache
*
* This operation behaves rather like vips_copy() between images
* @in and @out, except that it keeps a cache of computed pixels.
@ -731,6 +730,9 @@ vips_line_cache_init( VipsLineCache *cache )
* @strategy is #VIPS_CACHE_SEQUENTIAL, the top-most tile is reused.
* @strategy defaults to #VIPS_CACHE_RANDOM.
*
* @tile_height can be used to set the size of the strips that
* vips_linecache() uses. The default is 1 (a single scanline).
*
* This is a lower-level operation than vips_image_cache() since it does no
* subdivision and it single-threads its callee. It is suitable for caching
* the output of operations like png load.

View File

@ -861,6 +861,11 @@ read_jpeg_generate( VipsRegion *or,
*/
g_assert( r->top % 8 == 0 );
/* Tiles should always be a strip in height, unless it's the final
* strip.
*/
g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) );
/* Here for longjmp() from vips__new_error_exit().
*/
if( setjmp( jpeg->eman.jmp ) )
@ -917,7 +922,9 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
if( vips_image_generate( t[0],
NULL, read_jpeg_generate, NULL,
jpeg, NULL ) ||
vips_sequential( t[0], &t[1], NULL ) ||
vips_sequential( t[0], &t[1],
"tile_height", 8,
NULL ) ||
vips_image_write( t[1], out ) )
return( -1 );

View File

@ -1319,6 +1319,12 @@ tiff2vips_stripwise_generate( VipsRegion *or,
*/
g_assert( r->top % rtiff->rows_per_strip == 0 );
/* Tiles should always be a strip in height, unless it's the final
* strip.
*/
g_assert( r->height ==
VIPS_MIN( rtiff->rows_per_strip, or->im->Ysize - r->top ) );
for( y = 0; y < r->height; y += rtiff->rows_per_strip ) {
tdata_t dst;
tstrip_t strip;
@ -1419,7 +1425,9 @@ read_stripwise( ReadTiff *rtiff, VipsImage *out )
vips_image_generate( t[0],
NULL, tiff2vips_stripwise_generate, NULL,
rtiff, tbuf ) ||
vips_sequential( t[0], &t[1], NULL ) ||
vips_sequential( t[0], &t[1],
"tile_height", rtiff->rows_per_strip,
NULL ) ||
vips_image_write( t[1], out ) )
return( -1 );

View File

@ -416,6 +416,11 @@ png2vips_generate( VipsRegion *or,
g_assert( r->width == or->im->Xsize );
g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize );
/* Tiles should always be a strip in height, unless it's the final
* strip.
*/
g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) );
if( setjmp( png_jmpbuf( read->pPng ) ) ) {
#ifdef DEBUG
printf( "png2vips_generate: failing in setjmp\n" );
@ -488,7 +493,9 @@ vips__png_read( const char *name, VipsImage *out )
vips_image_generate( t[0],
NULL, png2vips_generate, NULL,
read, NULL ) ||
vips_sequential( t[0], &t[1], NULL ) ||
vips_sequential( t[0], &t[1],
"tile_height", 8,
NULL ) ||
vips_image_write( t[1], out ) )
return( -1 );
}