support "rs" mode in im_open()

vips7 compat mode now supports "rs" mode --- sequential read

ruby-vips uses this to get :sequetial=>true working
This commit is contained in:
John Cupitt 2012-07-20 13:07:49 +01:00
parent 41be00d5dd
commit a71fe51d2d
9 changed files with 42 additions and 20 deletions

View File

@ -1,5 +1,5 @@
20/7/12 started 7.30.0 20/7/12 started 7.30.0
- version bump - support "rs" mode in vips7
19/3/12 started 7.29.0 19/3/12 started 7.29.0
- sanity-check PNG read geometry - sanity-check PNG read geometry

10
TODO
View File

@ -1,3 +1,13 @@
- try:
vipsthumbnail wtc.tif --verbose --vips-progress --vips-leak
get no progress info
does not report static interpolators on exit, shouldn't leak check do
this?
blocking bugs blocking bugs
============= =============

View File

@ -110,7 +110,7 @@ input_image_init( im_object *obj, char *str )
{ {
IMAGE **im = (IMAGE **) obj; IMAGE **im = (IMAGE **) obj;
return( !(*im = vips__deprecated_open_read( str )) ); return( !(*im = vips__deprecated_open_read( str, FALSE )) );
} }
/* Input image type. /* Input image type.

View File

@ -58,6 +58,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
char mode[FILENAME_MAX]; char mode[FILENAME_MAX];
char *p, *q; char *p, *q;
int shrink; int shrink;
int seq;
gboolean fail_on_warn; gboolean fail_on_warn;
/* By default, we ignore any warnings. We want to get as much of /* By default, we ignore any warnings. We want to get as much of
@ -70,6 +71,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
im_filename_split( name, filename, mode ); im_filename_split( name, filename, mode );
p = &mode[0]; p = &mode[0];
shrink = 1; shrink = 1;
seq = 0;
if( (q = im_getnextoption( &p )) ) { if( (q = im_getnextoption( &p )) ) {
shrink = atoi( q ); shrink = atoi( q );
@ -84,13 +86,9 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
if( im_isprefix( "fail", q ) ) if( im_isprefix( "fail", q ) )
fail_on_warn = TRUE; fail_on_warn = TRUE;
} }
/* vips__jpeg_read_file() is always sequential. Parse the option, but
* don't use it.
*/
if( (q = im_getnextoption( &p )) ) { if( (q = im_getnextoption( &p )) ) {
if( im_isprefix( "seq", q ) ) if( im_isprefix( "seq", q ) )
; seq = 1;
} }
/* Don't use vips_jpegload() ... we call the jpeg func directly in /* Don't use vips_jpegload() ... we call the jpeg func directly in
@ -106,6 +104,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
*/ */
if( !header_only && if( !header_only &&
!seq &&
out->dtype == VIPS_IMAGE_PARTIAL ) { out->dtype == VIPS_IMAGE_PARTIAL ) {
if( vips__image_wio_output( out ) ) if( vips__image_wio_output( out ) )
return( -1 ); return( -1 );

View File

@ -52,13 +52,15 @@ png2vips( const char *name, IMAGE *out, gboolean header_only )
char filename[FILENAME_MAX]; char filename[FILENAME_MAX];
char mode[FILENAME_MAX]; char mode[FILENAME_MAX];
char *p, *q; char *p, *q;
int seq;
im_filename_split( name, filename, mode ); im_filename_split( name, filename, mode );
seq = 0;
p = &mode[0]; p = &mode[0];
if( (q = im_getnextoption( &p )) ) { if( (q = im_getnextoption( &p )) ) {
if( im_isprefix( "seq", q ) ) if( im_isprefix( "seq", q ) )
; seq = 1;
} }
/* We need to be compatible with the pre-sequential mode /* We need to be compatible with the pre-sequential mode
@ -72,6 +74,7 @@ png2vips( const char *name, IMAGE *out, gboolean header_only )
*/ */
if( !header_only && if( !header_only &&
!seq &&
out->dtype == VIPS_IMAGE_PARTIAL ) { out->dtype == VIPS_IMAGE_PARTIAL ) {
if( vips__image_wio_output( out ) ) if( vips__image_wio_output( out ) )
return( -1 ); return( -1 );

View File

@ -57,17 +57,19 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
char mode[FILENAME_MAX]; char mode[FILENAME_MAX];
char *p, *q; char *p, *q;
int page; int page;
int seq;
im_filename_split( name, filename, mode ); im_filename_split( name, filename, mode );
page = 0; page = 0;
seq = 0;
p = &mode[0]; p = &mode[0];
if( (q = im_getnextoption( &p )) ) { if( (q = im_getnextoption( &p )) ) {
page = atoi( q ); page = atoi( q );
} }
if( (q = im_getnextoption( &p )) ) { if( (q = im_getnextoption( &p )) ) {
if( im_isprefix( "seq", q ) ) if( im_isprefix( "seq", q ) )
; seq = 1;
} }
/* We need to be compatible with the pre-sequential mode /* We need to be compatible with the pre-sequential mode
@ -82,6 +84,7 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
*/ */
if( !header_only && if( !header_only &&
!seq &&
!vips__istifftiled( filename ) && !vips__istifftiled( filename ) &&
out->dtype == VIPS_IMAGE_PARTIAL ) { out->dtype == VIPS_IMAGE_PARTIAL ) {
if( vips__image_wio_output( out ) ) if( vips__image_wio_output( out ) )

View File

@ -63,7 +63,7 @@ typedef struct {
VipsImage *image; VipsImage *image;
VipsFormatClass *format;/* Read in pixels with this */ VipsFormatClass *format;/* Read in pixels with this */
char *filename; /* Get pixels from here */ char *filename; /* Get pixels from here */
gboolean disc; /* Read via disc requested */ gboolean sequential; /* Sequential read requested */
VipsImage *real; /* The real decompressed image */ VipsImage *real; /* The real decompressed image */
} Lazy; } Lazy;
@ -80,7 +80,7 @@ lazy_free_cb( VipsImage *image, Lazy *lazy )
static Lazy * static Lazy *
lazy_new( VipsImage *image, lazy_new( VipsImage *image,
VipsFormatClass *format, const char *filename, gboolean disc ) VipsFormatClass *format, const char *filename, gboolean sequential )
{ {
Lazy *lazy; Lazy *lazy;
@ -89,7 +89,7 @@ lazy_new( VipsImage *image,
lazy->image = image; lazy->image = image;
lazy->format = format; lazy->format = format;
lazy->filename = g_strdup( filename ); lazy->filename = g_strdup( filename );
lazy->disc = disc; lazy->sequential = sequential;
lazy->real = NULL; lazy->real = NULL;
g_signal_connect( image, "close", G_CALLBACK( lazy_free_cb ), lazy ); g_signal_connect( image, "close", G_CALLBACK( lazy_free_cb ), lazy );
@ -132,13 +132,13 @@ lazy_real_image( Lazy *lazy )
VipsImage *real; VipsImage *real;
/* We open via disc if: /* We open via disc if:
* - 'disc' is set * - 'sequential' is not set
* - disc_threshold() has not been set to zero * - disc_threshold() has not been set to zero
* - the format does not support lazy read * - the format does not support lazy read
* - the uncompressed image will be larger than disc_threshold() * - the uncompressed image will be larger than disc_threshold()
*/ */
real = NULL; real = NULL;
if( lazy->disc && if( !lazy->sequential &&
disc_threshold() && disc_threshold() &&
!(vips_format_get_flags( lazy->format, lazy->filename ) & !(vips_format_get_flags( lazy->format, lazy->filename ) &
VIPS_FORMAT_PARTIAL) && VIPS_FORMAT_PARTIAL) &&
@ -203,11 +203,11 @@ open_lazy_generate( VipsRegion *or,
*/ */
static int static int
vips_image_open_lazy( VipsImage *image, vips_image_open_lazy( VipsImage *image,
VipsFormatClass *format, const char *filename, gboolean disc ) VipsFormatClass *format, const char *filename, gboolean sequential )
{ {
Lazy *lazy; Lazy *lazy;
lazy = lazy_new( image, format, filename, disc ); lazy = lazy_new( image, format, filename, sequential );
/* Is there a ->header() function? We need to do a lazy load. /* Is there a ->header() function? We need to do a lazy load.
*/ */
@ -273,7 +273,7 @@ vips_attach_save( VipsImage *image, int (*save_fn)(), const char *filename )
} }
IMAGE * IMAGE *
vips__deprecated_open_read( const char *filename ) vips__deprecated_open_read( const char *filename, gboolean sequential )
{ {
VipsFormatClass *format; VipsFormatClass *format;
@ -293,7 +293,8 @@ vips__deprecated_open_read( const char *filename )
IMAGE *image; IMAGE *image;
image = vips_image_new(); image = vips_image_new();
if( vips_image_open_lazy( image, format, filename, TRUE ) ) { if( vips_image_open_lazy( image, format,
filename, sequential ) ) {
g_object_unref( image ); g_object_unref( image );
return( NULL ); return( NULL );
} }

View File

@ -62,10 +62,16 @@ im_open( const char *filename, const char *mode )
/* We have to go via the old VipsFormat system so we can support the /* We have to go via the old VipsFormat system so we can support the
* "filename:option" syntax. * "filename:option" syntax.
*
* Use "rs" to turn on seq mode.
*/ */
if( strcmp( mode, "r" ) == 0 || if( strcmp( mode, "r" ) == 0 ||
strcmp( mode, "rd" ) == 0 ) { strcmp( mode, "rd" ) == 0 ) {
if( !(image = vips__deprecated_open_read( filename )) ) if( !(image = vips__deprecated_open_read( filename, FALSE )) )
return( NULL );
}
else if( strcmp( mode, "rs" ) == 0 ) {
if( !(image = vips__deprecated_open_read( filename, TRUE )) )
return( NULL ); return( NULL );
} }
else if( strcmp( mode, "w" ) == 0 ) { else if( strcmp( mode, "w" ) == 0 ) {

View File

@ -297,7 +297,7 @@ void vips_foreign_operation_init( void );
guint64 vips__parse_size( const char *size_string ); guint64 vips__parse_size( const char *size_string );
IMAGE *vips__deprecated_open_read( const char *filename ); IMAGE *vips__deprecated_open_read( const char *filename, gboolean sequential );
IMAGE *vips__deprecated_open_write( const char *filename ); IMAGE *vips__deprecated_open_write( const char *filename );
#ifdef __cplusplus #ifdef __cplusplus