pytest passes again after stream -> source/target

This commit is contained in:
John Cupitt 2019-12-29 23:08:33 +00:00
parent 06b52da52a
commit 119dd2cb72
12 changed files with 118 additions and 358 deletions

View File

@ -116,7 +116,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
if( !(source = vips_source_new_from_file( filename )) ) if( !(source = vips_source_new_from_file( filename )) )
return( -1 ); return( -1 );
if( vips__jpeg_read_stream( source, out, if( vips__jpeg_read_source( source, out,
header_only, shrink, fail_on_warn, FALSE ) ) { header_only, shrink, fail_on_warn, FALSE ) ) {
VIPS_UNREF( source ); VIPS_UNREF( source );
return( -1 ); return( -1 );

View File

@ -490,7 +490,7 @@ vips_foreign_find_load_sub( VipsForeignLoadClass *load_class,
if( load_class->is_a && if( load_class->is_a &&
!vips_ispostfix( object_class->nickname, "_buffer" ) && !vips_ispostfix( object_class->nickname, "_buffer" ) &&
!vips_ispostfix( object_class->nickname, "_stream" ) ) { !vips_ispostfix( object_class->nickname, "_source" ) ) {
if( load_class->is_a( filename ) ) if( load_class->is_a( filename ) )
return( load_class ); return( load_class );
@ -629,7 +629,7 @@ vips_foreign_find_load_buffer( const void *data, size_t size )
return( G_OBJECT_CLASS_NAME( load_class ) ); return( G_OBJECT_CLASS_NAME( load_class ) );
} }
/* Can this VipsForeign open this stream? /* Can this VipsForeign open this source?
*/ */
static void * static void *
vips_foreign_find_load_source_sub( void *item, void *a, void *b ) vips_foreign_find_load_source_sub( void *item, void *a, void *b )
@ -639,7 +639,7 @@ vips_foreign_find_load_source_sub( void *item, void *a, void *b )
VipsSource *source = VIPS_SOURCE( a ); VipsSource *source = VIPS_SOURCE( a );
if( load_class->is_a_source && if( load_class->is_a_source &&
vips_ispostfix( object_class->nickname, "_stream" ) ) { vips_ispostfix( object_class->nickname, "_source" ) ) {
/* We may have done a read() rather than a sniff() in one of /* We may have done a read() rather than a sniff() in one of
* the is_a testers. Always rewind. * the is_a testers. Always rewind.
*/ */
@ -654,12 +654,12 @@ vips_foreign_find_load_source_sub( void *item, void *a, void *b )
/** /**
* vips_foreign_find_load_source: * vips_foreign_find_load_source:
* @source: stream to load from * @source: source 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 source. To see the
* range of buffer loaders supported by your vips, try something like: * range of source loaders supported by your vips, try something like:
* *
* vips -l | grep load_stream * vips -l | grep load_source
* *
* See also: vips_image_new_from_source(). * See also: vips_image_new_from_source().
* *
@ -676,7 +676,7 @@ vips_foreign_find_load_source( VipsSource *source )
vips_foreign_find_load_source_sub, vips_foreign_find_load_source_sub,
source, NULL )) ) { source, NULL )) ) {
vips_error( "VipsForeignLoad", vips_error( "VipsForeignLoad",
"%s", _( "stream is not in a known format" ) ); "%s", _( "source is not in a known format" ) );
return( NULL ); return( NULL );
} }
@ -739,12 +739,12 @@ vips_foreign_is_a_buffer( const char *loader, const void *data, size_t size )
/** /**
* vips_foreign_is_a_source: * vips_foreign_is_a_source:
* @loader: name of loader to use for test * @loader: name of loader to use for test
* @source: stream to test * @source: source to test
* *
* Return %TRUE if @source can be loaded by @loader. @loader is something * Return %TRUE if @source can be loaded by @loader. @loader is something
* like "tiffload_stream" or "VipsForeignLoadTiffStream". * like "tiffload_source" or "VipsForeignLoadTiffSource".
* *
* Returns: %TRUE if @data can be loaded by @stream. * Returns: %TRUE if @data can be loaded by @source.
*/ */
gboolean gboolean
vips_foreign_is_a_source( const char *loader, VipsSource *source ) vips_foreign_is_a_source( const char *loader, VipsSource *source )
@ -1755,12 +1755,12 @@ vips_foreign_find_save_sub( VipsForeignSaveClass *save_class,
/* The suffs might be defined on an abstract base class, make sure we /* The suffs might be defined on an abstract base class, make sure we
* don't pick that. * don't pick that.
* *
* Suffs can be defined on buffer and stream writers too. Make sure * Suffs can be defined on buffer and target writers too. Make sure
* it's not one of those. * it's not one of those.
*/ */
if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) && if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) &&
!vips_ispostfix( object_class->nickname, "_buffer" ) && !vips_ispostfix( object_class->nickname, "_buffer" ) &&
!vips_ispostfix( object_class->nickname, "_stream" ) && !vips_ispostfix( object_class->nickname, "_target" ) &&
class->suffs && class->suffs &&
vips_filename_suffix_match( filename, class->suffs ) ) vips_filename_suffix_match( filename, class->suffs ) )
return( save_class ); return( save_class );
@ -1898,7 +1898,7 @@ vips_foreign_save( VipsImage *in, const char *name, ... )
return( result ); return( result );
} }
/* Can this class write this filetype to a stream? /* Can this class write this filetype to a target?
*/ */
static void * static void *
vips_foreign_find_save_target_sub( VipsForeignSaveClass *save_class, vips_foreign_find_save_target_sub( VipsForeignSaveClass *save_class,
@ -1908,7 +1908,7 @@ vips_foreign_find_save_target_sub( VipsForeignSaveClass *save_class,
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class ); VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
if( class->suffs && if( class->suffs &&
vips_ispostfix( object_class->nickname, "_stream" ) && vips_ispostfix( object_class->nickname, "_target" ) &&
vips_filename_suffix_match( suffix, class->suffs ) ) vips_filename_suffix_match( suffix, class->suffs ) )
return( save_class ); return( save_class );
@ -1919,7 +1919,7 @@ vips_foreign_find_save_target_sub( VipsForeignSaveClass *save_class,
* vips_foreign_find_save_target: * vips_foreign_find_save_target:
* @suffix: format to find a saver for * @suffix: format to find a saver for
* *
* Searches for an operation you could use to write to a stream in @suffix * Searches for an operation you could use to write to a target in @suffix
* format. * format.
* *
* See also: vips_image_write_to_buffer(). * See also: vips_image_write_to_buffer().
@ -1940,7 +1940,7 @@ vips_foreign_find_save_target( const char *name )
(VipsSListMap2Fn) vips_foreign_find_save_target_sub, (VipsSListMap2Fn) vips_foreign_find_save_target_sub,
(void *) suffix, NULL )) ) { (void *) suffix, NULL )) ) {
vips_error( "VipsForeignSave", vips_error( "VipsForeignSave",
_( "\"%s\" is not a known stream format" ), name ); _( "\"%s\" is not a known target format" ), name );
return( NULL ); return( NULL );
} }
@ -2041,10 +2041,10 @@ vips_foreign_operation_init( void )
extern GType vips_foreign_load_jpeg_file_get_type( void ); extern GType vips_foreign_load_jpeg_file_get_type( void );
extern GType vips_foreign_load_jpeg_buffer_get_type( void ); extern GType vips_foreign_load_jpeg_buffer_get_type( void );
extern GType vips_foreign_load_jpeg_stream_get_type( void ); extern GType vips_foreign_load_jpeg_source_get_type( void );
extern GType vips_foreign_save_jpeg_file_get_type( void ); extern GType vips_foreign_save_jpeg_file_get_type( void );
extern GType vips_foreign_save_jpeg_buffer_get_type( void ); extern GType vips_foreign_save_jpeg_buffer_get_type( void );
extern GType vips_foreign_save_jpeg_stream_get_type( void ); extern GType vips_foreign_save_jpeg_target_get_type( void );
extern GType vips_foreign_save_jpeg_mime_get_type( void ); extern GType vips_foreign_save_jpeg_mime_get_type( void );
extern GType vips_foreign_load_tiff_file_get_type( void ); extern GType vips_foreign_load_tiff_file_get_type( void );
@ -2175,10 +2175,10 @@ vips_foreign_operation_init( void )
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
vips_foreign_load_jpeg_file_get_type(); vips_foreign_load_jpeg_file_get_type();
vips_foreign_load_jpeg_buffer_get_type(); vips_foreign_load_jpeg_buffer_get_type();
vips_foreign_load_jpeg_stream_get_type(); vips_foreign_load_jpeg_source_get_type();
vips_foreign_save_jpeg_file_get_type(); vips_foreign_save_jpeg_file_get_type();
vips_foreign_save_jpeg_buffer_get_type(); vips_foreign_save_jpeg_buffer_get_type();
vips_foreign_save_jpeg_stream_get_type(); vips_foreign_save_jpeg_target_get_type();
vips_foreign_save_jpeg_mime_get_type(); vips_foreign_save_jpeg_mime_get_type();
#endif /*HAVE_JPEG*/ #endif /*HAVE_JPEG*/

