diff --git a/ChangeLog b/ChangeLog index 3a0bafd8..acd5699a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ - vips8 command-line interface uses this to turn sequential mode on automatically when possible - better handling of input files in vips7 command-line interface +- sequential can skip ahead, so extract / insert are now seq 18/6/12 started 7.28.9 - slightly more memory debugging output diff --git a/libvips/conversion/extract.c b/libvips/conversion/extract.c index 6e398356..d1b334e0 100644 --- a/libvips/conversion/extract.c +++ b/libvips/conversion/extract.c @@ -180,6 +180,7 @@ vips_extract_area_class_init( VipsExtractAreaClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); VIPS_DEBUG_MSG( "vips_extract_area_class_init\n" ); @@ -190,8 +191,7 @@ vips_extract_area_class_init( VipsExtractAreaClass *class ) vobject_class->description = _( "extract an area from an image" ); vobject_class->build = vips_extract_area_build; - /* Not sequential, since we skip the top and bottom of the image. - */ + operation_class->flags = VIPS_OPERATION_SEQUENTIAL; VIPS_ARG_IMAGE( class, "input", 0, _( "Input" ), diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index 14a13da6..c100fa82 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -339,6 +339,7 @@ vips_insert_class_init( VipsInsertClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); VIPS_DEBUG_MSG( "vips_insert_class_init\n" ); @@ -349,9 +350,7 @@ vips_insert_class_init( VipsInsertClass *class ) vobject_class->description = _( "insert an image" ); vobject_class->build = vips_insert_build; - /* Not sequential, since the image being inserted may be clipped and - * we may need to skip the top or bottom. - */ + operation_class->flags = VIPS_OPERATION_SEQUENTIAL; VIPS_ARG_IMAGE( class, "main", -1, _( "Main" ), diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 342fcc23..f259e0cd 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -5,6 +5,8 @@ * * 15/2/12 * - from VipsForeignLoad + * 14/7/12 + * - support skip forwards as well, so we can do extract/insert */ /* @@ -74,14 +76,9 @@ vips_sequential_generate( VipsRegion *or, VIPS_DEBUG_MSG( "vips_sequential_generate %d\n", r->top ); - /* The y pos of the request must be the same as our current file - * position. + /* We can't go backwards, but we can skip forwards. */ - if( r->top != sequential->y_pos ) { - printf( "vips_sequential_generate: error -- " - "at position %d in file, but position %d requested\n", - sequential->y_pos, r->top ); - + if( r->top < sequential->y_pos ) { vips_error( "VipsSequential", _( "non-sequential read --- " "at position %d in file, but position %d requested" ), @@ -96,6 +93,24 @@ vips_sequential_generate( VipsRegion *or, g_assert( r->width == or->im->Xsize ); g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize ); + /* Skip forwards, if necessary. + */ + while( sequential->y_pos < r->top ) { + VipsRect rect; + + rect.top = sequential->y_pos; + rect.left = 0; + rect.width = or->im->Xsize; + rect.height = VIPS_MIN( r->top - sequential->y_pos, + VIPS__FATSTRIP_HEIGHT ); + if( vips_region_prepare( ir, &rect ) ) + return( -1 ); + + sequential->y_pos += rect.height; + } + + g_assert( sequential->y_pos == r->top ); + /* Pointer copy. */ if( vips_region_prepare( ir, r ) ||