diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 950874853..5d42363a3 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -142,25 +142,30 @@ vips_sequential_generate(VipsRegion *out_region, * Probably the operation is something like extract_area and * we should skip the initial part of the image. In fact, * we read to cache, since it may be useful. + * + * Read in chunks, since we may be skipping *many* lines of image from + * a file source. */ - VipsRect area; - - /* - printf("vips_sequential_generate %p: skipping to line %d ...\n", - sequential, r->top); - */ - - area.left = 0; - area.top = sequential->y_pos; - area.width = 1; - area.height = r->top - sequential->y_pos; - if (vips_region_prepare(ir, &area)) { - sequential->error = -1; - g_mutex_unlock(sequential->lock); - return -1; + int tile_width; + int tile_height; + int n_lines; + + vips_get_tile_size(ir->im, &tile_width, &tile_height, &n_lines); + for (int y = sequential->y_pos; y < r->top; y += tile_height) { + VipsRect area; + + area.left = 0; + area.top = y; + area.width = 1; + area.height = VIPS_MIN(tile_height, r->top - area.top); + if (vips_region_prepare(ir, &area)) { + sequential->error = -1; + g_mutex_unlock(sequential->lock); + return -1; + } + + sequential->y_pos += area.height; } - - sequential->y_pos = VIPS_RECT_BOTTOM(&area); } /* This is a request for old pixels, or for pixels exactly at the read @@ -174,8 +179,7 @@ vips_sequential_generate(VipsRegion *out_region, return -1; } - sequential->y_pos = - VIPS_MAX(sequential->y_pos, VIPS_RECT_BOTTOM(r)); + sequential->y_pos = VIPS_MAX(sequential->y_pos, VIPS_RECT_BOTTOM(r)); g_mutex_unlock(sequential->lock);