View File

@ -105,7 +105,7 @@
* 3/10/19 * 3/10/19
* - restart after minimise * - restart after minimise
* 14/10/19 * 14/10/19
* - revise for stream IO * - revise for source IO
*/ */
/* /*
@ -191,15 +191,15 @@ typedef struct _ReadJpeg {
int output_width; int output_width;
int output_height; int output_height;
/* The stream we read from. /* The source we read from.
*/ */
VipsSource *source; VipsSource *source;
} ReadJpeg; } ReadJpeg;
#define STREAM_BUFFER_SIZE (4096) #define SOURCE_BUFFER_SIZE (4096)
/* Private struct for stream input. /* Private struct for source input.
*/ */
typedef struct { typedef struct {
/* Public jpeg fields. /* Public jpeg fields.
@ -209,12 +209,12 @@ typedef struct {
/* Private stuff during read. /* Private stuff during read.
*/ */
VipsSource *source; VipsSource *source;
unsigned char buf[STREAM_BUFFER_SIZE]; unsigned char buf[SOURCE_BUFFER_SIZE];
} Source; } Source;
static void static void
stream_init_source( j_decompress_ptr cinfo ) source_init_source( j_decompress_ptr cinfo )
{ {
Source *src = (Source *) cinfo->src; Source *src = (Source *) cinfo->src;
@ -228,7 +228,7 @@ stream_init_source( j_decompress_ptr cinfo )
/* Fill the input buffer --- called whenever buffer is emptied. /* Fill the input buffer --- called whenever buffer is emptied.
*/ */
static boolean static boolean
stream_fill_input_buffer( j_decompress_ptr cinfo ) source_fill_input_buffer( j_decompress_ptr cinfo )
{ {
static const JOCTET eoi_buffer[4] = { static const JOCTET eoi_buffer[4] = {
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0 (JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
@ -239,7 +239,7 @@ stream_fill_input_buffer( j_decompress_ptr cinfo )
size_t read; size_t read;
if( (read = vips_source_read( src->source, if( (read = vips_source_read( src->source,
src->buf, STREAM_BUFFER_SIZE )) > 0 ) { src->buf, SOURCE_BUFFER_SIZE )) > 0 ) {
src->pub.next_input_byte = src->buf; src->pub.next_input_byte = src->buf;
src->pub.bytes_in_buffer = read; src->pub.bytes_in_buffer = read;
} }
@ -291,8 +291,8 @@ readjpeg_open_input( ReadJpeg *jpeg )
src = (Source *) cinfo->src; src = (Source *) cinfo->src;
src->source = jpeg->source; src->source = jpeg->source;
src->pub.init_source = stream_init_source; src->pub.init_source = source_init_source;
src->pub.fill_input_buffer = stream_fill_input_buffer; src->pub.fill_input_buffer = source_fill_input_buffer;
src->pub.resync_to_restart = jpeg_resync_to_restart; src->pub.resync_to_restart = jpeg_resync_to_restart;
src->pub.skip_input_data = skip_input_data; src->pub.skip_input_data = skip_input_data;
src->pub.bytes_in_buffer = 0; src->pub.bytes_in_buffer = 0;
@ -959,7 +959,7 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
} }
int int
vips__jpeg_read_stream( VipsSource *source, VipsImage *out, vips__jpeg_read_source( VipsSource *source, VipsImage *out,
gboolean header_only, int shrink, int fail, gboolean autorotate ) gboolean header_only, int shrink, int fail, gboolean autorotate )
{ {
ReadJpeg *jpeg; ReadJpeg *jpeg;
@ -985,7 +985,7 @@ vips__jpeg_read_stream( VipsSource *source, VipsImage *out,
} }
int int
vips__isjpeg_stream( VipsSource *source ) vips__isjpeg_source( VipsSource *source )
{ {
const unsigned char *p; const unsigned char *p;

View File

@ -136,7 +136,7 @@ vips_foreign_load_jpeg_header( VipsForeignLoad *load )
{ {
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load; VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
if( vips__jpeg_read_stream( jpeg->source, if( vips__jpeg_read_source( jpeg->source,
load->out, TRUE, jpeg->shrink, load->fail, jpeg->autorotate ) ) load->out, TRUE, jpeg->shrink, load->fail, jpeg->autorotate ) )
return( -1 ); return( -1 );
@ -148,7 +148,7 @@ vips_foreign_load_jpeg_load( VipsForeignLoad *load )
{ {
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load; VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
if( vips__jpeg_read_stream( jpeg->source, if( vips__jpeg_read_source( jpeg->source,
load->real, FALSE, jpeg->shrink, load->fail, load->real, FALSE, jpeg->shrink, load->fail,
jpeg->autorotate ) ) jpeg->autorotate ) )
return( -1 ); return( -1 );
@ -204,31 +204,31 @@ vips_foreign_load_jpeg_init( VipsForeignLoadJpeg *jpeg )
jpeg->shrink = 1; jpeg->shrink = 1;
} }
typedef struct _VipsForeignLoadJpegStream { typedef struct _VipsForeignLoadJpegSource {
VipsForeignLoadJpeg parent_object; VipsForeignLoadJpeg parent_object;
VipsSource *source; VipsSource *source;
} VipsForeignLoadJpegStream; } VipsForeignLoadJpegSource;
typedef VipsForeignLoadJpegClass VipsForeignLoadJpegStreamClass; typedef VipsForeignLoadJpegClass VipsForeignLoadJpegSourceClass;
G_DEFINE_TYPE( VipsForeignLoadJpegStream, vips_foreign_load_jpeg_stream, G_DEFINE_TYPE( VipsForeignLoadJpegSource, vips_foreign_load_jpeg_source,
vips_foreign_load_jpeg_get_type() ); vips_foreign_load_jpeg_get_type() );
static int static int
vips_foreign_load_jpeg_stream_build( VipsObject *object ) vips_foreign_load_jpeg_source_build( VipsObject *object )
{ {
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) object; VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) object;
VipsForeignLoadJpegStream *stream = VipsForeignLoadJpegSource *source =
(VipsForeignLoadJpegStream *) object; (VipsForeignLoadJpegSource *) object;
if( stream->source ) { if( source->source ) {
jpeg->source = stream->source; jpeg->source = source->source;
g_object_ref( jpeg->source ); g_object_ref( jpeg->source );
} }
if( VIPS_OBJECT_CLASS( vips_foreign_load_jpeg_stream_parent_class )-> if( VIPS_OBJECT_CLASS( vips_foreign_load_jpeg_source_parent_class )->
build( object ) ) build( object ) )
return( -1 ); return( -1 );
@ -236,14 +236,14 @@ vips_foreign_load_jpeg_stream_build( VipsObject *object )
} }
static gboolean static gboolean
vips_foreign_load_jpeg_stream_is_a_source( VipsSource *source ) vips_foreign_load_jpeg_source_is_a_source( VipsSource *source )
{ {
return( vips__isjpeg_stream( source ) ); return( vips__isjpeg_source( source ) );
} }
static void static void
vips_foreign_load_jpeg_stream_class_init( vips_foreign_load_jpeg_source_class_init(
VipsForeignLoadJpegStreamClass *class ) VipsForeignLoadJpegSourceClass *class )
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS( class ); GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class; VipsObjectClass *object_class = (VipsObjectClass *) class;
@ -252,23 +252,23 @@ vips_foreign_load_jpeg_stream_class_init(
gobject_class->set_property = vips_object_set_property; gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property; gobject_class->get_property = vips_object_get_property;
object_class->nickname = "jpegload_stream"; object_class->nickname = "jpegload_source";
object_class->description = _( "load image from jpeg stream" ); object_class->description = _( "load image from jpeg source" );
object_class->build = vips_foreign_load_jpeg_stream_build; object_class->build = vips_foreign_load_jpeg_source_build;
load_class->is_a_source = vips_foreign_load_jpeg_stream_is_a_source; load_class->is_a_source = vips_foreign_load_jpeg_source_is_a_source;
VIPS_ARG_OBJECT( class, "source", 1, VIPS_ARG_OBJECT( class, "source", 1,
_( "Streami" ), _( "Source" ),
_( "Stream to load from" ), _( "Source to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT, VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadJpegStream, source ), G_STRUCT_OFFSET( VipsForeignLoadJpegSource, source ),
VIPS_TYPE_SOURCE ); VIPS_TYPE_SOURCE );
} }
static void static void
vips_foreign_load_jpeg_stream_init( VipsForeignLoadJpegStream *stream ) vips_foreign_load_jpeg_source_init( VipsForeignLoadJpegSource *source )
{ {
} }
@ -310,7 +310,7 @@ vips_foreign_load_jpeg_file_is_a( const char *filename )
if( !(source = vips_source_new_from_file( filename )) ) if( !(source = vips_source_new_from_file( filename )) )
return( FALSE ); return( FALSE );
result = vips_foreign_load_jpeg_stream_is_a_source( source ); result = vips_foreign_load_jpeg_source_is_a_source( source );
VIPS_UNREF( source ); VIPS_UNREF( source );
return( result ); return( result );
@ -388,7 +388,7 @@ vips_foreign_load_jpeg_buffer_is_a_buffer( const void *buf, size_t len )
if( !(source = vips_source_new_from_memory( buf, len )) ) if( !(source = vips_source_new_from_memory( buf, len )) )
return( FALSE ); return( FALSE );
result = vips_foreign_load_jpeg_stream_is_a_source( source ); result = vips_foreign_load_jpeg_source_is_a_source( source );
VIPS_UNREF( source ); VIPS_UNREF( source );
return( result ); return( result );

View File

@ -216,31 +216,31 @@ vips_foreign_save_jpeg_init( VipsForeignSaveJpeg *jpeg )
jpeg->Q = 75; jpeg->Q = 75;
} }
typedef struct _VipsForeignSaveJpegStream { typedef struct _VipsForeignSaveJpegTarget {
VipsForeignSaveJpeg parent_object; VipsForeignSaveJpeg parent_object;
VipsTarget *target; VipsTarget *target;
} VipsForeignSaveJpegStream; } VipsForeignSaveJpegTarget;
typedef VipsForeignSaveJpegClass VipsForeignSaveJpegStreamClass; typedef VipsForeignSaveJpegClass VipsForeignSaveJpegTargetClass;
G_DEFINE_TYPE( VipsForeignSaveJpegStream, vips_foreign_save_jpeg_stream, G_DEFINE_TYPE( VipsForeignSaveJpegTarget, vips_foreign_save_jpeg_target,
vips_foreign_save_jpeg_get_type() ); vips_foreign_save_jpeg_get_type() );
static int static int
vips_foreign_save_jpeg_stream_build( VipsObject *object ) vips_foreign_save_jpeg_target_build( VipsObject *object )
{ {
VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSave *save = (VipsForeignSave *) object;
VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object; VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object;
VipsForeignSaveJpegStream *stream = VipsForeignSaveJpegTarget *target =
(VipsForeignSaveJpegStream *) object; (VipsForeignSaveJpegTarget *) object;
if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_stream_parent_class )-> if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_target_parent_class )->
build( object ) ) build( object ) )
return( -1 ); return( -1 );
if( vips__jpeg_write_stream( save->ready, stream->target, if( vips__jpeg_write_target( save->ready, target->target,
jpeg->Q, jpeg->profile, jpeg->optimize_coding, jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample, jpeg->interlace, save->strip, jpeg->no_subsample,
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->trellis_quant, jpeg->overshoot_deringing,
@ -251,8 +251,8 @@ vips_foreign_save_jpeg_stream_build( VipsObject *object )
} }
static void static void
vips_foreign_save_jpeg_stream_class_init( vips_foreign_save_jpeg_target_class_init(
VipsForeignSaveJpegStreamClass *class ) VipsForeignSaveJpegTargetClass *class )
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS( class ); GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class; VipsObjectClass *object_class = (VipsObjectClass *) class;
@ -260,21 +260,21 @@ vips_foreign_save_jpeg_stream_class_init(
gobject_class->set_property = vips_object_set_property; gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property; gobject_class->get_property = vips_object_get_property;
object_class->nickname = "jpegsave_stream"; object_class->nickname = "jpegsave_target";
object_class->description = _( "save image to jpeg stream" ); object_class->description = _( "save image to jpeg target" );
object_class->build = vips_foreign_save_jpeg_stream_build; object_class->build = vips_foreign_save_jpeg_target_build;
VIPS_ARG_OBJECT( class, "target", 1, VIPS_ARG_OBJECT( class, "target", 1,
_( "Streamo" ), _( "Streamo" ),
_( "Stream to save to" ), _( "Stream to save to" ),
VIPS_ARGUMENT_REQUIRED_INPUT, VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveJpegStream, target ), G_STRUCT_OFFSET( VipsForeignSaveJpegTarget, target ),
VIPS_TYPE_TARGET ); VIPS_TYPE_TARGET );
} }
static void static void
vips_foreign_save_jpeg_stream_init( VipsForeignSaveJpegStream *stream ) vips_foreign_save_jpeg_target_init( VipsForeignSaveJpegTarget *target )
{ {
} }
@ -307,7 +307,7 @@ vips_foreign_save_jpeg_file_build( VipsObject *object )
if( !(target = vips_target_new_to_file( file->filename )) ) if( !(target = vips_target_new_to_file( file->filename )) )
return( -1 ); return( -1 );
if( vips__jpeg_write_stream( save->ready, target, if( vips__jpeg_write_target( save->ready, target,
jpeg->Q, jpeg->profile, jpeg->optimize_coding, jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample, jpeg->interlace, save->strip, jpeg->no_subsample,
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->trellis_quant, jpeg->overshoot_deringing,
@ -377,7 +377,7 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object )
if( !(target = vips_target_new_to_memory()) ) if( !(target = vips_target_new_to_memory()) )
return( -1 ); return( -1 );
if( vips__jpeg_write_stream( save->ready, target, if( vips__jpeg_write_target( save->ready, target,
jpeg->Q, jpeg->profile, jpeg->optimize_coding, jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample, jpeg->interlace, save->strip, jpeg->no_subsample,
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->trellis_quant, jpeg->overshoot_deringing,
@ -450,7 +450,7 @@ vips_foreign_save_jpeg_mime_build( VipsObject *object )
if( !(target = vips_target_new_to_memory()) ) if( !(target = vips_target_new_to_memory()) )
return( -1 ); return( -1 );
if( vips__jpeg_write_stream( save->ready, target, if( vips__jpeg_write_target( save->ready, target,
jpeg->Q, jpeg->profile, jpeg->optimize_coding, jpeg->Q, jpeg->profile, jpeg->optimize_coding,
jpeg->interlace, save->strip, jpeg->no_subsample, jpeg->interlace, save->strip, jpeg->no_subsample,
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->trellis_quant, jpeg->overshoot_deringing,
@ -612,7 +612,7 @@ vips_jpegsave( VipsImage *in, const char *filename, ... )
/** /**
* vips_jpegsave_target: (method) * vips_jpegsave_target: (method)
* @in: image to save * @in: image to save
* @target: save image to this stream * @target: save image to this target
* @...: %NULL-terminated list of optional named arguments * @...: %NULL-terminated list of optional named arguments
* *
* Optional arguments: * Optional arguments:
@ -628,7 +628,7 @@ vips_jpegsave( VipsImage *in, const char *filename, ... )
* * @optimize_scans: %gboolean, split DCT coefficients into separate scans * * @optimize_scans: %gboolean, split DCT coefficients into separate scans
* * @quant_table: %gint, quantization table index * * @quant_table: %gint, quantization table index
* *
* As vips_jpegsave(), but save to a stream. * As vips_jpegsave(), but save to a target.
* *
* See also: vips_jpegsave(), vips_image_write_to_target(). * See also: vips_jpegsave(), vips_image_write_to_target().
* *
@ -641,7 +641,7 @@ vips_jpegsave_target( VipsImage *in, VipsTarget *target, ... )
int result; int result;
va_start( ap, target ); va_start( ap, target );
result = vips_call_split( "jpegsave_stream", ap, in, target ); result = vips_call_split( "jpegsave_target", ap, in, target );
va_end( ap ); va_end( ap );
return( result ); return( result );

View File

@ -157,16 +157,16 @@ 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, VipsTarget *target, int vips__jpeg_write_target( VipsImage *in, VipsTarget *target,
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( VipsSource *source, VipsImage *out, int vips__jpeg_read_source( VipsSource *source, VipsImage *out,
gboolean header_only, int shrink, int fail, gboolean autorotate ); gboolean header_only, int shrink, int fail, gboolean autorotate );
int vips__isjpeg_stream( VipsSource *source ); int vips__isjpeg_source( VipsSource *source );
int vips__png_ispng_stream( VipsSource *source ); int vips__png_ispng_stream( VipsSource *source );
int vips__png_header_stream( VipsSource *source, VipsImage *out ); int vips__png_header_stream( VipsSource *source, VipsImage *out );

View File

@ -91,7 +91,7 @@
* 19/7/19 * 19/7/19
* - ignore large XMP * - ignore large XMP
* 14/10/19 * 14/10/19
* - revise for stream IO * - revise for target IO
*/ */
/* /*
@ -752,7 +752,7 @@ term_destination( j_compress_ptr cinfo )
/* Set dest to one of our objects. /* Set dest to one of our objects.
*/ */
static void static void
stream_dest( j_compress_ptr cinfo, VipsTarget *target ) target_dest( j_compress_ptr cinfo, VipsTarget *target )
{ {
Dest *dest; Dest *dest;
@ -771,7 +771,7 @@ stream_dest( j_compress_ptr cinfo, VipsTarget *target )
} }
int int
vips__jpeg_write_stream( VipsImage *in, VipsTarget *target, vips__jpeg_write_target( VipsImage *in, VipsTarget *target,
int Q, const char *profile, int Q, const char *profile,
gboolean optimize_coding, gboolean progressive, gboolean optimize_coding, gboolean progressive,
gboolean strip, gboolean no_subsample, gboolean trellis_quant, gboolean strip, gboolean no_subsample, gboolean trellis_quant,
@ -795,7 +795,7 @@ vips__jpeg_write_stream( VipsImage *in, VipsTarget *target,
/* Attach output. /* Attach output.
*/ */
stream_dest( &write->cinfo, target ); target_dest( &write->cinfo, target );
/* Convert! Write errors come back here as an error return. /* Convert! Write errors come back here as an error return.
*/ */

View File

@ -3,9 +3,9 @@ noinst_LTLIBRARIES = libiofuncs.la
libiofuncs_la_SOURCES = \ libiofuncs_la_SOURCES = \
connection.c \ connection.c \
source.c \ source.c \
sourceuser.c \ sourcecustom.c \
target.c \ target.c \
targetuser.c \ targetcustom.c \
bufis.c \ bufis.c \
dbuf.c \ dbuf.c \
reorder.c \ reorder.c \

View File

@ -1,240 +0,0 @@
/* A Streami subclass with signals you can easily hook up to other input
* sources.
*
* J.Cupitt, 21/11/19
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
/*
#define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /*HAVE_UNISTD_H*/
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/debug.h>
#include "vipsmarshal.h"
G_DEFINE_TYPE( VipsSourceCustom, vips_source_custom, VIPS_TYPE_SOURCE );
/* Our signals.
*/
enum {
SIG_SEEK,
SIG_READ,
SIG_LAST
};
static guint vips_source_custom_signals[SIG_LAST] = { 0 };
static gint64
vips_source_custom_read_real( VipsSource *source,
void *buffer, size_t length )
{
gint64 bytes_read;
VIPS_DEBUG_MSG( "vips_source_custom_read_real:\n" );
/* Return this value (error) if there's no attached handler.
*/
bytes_read = 0;
g_signal_emit( source, vips_source_custom_signals[SIG_READ], 0,
buffer, (gint64) length, &bytes_read );
VIPS_DEBUG_MSG( " vips_source_custom_read_real, seen %zd bytes\n",
bytes_read );
return( bytes_read );
}
static gint64
vips_source_custom_seek_real( VipsSource *source,
gint64 offset, int whence )
{
GValue args[3] = { { 0 } };
GValue result = { 0 };
gint64 new_position;
VIPS_DEBUG_MSG( "vips_source_custom_seek_real:\n" );
/* Set the signal args.
*/
g_value_init( &args[0], G_TYPE_OBJECT );
g_value_set_object( &args[0], source );
g_value_init( &args[1], G_TYPE_INT64 );
g_value_set_int64( &args[1], offset );
g_value_init( &args[2], G_TYPE_INT );
g_value_set_int( &args[2], whence );
/* Set the default value if no handlers are attached.
*/
g_value_init( &result, G_TYPE_INT64 );
g_value_set_int64( &result, -1 );
/* We need to use this signal interface since we want a default value
* if no handlers are attached.
*/
g_signal_emitv( (const GValue *) &args,
vips_source_custom_signals[SIG_SEEK], 0, &result );
new_position = g_value_get_int64( &result );
g_value_unset( &args[0] );
g_value_unset( &args[1] );
g_value_unset( &args[2] );
g_value_unset( &result );
VIPS_DEBUG_MSG( " vips_source_custom_seek_real, seen new pos %zd\n",
new_position );
return( new_position );
}
static gint64
vips_source_custom_read_signal_real( VipsSourceCustom *source_custom,
void *data, gint64 length )
{
VIPS_DEBUG_MSG( "vips_source_custom_read_signal_real:\n" );
return( 0 );
}
static gint64
vips_source_custom_seek_signal_real( VipsSourceCustom *source_custom,
gint64 offset, int whence )
{
VIPS_DEBUG_MSG( "vips_source_custom_seek_signal_real:\n" );
return( -1 );
}
static void
vips_source_custom_class_init( VipsSourceCustomClass *class )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
VipsSourceClass *source_class = VIPS_SOURCE_CLASS( class );
object_class->nickname = "source_custom";
object_class->description = _( "input stream" );
source_class->read = vips_source_custom_read_real;
source_class->seek = vips_source_custom_seek_real;
class->read = vips_source_custom_read_signal_real;
class->seek = vips_source_custom_seek_signal_real;
/**
* VipsSourceCustom::read:
* @source_custom: the stream being operated on
* @buffer: %gpointer, buffer to fill
* @size: %gint64, size of buffer
*
* This signal is emitted to read bytes from the source into @buffer.
*
* Returns: the number of bytes read.
*/
vips_source_custom_signals[SIG_READ] = g_signal_new( "read",
G_TYPE_FROM_CLASS( class ),
G_SIGNAL_ACTION,
G_STRUCT_OFFSET( VipsSourceCustomClass, read ),
NULL, NULL,
vips_INT64__POINTER_INT64,
G_TYPE_INT64, 2,
G_TYPE_POINTER, G_TYPE_INT64 );
/**
* VipsSourceCustom::seek:
* @source_custom: the stream being operated on
* @offset: %gint64, seek offset
* @whence: %gint, seek origin
*
* This signal is emitted to seek the stream. The handler should
* change the stream position appropriately.
*
* The handler on an unseekable stream should always return -1.
*
* Returns: the new seek position.
*/
vips_source_custom_signals[SIG_SEEK] = g_signal_new( "seek",
G_TYPE_FROM_CLASS( class ),
G_SIGNAL_ACTION,
G_STRUCT_OFFSET( VipsSourceCustomClass, seek ),
NULL, NULL,
vips_INT64__INT64_INT,
G_TYPE_INT64, 2,
G_TYPE_INT64, G_TYPE_INT );
}
static void
vips_source_custom_init( VipsSourceCustom *source_custom )
{
}
/**
* vips_source_custom_new:
*
* Create a #VipsSourceCustom. Attach signals to implement read and seek.
*
* Returns: a new #VipsSourceCustom
*/
VipsSourceCustom *
vips_source_custom_new( void )
{
VipsSourceCustom *source_custom;
VIPS_DEBUG_MSG( "vips_source_custom_new:\n" );
source_custom = VIPS_SOURCE_CUSTOM( g_object_new( VIPS_TYPE_SOURCE_CUSTOM, NULL ) );
if( vips_object_build( VIPS_OBJECT( source_custom ) ) ) {
VIPS_UNREF( source_custom );
return( NULL );
}
return( source_custom );
}

View File

@ -16,6 +16,6 @@ EXTRA_DIST = \
test_iofuncs.py \ test_iofuncs.py \
test_morphology.py \ test_morphology.py \
test_resample.py \ test_resample.py \
test_stream.py test_connection.py

View File

@ -12,12 +12,12 @@ from helpers import \
temp_filename, assert_almost_equal_objects, have, skip_if_no temp_filename, assert_almost_equal_objects, have, skip_if_no
class TestStream: class TestConnection:
tempdir = None tempdir = None
@classmethod @classmethod
def setup_class(cls): def setup_class(cls):
# for now, only run these tests if we have the stream pyvips installed # for now, only run these tests if we have the source pyvips installed
if pyvips.__version__ != "2.1.10": if pyvips.__version__ != "2.1.10":
pytest.skip("tests cannot run with pyvips {}" pytest.skip("tests cannot run with pyvips {}"
.format(pyvips.__version__)) .format(pyvips.__version__))
@ -42,60 +42,60 @@ class TestStream:
cls.rad = None cls.rad = None
cls.cmyk = None cls.cmyk = None
def test_streami_new_from_file(self): def test_source_new_from_file(self):
x = pyvips.Streami.new_from_file(JPEG_FILE) x = pyvips.Source.new_from_file(JPEG_FILE)
assert x.filename() == JPEG_FILE assert x.filename() == JPEG_FILE
@skip_if_no("jpegload_stream") @skip_if_no("jpegload_source")
def test_image_new_from_stream_file(self): def test_image_new_from_source_file(self):
x = pyvips.Streami.new_from_file(JPEG_FILE) x = pyvips.Source.new_from_file(JPEG_FILE)
y = pyvips.Image.new_from_stream(x, "") y = pyvips.Image.new_from_source(x, "")
assert y.width == 290 assert y.width == 290
assert y.height == 442 assert y.height == 442
def test_streamo_new_to_file(self): def test_target_new_to_file(self):
filename = temp_filename(self.tempdir, ".jpg") filename = temp_filename(self.tempdir, ".jpg")
x = pyvips.Streamo.new_to_file(filename) x = pyvips.Target.new_to_file(filename)
assert x.filename() == filename assert x.filename() == filename
@skip_if_no("jpegload_stream") @skip_if_no("jpegload_source")
def test_image_write_to_stream_file(self): def test_image_write_to_target_file(self):
filename = temp_filename(self.tempdir, ".jpg") filename = temp_filename(self.tempdir, ".jpg")
x = pyvips.Streamo.new_to_file(filename) x = pyvips.Target.new_to_file(filename)
self.colour.write_to_stream(x, ".jpg") self.colour.write_to_target(x, ".jpg")
with open(filename, 'rb') as f: with open(filename, 'rb') as f:
data = f.read() data = f.read()
data2 = self.colour.write_to_buffer(".jpg") data2 = self.colour.write_to_buffer(".jpg")
assert data == data2 assert data == data2
def test_streami_new_memory(self): def test_source_new_memory(self):
data = self.colour.write_to_buffer(".jpg") data = self.colour.write_to_buffer(".jpg")
x = pyvips.Streami.new_from_memory(data) x = pyvips.Source.new_from_memory(data)
assert x.filename() == None assert x.filename() == None
@skip_if_no("jpegload_stream") @skip_if_no("jpegload_source")
def test_image_new_from_stream_memory(self): def test_image_new_from_source_memory(self):
data = self.colour.write_to_buffer(".jpg") data = self.colour.write_to_buffer(".jpg")
x = pyvips.Streami.new_from_memory(data) x = pyvips.Source.new_from_memory(data)
y = pyvips.Image.new_from_stream(x, "") y = pyvips.Image.new_from_source(x, "")
assert y.width == 290 assert y.width == 290
assert y.height == 442 assert y.height == 442
def test_streamo_new_memory(self): def test_target_new_memory(self):
x = pyvips.Streamo.new_to_memory() x = pyvips.Target.new_to_memory()
assert x.filename() == None assert x.filename() == None
@skip_if_no("jpegload_stream") @skip_if_no("jpegload_source")
def test_image_write_to_stream_filename(self): def test_image_write_to_target_memory(self):
x = pyvips.Streamo.new_to_memory() x = pyvips.Target.new_to_memory()
self.colour.write_to_stream(x, ".jpg") self.colour.write_to_target(x, ".jpg")
y = self.colour.write_to_buffer(".jpg") y = self.colour.write_to_buffer(".jpg")
assert x.get("blob") == y assert x.get("blob") == y