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 )) )
return( -1 );
if( vips__jpeg_read_stream( source, out,
if( vips__jpeg_read_source( source, out,
header_only, shrink, fail_on_warn, FALSE ) ) {
VIPS_UNREF( source );
return( -1 );

View File

@ -490,7 +490,7 @@ vips_foreign_find_load_sub( VipsForeignLoadClass *load_class,
if( load_class->is_a &&
!vips_ispostfix( object_class->nickname, "_buffer" ) &&
!vips_ispostfix( object_class->nickname, "_stream" ) ) {
!vips_ispostfix( object_class->nickname, "_source" ) ) {
if( load_class->is_a( filename ) )
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 ) );
}
/* Can this VipsForeign open this stream?
/* Can this VipsForeign open this source?
*/
static void *
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 );
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
* 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:
* @source: stream to load from
* @source: source to load from
*
* 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:
* Searches for an operation you could use to load a source. To see the
* 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().
*
@ -676,7 +676,7 @@ vips_foreign_find_load_source( VipsSource *source )
vips_foreign_find_load_source_sub,
source, NULL )) ) {
vips_error( "VipsForeignLoad",
"%s", _( "stream is not in a known format" ) );
"%s", _( "source is not in a known format" ) );
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:
* @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
* 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
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
* 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.
*/
if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) &&
!vips_ispostfix( object_class->nickname, "_buffer" ) &&
!vips_ispostfix( object_class->nickname, "_stream" ) &&
!vips_ispostfix( object_class->nickname, "_target" ) &&
class->suffs &&
vips_filename_suffix_match( filename, class->suffs ) )
return( save_class );
@ -1898,7 +1898,7 @@ vips_foreign_save( VipsImage *in, const char *name, ... )
return( result );
}
/* Can this class write this filetype to a stream?
/* Can this class write this filetype to a target?
*/
static void *
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 );
if( class->suffs &&
vips_ispostfix( object_class->nickname, "_stream" ) &&
vips_ispostfix( object_class->nickname, "_target" ) &&
vips_filename_suffix_match( suffix, class->suffs ) )
return( save_class );
@ -1919,7 +1919,7 @@ vips_foreign_find_save_target_sub( VipsForeignSaveClass *save_class,
* vips_foreign_find_save_target:
* @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.
*
* 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,
(void *) suffix, NULL )) ) {
vips_error( "VipsForeignSave",
_( "\"%s\" is not a known stream format" ), name );
_( "\"%s\" is not a known target format" ), name );
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_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_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_load_tiff_file_get_type( void );
@ -2175,10 +2175,10 @@ vips_foreign_operation_init( void )
#ifdef HAVE_JPEG
vips_foreign_load_jpeg_file_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_buffer_get_type();
vips_foreign_save_jpeg_stream_get_type();
vips_foreign_save_jpeg_target_get_type();
vips_foreign_save_jpeg_mime_get_type();
#endif /*HAVE_JPEG*/

View File

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

View File

@ -136,7 +136,7 @@ vips_foreign_load_jpeg_header( VipsForeignLoad *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 ) )
return( -1 );
@ -148,7 +148,7 @@ vips_foreign_load_jpeg_load( VipsForeignLoad *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,
jpeg->autorotate ) )
return( -1 );
@ -204,31 +204,31 @@ vips_foreign_load_jpeg_init( VipsForeignLoadJpeg *jpeg )
jpeg->shrink = 1;
}
typedef struct _VipsForeignLoadJpegStream {
typedef struct _VipsForeignLoadJpegSource {
VipsForeignLoadJpeg parent_object;
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() );
static int
vips_foreign_load_jpeg_stream_build( VipsObject *object )
vips_foreign_load_jpeg_source_build( VipsObject *object )
{
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) object;
VipsForeignLoadJpegStream *stream =
(VipsForeignLoadJpegStream *) object;
VipsForeignLoadJpegSource *source =
(VipsForeignLoadJpegSource *) object;
if( stream->source ) {
jpeg->source = stream->source;
if( source->source ) {
jpeg->source = source->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 ) )
return( -1 );
@ -236,14 +236,14 @@ vips_foreign_load_jpeg_stream_build( VipsObject *object )
}
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
vips_foreign_load_jpeg_stream_class_init(
VipsForeignLoadJpegStreamClass *class )
vips_foreign_load_jpeg_source_class_init(
VipsForeignLoadJpegSourceClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( 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->get_property = vips_object_get_property;
object_class->nickname = "jpegload_stream";
object_class->description = _( "load image from jpeg stream" );
object_class->build = vips_foreign_load_jpeg_stream_build;
object_class->nickname = "jpegload_source";
object_class->description = _( "load image from jpeg source" );
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,
_( "Streami" ),
_( "Stream to load from" ),
_( "Source" ),
_( "Source to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadJpegStream, source ),
G_STRUCT_OFFSET( VipsForeignLoadJpegSource, source ),
VIPS_TYPE_SOURCE );
}
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 )) )
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 );
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 )) )
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 );
return( result );

