more revision

This commit is contained in:
John Cupitt 2019-10-21 15:04:30 +01:00
parent d49e816641
commit 72cbaa9ea3
7 changed files with 117 additions and 97 deletions

View File

@ -627,10 +627,10 @@ static void *
vips_foreign_find_load_stream_sub( void *item, void *a, void *b ) vips_foreign_find_load_stream_sub( void *item, void *a, void *b )
{ {
VipsForeignLoadClass *load_class = VIPS_FOREIGN_LOAD_CLASS( item ); VipsForeignLoadClass *load_class = VIPS_FOREIGN_LOAD_CLASS( item );
VipsStreamInput *input = VIPS_STREAM_INPUT( a ); VipsStreami *streami = VIPS_STREAMI( a );
if( load_class->is_a_stream && if( load_class->is_a_stream &&
load_class->is_a_stream( input ) ) load_class->is_a_stream( streami ) )
return( load_class ); return( load_class );
return( NULL ); return( NULL );
@ -638,7 +638,7 @@ vips_foreign_find_load_stream_sub( void *item, void *a, void *b )
/** /**
* vips_foreign_find_load_stream: * vips_foreign_find_load_stream:
* @input: stream to load from * @streami: stream to load from
* *
* Searches for an operation you could use to load a stream. To see the * Searches for an operation you could use to load a stream. To see the
* range of buffer loaders supported by your vips, try something like: * range of buffer loaders supported by your vips, try something like:
@ -651,14 +651,14 @@ vips_foreign_find_load_stream_sub( void *item, void *a, void *b )
* error. * error.
*/ */
const char * const char *
vips_foreign_find_load_stream( VipsStreamInput *input ) vips_foreign_find_load_stream( VipsStreami *streami )
{ {
VipsForeignLoadClass *load_class; VipsForeignLoadClass *load_class;
if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map( if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
"VipsForeignLoad", "VipsForeignLoad",
vips_foreign_find_load_stream_sub, vips_foreign_find_load_stream_sub,
input, NULL )) ) { streami, NULL )) ) {
vips_error( "VipsForeignLoad", vips_error( "VipsForeignLoad",
"%s", _( "stream is not in a known format" ) ); "%s", _( "stream is not in a known format" ) );
return( NULL ); return( NULL );
@ -723,15 +723,15 @@ vips_foreign_is_a_buffer( const char *loader, const void *data, size_t size )
/** /**
* vips_foreign_is_a_stream: * vips_foreign_is_a_stream:
* @loader: name of loader to use for test * @loader: name of loader to use for test
* @input: stream to test * @streami: stream to test
* *
* Return %TRUE if @input can be loaded by @loader. @loader is something * Return %TRUE if @streami can be loaded by @loader. @loader is something
* like "tiffload_stream" or "VipsForeignLoadTiffStream". * like "tiffload_stream" or "VipsForeignLoadTiffStream".
* *
* Returns: %TRUE if @data can be loaded by @stream. * Returns: %TRUE if @data can be loaded by @stream.
*/ */
gboolean gboolean
vips_foreign_is_a_stream( const char *loader, VipsStreamInput *input ) vips_foreign_is_a_stream( const char *loader, VipsStreami *streami )
{ {
const VipsObjectClass *class; const VipsObjectClass *class;
VipsForeignLoadClass *load_class; VipsForeignLoadClass *load_class;
@ -740,7 +740,7 @@ vips_foreign_is_a_stream( const char *loader, VipsStreamInput *input )
return( FALSE ); return( FALSE );
load_class = VIPS_FOREIGN_LOAD_CLASS( class ); load_class = VIPS_FOREIGN_LOAD_CLASS( class );
if( load_class->is_a_stream && if( load_class->is_a_stream &&
load_class->is_a_stream( input ) ) load_class->is_a_stream( streami ) )
return( TRUE ); return( TRUE );
return( FALSE ); return( FALSE );

View File

@ -79,11 +79,11 @@ int vips__tiff_write_buf( VipsImage *in,
VipsRegionShrink region_shrink, VipsRegionShrink region_shrink,
int level, gboolean lossless ); int level, gboolean lossless );
gboolean vips__istiff_stream( VipsStreamInput *input ); gboolean vips__istiff_stream( VipsStreami *streami );
gboolean vips__istifftiled_stream( VipsStreamInput *input ); gboolean vips__istifftiled_stream( VipsStreami *streami );
int vips__tiff_read_header_stream( VipsStreamInput *input, VipsImage *out, int vips__tiff_read_header_stream( VipsStreami *streami, VipsImage *out,
int page, int n, gboolean autorotate ); int page, int n, gboolean autorotate );
int vips__tiff_read_stream( VipsStreamInput *input, VipsImage *out, int vips__tiff_read_stream( VipsStreami *streami, VipsImage *out,
int page, int n, gboolean autorotate ); int page, int n, gboolean autorotate );
extern const char *vips__foreign_tiff_suffs[]; extern const char *vips__foreign_tiff_suffs[];
@ -163,25 +163,25 @@ extern const char *vips__rad_suffs[];
extern const char *vips__jpeg_suffs[]; extern const char *vips__jpeg_suffs[];
int vips__jpeg_write_stream( VipsImage *in, VipsStreamOutput *output, int vips__jpeg_write_stream( VipsImage *in, VipsStreamo *streamo,
int Q, const char *profile, int Q, const char *profile,
gboolean optimize_coding, gboolean progressive, gboolean strip, gboolean optimize_coding, gboolean progressive, gboolean strip,
gboolean no_subsample, gboolean trellis_quant, gboolean no_subsample, gboolean trellis_quant,
gboolean overshoot_deringing, gboolean optimize_scans, gboolean overshoot_deringing, gboolean optimize_scans,
int quant_table ); int quant_table );
int vips__jpeg_read_stream( VipsStreamInput *input, VipsImage *out, int vips__jpeg_read_stream( VipsStreami *streami, VipsImage *out,
gboolean header_only, int shrink, int fail, gboolean autorotate ); gboolean header_only, int shrink, int fail, gboolean autorotate );
int vips__isjpeg_stream( VipsStreamInput *input ); int vips__isjpeg_stream( VipsStreami *streami );
int vips__png_ispng_stream( VipsStreamInput *input ); int vips__png_ispng_stream( VipsStreami *streami );
int vips__png_header_stream( VipsStreamInput *input, VipsImage *out ); int vips__png_header_stream( VipsStreami *streami, VipsImage *out );
int vips__png_read_stream( VipsStreamInput *input, VipsImage *out, int vips__png_read_stream( VipsStreami *streami, VipsImage *out,
gboolean fail ); gboolean fail );
gboolean vips__png_isinterlaced_stream( VipsStreamInput *input ); gboolean vips__png_isinterlaced_stream( VipsStreami *streami );
extern const char *vips__png_suffs[]; extern const char *vips__png_suffs[];
int vips__png_write_stream( VipsImage *in, VipsStreamOutput *output, int vips__png_write_stream( VipsImage *in, VipsStreamo *streamo,
int compress, int interlace, const char *profile, int compress, int interlace, const char *profile,
VipsForeignPngFilter filter, gboolean strip, VipsForeignPngFilter filter, gboolean strip,
gboolean palette, int colours, int Q, double dither ); gboolean palette, int colours, int Q, double dither );
@ -198,14 +198,14 @@ extern const VipsWebPNames vips__webp_names[];
extern const int vips__n_webp_names; extern const int vips__n_webp_names;
extern const char *vips__webp_suffs[]; extern const char *vips__webp_suffs[];
int vips__iswebp_stream( VipsStreamInput *input ); int vips__iswebp_stream( VipsStreami *streami );
int vips__webp_read_header_stream( VipsStreamInput *input, VipsImage *out, int vips__webp_read_header_stream( VipsStreami *streami, VipsImage *out,
int page, int n, double scale ); int page, int n, double scale );
int vips__webp_read_stream( VipsStreamInput *input, VipsImage *out, int vips__webp_read_stream( VipsStreami *streami, VipsImage *out,
int page, int n, double scale ); int page, int n, double scale );
int vips__webp_write_stream( VipsImage *image, VipsStreamOutput *output, int vips__webp_write_stream( VipsImage *image, VipsStreamo *streamo,
int Q, gboolean lossless, VipsForeignWebpPreset preset, int Q, gboolean lossless, VipsForeignWebpPreset preset,
gboolean smart_subsample, gboolean near_lossless, gboolean smart_subsample, gboolean near_lossless,
int alpha_q, int reduction_effort, int alpha_q, int reduction_effort,

View File

@ -57,7 +57,7 @@ typedef struct _VipsForeignLoadPngStream {
/* Load from a stream. /* Load from a stream.
*/ */
VipsStreamInput *input; VipsStreami *input;
} VipsForeignLoadPngStream; } VipsForeignLoadPngStream;
@ -153,7 +153,7 @@ G_DEFINE_TYPE( VipsForeignLoadPng, vips_foreign_load_png,
static gboolean static gboolean
vips_foreign_load_png_is_a( const char *filename ) vips_foreign_load_png_is_a( const char *filename )
{ {
VipsStreamInput *input; VipsStreami *input;
gboolean result; gboolean result;
if( !(input = vips_stream_input_new_from_filename( filename )) ) if( !(input = vips_stream_input_new_from_filename( filename )) )
@ -167,7 +167,7 @@ vips_foreign_load_png_is_a( const char *filename )
static VipsForeignFlags static VipsForeignFlags
vips_foreign_load_png_get_flags_filename( const char *filename ) vips_foreign_load_png_get_flags_filename( const char *filename )
{ {
VipsStreamInput *input; VipsStreami *input;
VipsForeignFlags flags; VipsForeignFlags flags;
if( !(input = vips_stream_input_new_from_filename( filename )) ) if( !(input = vips_stream_input_new_from_filename( filename )) )
@ -197,7 +197,7 @@ vips_foreign_load_png_header( VipsForeignLoad *load )
{ {
VipsForeignLoadPng *png = (VipsForeignLoadPng *) load; VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
VipsStreamInput *input; VipsStreami *input;
if( !(input = vips_stream_input_new_from_filename( png->filename )) ) if( !(input = vips_stream_input_new_from_filename( png->filename )) )
return( -1 ); return( -1 );
@ -215,7 +215,7 @@ vips_foreign_load_png_load( VipsForeignLoad *load )
{ {
VipsForeignLoadPng *png = (VipsForeignLoadPng *) load; VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
VipsStreamInput *input; VipsStreami *input;
if( !(input = vips_stream_input_new_from_filename( png->filename )) ) if( !(input = vips_stream_input_new_from_filename( png->filename )) )
return( -1 ); return( -1 );
@ -285,7 +285,7 @@ G_DEFINE_TYPE( VipsForeignLoadPngBuffer, vips_foreign_load_png_buffer,
static gboolean static gboolean
vips_foreign_load_png_buffer_is_a_buffer( const void *buf, size_t len ) vips_foreign_load_png_buffer_is_a_buffer( const void *buf, size_t len )
{ {
VipsStreamInput *input; VipsStreami *input;
gboolean result; gboolean result;
if( !(input = vips_stream_input_new_from_memory( buf, len )) ) if( !(input = vips_stream_input_new_from_memory( buf, len )) )
@ -301,7 +301,7 @@ vips_foreign_load_png_buffer_get_flags( VipsForeignLoad *load )
{ {
VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load; VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load;
VipsStreamInput *input; VipsStreami *input;
VipsForeignFlags flags; VipsForeignFlags flags;
if( !(input = vips_stream_input_new_from_memory( buffer->buf->data, if( !(input = vips_stream_input_new_from_memory( buffer->buf->data,
@ -324,7 +324,7 @@ vips_foreign_load_png_buffer_header( VipsForeignLoad *load )
{ {
VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load; VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load;
VipsStreamInput *input; VipsStreami *input;
if( !(input = vips_stream_input_new_from_memory( buffer->buf->data, if( !(input = vips_stream_input_new_from_memory( buffer->buf->data,
buffer->buf->length )) ) buffer->buf->length )) )
@ -343,7 +343,7 @@ vips_foreign_load_png_buffer_load( VipsForeignLoad *load )
{ {
VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load; VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load;
VipsStreamInput *input; VipsStreami *input;
if( !(input = vips_stream_input_new_from_memory( buffer->buf->data, if( !(input = vips_stream_input_new_from_memory( buffer->buf->data,
buffer->buf->length )) ) buffer->buf->length )) )
@ -469,7 +469,7 @@ vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.
*/ */
int int
vips_pngload_stream( VipsStreamInput *input, VipsImage **out, ... ) vips_pngload_stream( VipsStreami *input, VipsImage **out, ... )
{ {
va_list ap; va_list ap;
int result; int result;

View File

@ -189,7 +189,7 @@ typedef struct _VipsForeignLoadClass {
* This function should return %TRUE if the stream contains an image of * This function should return %TRUE if the stream contains an image of
* this type. * this type.
*/ */
gboolean (*is_a_stream)( VipsStreamInput *stream ); gboolean (*is_a_stream)( VipsStreami *streami );
/* Get the flags from a filename. /* Get the flags from a filename.
* *
@ -240,14 +240,14 @@ GType vips_foreign_load_get_type(void);
const char *vips_foreign_find_load( const char *filename ); const char *vips_foreign_find_load( const char *filename );
const char *vips_foreign_find_load_buffer( const void *data, size_t size ); const char *vips_foreign_find_load_buffer( const void *data, size_t size );
const char *vips_foreign_find_load_stream( VipsStreamInput *stream ); const char *vips_foreign_find_load_stream( VipsStreami *streami );
VipsForeignFlags vips_foreign_flags( const char *loader, const char *filename ); VipsForeignFlags vips_foreign_flags( const char *loader, const char *filename );
gboolean vips_foreign_is_a( const char *loader, const char *filename ); gboolean vips_foreign_is_a( const char *loader, const char *filename );
gboolean vips_foreign_is_a_buffer( const char *loader, gboolean vips_foreign_is_a_buffer( const char *loader,
const void *data, size_t size ); const void *data, size_t size );
gboolean vips_foreign_is_a_stream( const char *loader, gboolean vips_foreign_is_a_stream( const char *loader,
VipsStreamInput *stream ); VipsStreami *streami );
void vips_foreign_load_invalidate( VipsImage *image ); void vips_foreign_load_invalidate( VipsImage *image );
@ -369,7 +369,7 @@ int vips_jpegload( const char *filename, VipsImage **out, ... )
int vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... ) int vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_jpegsave_stream( VipsImage *in, VipsStreamOutput *output, ... ) int vips_jpegsave_stream( VipsImage *in, VipsStreamo *streamo, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_jpegsave( VipsImage *in, const char *filename, ... ) int vips_jpegsave( VipsImage *in, const char *filename, ... )
__attribute__((sentinel)); __attribute__((sentinel));
@ -399,14 +399,14 @@ typedef enum {
VIPS_FOREIGN_WEBP_PRESET_LAST VIPS_FOREIGN_WEBP_PRESET_LAST
} VipsForeignWebpPreset; } VipsForeignWebpPreset;
int vips_webpload_stream( VipsStreamInput *input, VipsImage **out, ... ) int vips_webpload_stream( VipsStreami *streami, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_webpload( const char *filename, VipsImage **out, ... ) int vips_webpload( const char *filename, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_webpload_buffer( void *buf, size_t len, VipsImage **out, ... ) int vips_webpload_buffer( void *buf, size_t len, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_webpsave_stream( VipsImage *in, VipsStreamOutput *output, ... ) int vips_webpsave_stream( VipsImage *in, VipsStreamo *streamo, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_webpsave( VipsImage *in, const char *filename, ... ) int vips_webpsave( VipsImage *in, const char *filename, ... )
__attribute__((sentinel)); __attribute__((sentinel));
@ -481,7 +481,7 @@ int vips_tiffload( const char *filename, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... ) int vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_tiffload_stream( VipsStreamInput *input, VipsImage **out, ... ) int vips_tiffload_stream( VipsStreami *streami, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_tiffsave( VipsImage *in, const char *filename, ... ) int vips_tiffsave( VipsImage *in, const char *filename, ... )
__attribute__((sentinel)); __attribute__((sentinel));
@ -549,13 +549,13 @@ typedef enum /*< flags >*/ {
VIPS_FOREIGN_PNG_FILTER_ALL = 0xF8 VIPS_FOREIGN_PNG_FILTER_ALL = 0xF8
} VipsForeignPngFilter; } VipsForeignPngFilter;
int vips_pngload_stream( VipsStreamInput *input, VipsImage **out, ... ) int vips_pngload_stream( VipsStreami *streami, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_pngload( const char *filename, VipsImage **out, ... ) int vips_pngload( const char *filename, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... ) int vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_pngsave_stream( VipsImage *in, VipsStreamOutput *output, ... ) int vips_pngsave_stream( VipsImage *in, VipsStreamo *streamo, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_pngsave( VipsImage *in, const char *filename, ... ) int vips_pngsave( VipsImage *in, const char *filename, ... )
__attribute__((sentinel)); __attribute__((sentinel));

View File

@ -447,7 +447,7 @@ VipsImage *vips_image_new_from_memory_copy( const void *data, size_t size,
VipsImage *vips_image_new_from_buffer( const void *buf, size_t len, VipsImage *vips_image_new_from_buffer( const void *buf, size_t len,
const char *option_string, ... ) const char *option_string, ... )
__attribute__((sentinel)); __attribute__((sentinel));
VipsImage *vips_image_new_from_stream( VipsStreamInput *input, VipsImage *vips_image_new_from_stream( VipsStreami *streami,
const char *option_string, ... ) __attribute__((sentinel)); const char *option_string, ... ) __attribute__((sentinel));
VipsImage *vips_image_new_matrix( int width, int height ); VipsImage *vips_image_new_matrix( int width, int height );
VipsImage *vips_image_new_matrixv( int width, int height, ... ); VipsImage *vips_image_new_matrixv( int width, int height, ... );
@ -471,7 +471,7 @@ int vips_image_write_to_buffer( VipsImage *in,
const char *suffix, void **buf, size_t *size, ... ) const char *suffix, void **buf, size_t *size, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_image_write_to_stream( VipsImage *in, int vips_image_write_to_stream( VipsImage *in,
const char *suffix, VipsStreamOutput *output, ... ) const char *suffix, VipsStreamo *streamo, ... )
__attribute__((sentinel)); __attribute__((sentinel));
void *vips_image_write_to_memory( VipsImage *in, size_t *size ); void *vips_image_write_to_memory( VipsImage *in, size_t *size );

View File

@ -79,7 +79,7 @@ int vips_thumbnail_buffer( void *buf, size_t len, VipsImage **out,
__attribute__((sentinel)); __attribute__((sentinel));
int vips_thumbnail_image( VipsImage *in, VipsImage **out, int width, ... ) int vips_thumbnail_image( VipsImage *in, VipsImage **out, int width, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_thumbnail_stream( VipsStreamInput *input, VipsImage **out, int vips_thumbnail_stream( VipsStreami *streami, VipsImage **out,
int width, ... ) int width, ... )
__attribute__((sentinel)); __attribute__((sentinel));

View File

@ -33,17 +33,15 @@
/* TODO /* TODO
* *
* - catch out of range seeks
* - some sanity thing to prevent endless streams filling memory?
* - filename encoding * - filename encoding
* - seek END and _size need thinking about with pipes ... perhaps we should * - are we detecting EOF correctly? what about interrupted reads? perhaps
* force-read the whole thing in * we should check errno as well
* - _size() needs to be a vfunc too (libtiff needs it) * - _size() needs to be a vfunc too (libtiff needs it)
* - _miminize() is a vfunc, so _open() must be as well * - _miminize() is a vfunc, so _open() must be as well
* + perhaps minimise should not be a vfunc? is it really useful for * + perhaps minimise should not be a vfunc? is it really useful for
* subclasses? * subclasses?
* + perhaps make _open() / _close() into vfuncs and don't expose minimise * + perhaps make _open() / _close() into vfuncs on stream (not streami) and
* - only fetch length once * don't expose minimise
* - need to be able to set is_pipe via constructor * - need to be able to set is_pipe via constructor
* - test we can really change all behaviour in the subclass ... add callbacks * - test we can really change all behaviour in the subclass ... add callbacks
* as well to make it simpler for language bindings * as well to make it simpler for language bindings
@ -592,7 +590,7 @@ vips_streami_read( VipsStreami *streami, void *buffer, size_t length )
VIPS_DEBUG_MSG( " %zd bytes from cache\n", available ); VIPS_DEBUG_MSG( " %zd bytes from cache\n", available );
} }
/* Any more bytes required? Call the read() vfunc. /* Any more bytes requested? Call the read() vfunc.
*/ */
if( length > 0 ) { if( length > 0 ) {
ssize_t n; ssize_t n;
@ -626,30 +624,63 @@ vips_streami_read( VipsStreami *streami, void *buffer, size_t length )
return( bytes_read ); return( bytes_read );
} }
/* Read the entire pipe into memory and turn this into a memory source stream. /* Read a pipe to at least a position. -1 means read to end of stream. Does
* not chenge read_position.
*/ */
static int static int
vips_streami_read_whole_pipe( VipsStreami *streami ) vips_streami_pipe_read_to_position( VipsStreami *streami, gint64 target )
{ {
gint64 old_read_position; gint64 old_read_position;
unsigned char buffer[4096]; unsigned char buffer[4096];
unsigned char *data; unsigned char *data;
VIPS_DEBUG_MSG( "vips_streami_read_whole_pipe:\n" ); VIPS_DEBUG_MSG( "vips_streami_pipe_read_position:\n" );
vips_streami_sanity( streami ); vips_streami_sanity( streami );
if( streami->decode ) {
vips_error( vips_stream_name( VIPS_STREAM( streami ) ),
"%s", _( "can't seek pipe after "
"pixel decode begins" ) );
return( -1 );
}
old_read_position = streami->read_position; old_read_position = streami->read_position;
if( vips_streami_rewind( streami ) )
return( -1 );
/* TODO ... add something to prevent unbounded streams filling memory. /* TODO ... add something to prevent unbounded streams filling memory.
*/ */
while( vips_streami_read( streami, buffer, 4096 ) > 0 ) while( target == -1 ||
; streami->read_position < target ) {
ssize_t read;
read = vips_streami_read( streami, buffer, 4096 );
if( read == -1 )
return( -1 );
if( read == 0 )
break;
}
streami->read_position = old_read_position; streami->read_position = old_read_position;
vips_streami_sanity( streami );
return( 0 );
}
/* Read the entire pipe into memory and turn this into a memory source stream.
*/
static int
vips_streami_pipe_to_memory( VipsStreami *streami )
{
unsigned char *data;
VIPS_DEBUG_MSG( "vips_streami_pipe_to_memory:\n" );
vips_streami_sanity( streami );
if( vips_streami_pipe_read_to_position( streami, -1 ) )
return( -1 );
/* Move header_bytes into the memory blob and set up as a memory /* Move header_bytes into the memory blob and set up as a memory
* source. * source.
*/ */
@ -678,6 +709,12 @@ vips_streami_map( VipsStreami *streami, size_t *length_out )
vips_streami_sanity( streami ); vips_streami_sanity( streami );
/* Pipes need to be converted to memory streams.
*/
if( streami->is_pipe &&
vips_streami_pipe_to_memory( streami ) )
return( NULL );
/* Memory source ... easy! /* Memory source ... easy!
*/ */
if( streami->blob ) { if( streami->blob ) {
@ -685,12 +722,6 @@ vips_streami_map( VipsStreami *streami, size_t *length_out )
data = vips_blob_get( streami->blob, &length ); data = vips_blob_get( streami->blob, &length );
} }
else if( streami->is_pipe ) {
if( vips_streami_read_whole_pipe( streami ) )
return( NULL );
data = vips_blob_get( streami->blob, &length );
}
else { else {
/* A streami that supports mmap. /* A streami that supports mmap.
*/ */
@ -734,7 +765,8 @@ vips_streami_seek( VipsStreami *streami, gint64 offset, int whence )
case SEEK_END: case SEEK_END:
if( streami->length == -1 && if( streami->length == -1 &&
vips_streami_read_whole_pipe( streami ) ) streami->is_pipe &&
vips_streami_pipe_to_memory( streami ) )
return( -1 ); return( -1 );
new_pos = streami->length + offset; new_pos = streami->length + offset;
@ -747,30 +779,19 @@ vips_streami_seek( VipsStreami *streami, gint64 offset, int whence )
break; break;
} }
/* Don't allow out of range seeks.
*/
if( new_pos < 0 ||
(streami->length != -1 && new_pos >= streami->length) ) {
vips_error( vips_stream_name( VIPS_STREAM( streami ) ),
_( "bad seek to %" G_GINT64_FORMAT ), new_pos );
return( -1 );
}
if( streami->is_pipe ) { if( streami->is_pipe ) {
/* We can seek on non-seekable streams during the header phase. if( vips_streami_pipe_read_to_position( streami, new_pos ) )
*/
if( streami->decode ) {
vips_error( STREAM_NAME( streami ),
"%s", _( "can't rewind after decode begins" ) );
return( -1 ); return( -1 );
} }
g_assert( streami->header_bytes );
/* We may not have read up to the new position.
*/
while( streami->read_position < new_pos ) {
unsigned char buffer[4096];
ssize_t read;
read = vips_streami_read( streami, buffer, 4096 );
if( read < 0 )
return( -1 );
if( read == 0 ) {
}
}
}
else { else {
if( (new_pos = class->seek( streami, offset, whence )) == -1 ) if( (new_pos = class->seek( streami, offset, whence )) == -1 )
return( -1 ); return( -1 );
@ -877,13 +898,12 @@ vips_streami_size( VipsStreami *streami )
vips_streami_sanity( streami ); vips_streami_sanity( streami );
if( stream->descriptor >= 0 && if( streami->length == -1 &&
(size = vips_file_length( stream->descriptor )) >= 0 ) streami->is_pipe &&
return( size ); vips_streami_pipe_to_memory( streami ) )
else if( streami->blob )
return( VIPS_AREA( streami->blob )->length );
else if( streami->header_bytes )
return( streami->header_bytes->len );
else
return( -1 ); return( -1 );
vips_streami_sanity( streami );
return( streami->length );
} }