View File

@ -216,31 +216,31 @@ vips_foreign_save_jpeg_init( VipsForeignSaveJpeg *jpeg )
jpeg->Q = 75;
}
typedef struct _VipsForeignSaveJpegStream {
typedef struct _VipsForeignSaveJpegTarget {
VipsForeignSaveJpeg parent_object;
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() );
static int
vips_foreign_save_jpeg_stream_build( VipsObject *object )
vips_foreign_save_jpeg_target_build( VipsObject *object )
{
VipsForeignSave *save = (VipsForeignSave *) object;
VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object;
VipsForeignSaveJpegStream *stream =
(VipsForeignSaveJpegStream *) object;
VipsForeignSaveJpegTarget *target =
(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 ) )
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->interlace, save->strip, jpeg->no_subsample,
jpeg->trellis_quant, jpeg->overshoot_deringing,
@ -251,8 +251,8 @@ vips_foreign_save_jpeg_stream_build( VipsObject *object )
}
static void
vips_foreign_save_jpeg_stream_class_init(
VipsForeignSaveJpegStreamClass *class )
vips_foreign_save_jpeg_target_class_init(
VipsForeignSaveJpegTargetClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( 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->get_property = vips_object_get_property;
object_class->nickname = "jpegsave_stream";
object_class->description = _( "save image to jpeg stream" );
object_class->build = vips_foreign_save_jpeg_stream_build;
object_class->nickname = "jpegsave_target";
object_class->description = _( "save image to jpeg target" );
object_class->build = vips_foreign_save_jpeg_target_build;
VIPS_ARG_OBJECT( class, "target", 1,
_( "Streamo" ),
_( "Stream to save to" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveJpegStream, target ),
G_STRUCT_OFFSET( VipsForeignSaveJpegTarget, target ),
VIPS_TYPE_TARGET );
}
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 )) )
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->interlace, save->strip, jpeg->no_subsample,
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()) )
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->interlace, save->strip, jpeg->no_subsample,
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()) )
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->interlace, save->strip, jpeg->no_subsample,
jpeg->trellis_quant, jpeg->overshoot_deringing,
@ -612,7 +612,7 @@ vips_jpegsave( VipsImage *in, const char *filename, ... )
/**
* vips_jpegsave_target: (method)
* @in: image to save
* @target: save image to this stream
* @target: save image to this target
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
@ -628,7 +628,7 @@ vips_jpegsave( VipsImage *in, const char *filename, ... )
* * @optimize_scans: %gboolean, split DCT coefficients into separate scans
* * @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().
*
@ -641,7 +641,7 @@ vips_jpegsave_target( VipsImage *in, VipsTarget *target, ... )
int result;
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 );
return( result );

View File

@ -157,16 +157,16 @@ extern const char *vips__rad_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,
gboolean optimize_coding, gboolean progressive, gboolean strip,
gboolean no_subsample, gboolean trellis_quant,
gboolean overshoot_deringing, gboolean optimize_scans,
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 );
int vips__isjpeg_stream( VipsSource *source );
int vips__isjpeg_source( VipsSource *source );
int vips__png_ispng_stream( VipsSource *source );
int vips__png_header_stream( VipsSource *source, VipsImage *out );

View File

@ -91,7 +91,7 @@
* 19/7/19
* - ignore large XMP
* 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.
*/
static void
stream_dest( j_compress_ptr cinfo, VipsTarget *target )
target_dest( j_compress_ptr cinfo, VipsTarget *target )
{
Dest *dest;
@ -771,7 +771,7 @@ stream_dest( j_compress_ptr cinfo, VipsTarget *target )
}
int
vips__jpeg_write_stream( VipsImage *in, VipsTarget *target,
vips__jpeg_write_target( VipsImage *in, VipsTarget *target,
int Q, const char *profile,
gboolean optimize_coding, gboolean progressive,
gboolean strip, gboolean no_subsample, gboolean trellis_quant,
@ -795,7 +795,7 @@ vips__jpeg_write_stream( VipsImage *in, VipsTarget *target,
/* Attach output.
*/
stream_dest( &write->cinfo, target );
target_dest( &write->cinfo, target );
/* Convert! Write errors come back here as an error return.
*/

View File

@ -3,9 +3,9 @@ noinst_LTLIBRARIES = libiofuncs.la
libiofuncs_la_SOURCES = \
connection.c \
source.c \
sourceuser.c \
sourcecustom.c \
target.c \
targetuser.c \
targetcustom.c \
bufis.c \
dbuf.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_morphology.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
class TestStream:
class TestConnection:
tempdir = None
@classmethod
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":
pytest.skip("tests cannot run with pyvips {}"
.format(pyvips.__version__))
@ -42,60 +42,60 @@ class TestStream:
cls.rad = None
cls.cmyk = None
def test_streami_new_from_file(self):
x = pyvips.Streami.new_from_file(JPEG_FILE)
def test_source_new_from_file(self):
x = pyvips.Source.new_from_file(JPEG_FILE)
assert x.filename() == JPEG_FILE
@skip_if_no("jpegload_stream")
def test_image_new_from_stream_file(self):
x = pyvips.Streami.new_from_file(JPEG_FILE)
y = pyvips.Image.new_from_stream(x, "")
@skip_if_no("jpegload_source")
def test_image_new_from_source_file(self):
x = pyvips.Source.new_from_file(JPEG_FILE)
y = pyvips.Image.new_from_source(x, "")
assert y.width == 290
assert y.height == 442
def test_streamo_new_to_file(self):
def test_target_new_to_file(self):
filename = temp_filename(self.tempdir, ".jpg")
x = pyvips.Streamo.new_to_file(filename)
x = pyvips.Target.new_to_file(filename)
assert x.filename() == filename
@skip_if_no("jpegload_stream")
def test_image_write_to_stream_file(self):
@skip_if_no("jpegload_source")
def test_image_write_to_target_file(self):
filename = temp_filename(self.tempdir, ".jpg")
x = pyvips.Streamo.new_to_file(filename)
self.colour.write_to_stream(x, ".jpg")
x = pyvips.Target.new_to_file(filename)
self.colour.write_to_target(x, ".jpg")
with open(filename, 'rb') as f:
data = f.read()
data2 = self.colour.write_to_buffer(".jpg")
assert data == data2
def test_streami_new_memory(self):
def test_source_new_memory(self):
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
@skip_if_no("jpegload_stream")
def test_image_new_from_stream_memory(self):
@skip_if_no("jpegload_source")
def test_image_new_from_source_memory(self):
data = self.colour.write_to_buffer(".jpg")
x = pyvips.Streami.new_from_memory(data)
y = pyvips.Image.new_from_stream(x, "")
x = pyvips.Source.new_from_memory(data)
y = pyvips.Image.new_from_source(x, "")
assert y.width == 290
assert y.height == 442
def test_streamo_new_memory(self):
x = pyvips.Streamo.new_to_memory()
def test_target_new_memory(self):
x = pyvips.Target.new_to_memory()
assert x.filename() == None
@skip_if_no("jpegload_stream")
def test_image_write_to_stream_filename(self):
x = pyvips.Streamo.new_to_memory()
self.colour.write_to_stream(x, ".jpg")
@skip_if_no("jpegload_source")
def test_image_write_to_target_memory(self):
x = pyvips.Target.new_to_memory()
self.colour.write_to_target(x, ".jpg")
y = self.colour.write_to_buffer(".jpg")
assert x.get("blob") == y