add plumbing for stream minimise
and ::finish becomes a vfunc
This commit is contained in:
parent
a8fd5602ea
commit
6f0002c023
@ -71,6 +71,11 @@ typedef enum {
|
||||
char *vips_path_filename7( const char *path );
|
||||
char *vips_path_mode7( const char *path );
|
||||
|
||||
struct _VipsImage;
|
||||
typedef struct _VipsImage VipsImage;
|
||||
struct _VipsRegion;
|
||||
typedef struct _VipsRegion VipsRegion;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -133,9 +133,6 @@ typedef enum {
|
||||
VIPS_ACCESS_LAST
|
||||
} VipsAccess;
|
||||
|
||||
struct _VipsImage;
|
||||
struct _VipsRegion;
|
||||
|
||||
typedef void *(*VipsStartFn)( struct _VipsImage *out, void *a, void *b );
|
||||
typedef int (*VipsGenerateFn)( struct _VipsRegion *out,
|
||||
void *seq, void *a, void *b, gboolean *stop );
|
||||
|
@ -68,7 +68,7 @@ typedef struct _VipsStream {
|
||||
*/
|
||||
int tracked_descriptor;
|
||||
|
||||
/* A descriptor we close close().
|
||||
/* A descriptor we close with close().
|
||||
*/
|
||||
int close_descriptor;
|
||||
|
||||
@ -86,8 +86,6 @@ typedef struct _VipsStreamClass {
|
||||
|
||||
GType vips_stream_get_type( void );
|
||||
|
||||
void vips_stream_attach( VipsStream *stream );
|
||||
|
||||
#define VIPS_TYPE_STREAM_INPUT (vips_stream_input_get_type())
|
||||
#define VIPS_STREAM_INPUT( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
||||
@ -162,6 +160,15 @@ typedef struct _VipsStreamInputClass {
|
||||
ssize_t (*read)( VipsStreamInput *, unsigned char *, size_t );
|
||||
int (*rewind)( VipsStreamInput * );
|
||||
|
||||
/* Shut down anything that can safely restarted. For example, if
|
||||
* there's a fd that supports lseek(), it can be closed, since later
|
||||
* (if neccessary) it can be reopened and lseek()ed back to the
|
||||
* correct point.
|
||||
*
|
||||
* Non-restartable shutdown shuld be in _finalize().
|
||||
*/
|
||||
void (*minimise)( VipsStreamInput * );
|
||||
|
||||
} VipsStreamInputClass;
|
||||
|
||||
GType vips_stream_input_get_type( void );
|
||||
@ -176,6 +183,8 @@ VipsStreamInput *vips_stream_input_new_from_options( const char *options );
|
||||
ssize_t vips_stream_input_read( VipsStreamInput *input,
|
||||
unsigned char *data, size_t length );
|
||||
int vips_stream_input_rewind( VipsStreamInput *input );
|
||||
void vips_stream_minimise( VipsStreamInput *input );
|
||||
void vips_stream_set_image( VipsStreamInput *input, VipsImage *image );
|
||||
void vips_stream_input_decode( VipsStreamInput *input );
|
||||
gboolean vips_stream_input_eof( VipsStreamInput *input );
|
||||
unsigned char *vips_stream_input_sniff( VipsStreamInput *input, size_t length );
|
||||
@ -219,6 +228,11 @@ typedef struct _VipsStreamOutputClass {
|
||||
*/
|
||||
ssize_t (*write)( VipsStreamOutput *, const unsigned char *, size_t );
|
||||
|
||||
/* A complete output image has been generated, so do any clearing up,
|
||||
* eg. copy the bytes we saved in memory to the output blob.
|
||||
*/
|
||||
void (*finish)( VipsStreamOutput * );
|
||||
|
||||
} VipsStreamOutputClass;
|
||||
|
||||
GType vips_stream_output_get_type( void );
|
||||
@ -226,7 +240,7 @@ GType vips_stream_output_get_type( void );
|
||||
VipsStreamOutput *vips_stream_output_new_from_descriptor( int descriptor );
|
||||
VipsStreamOutput *vips_stream_output_new_from_filename( const char *filename );
|
||||
VipsStreamOutput *vips_stream_output_new_memory( void );
|
||||
int vips_stream_output_write( VipsStreamOutput *stream,
|
||||
int vips_stream_output_write( VipsStreamOutput *output,
|
||||
const unsigned char *data, size_t length );
|
||||
void vips_stream_output_finish( VipsStreamOutput *output );
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/debug.h>
|
||||
@ -114,19 +115,10 @@
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsStream, vips_stream, VIPS_TYPE_OBJECT );
|
||||
|
||||
static void
|
||||
vips_stream_close( VipsStream *stream )
|
||||
{
|
||||
if( stream->close_descriptor >= 0 ) {
|
||||
close( stream->close_descriptor );
|
||||
stream->close_descriptor = -1;
|
||||
}
|
||||
|
||||
if( stream->tracked_descriptor >= 0 ) {
|
||||
vips_tracked_close( stream->tracked_descriptor );
|
||||
stream->tracked_descriptor = -1;
|
||||
}
|
||||
}
|
||||
#define STREAM_NAME( STREAM ) \
|
||||
(VIPS_STREAM( STREAM )->filename ? \
|
||||
VIPS_STREAM( STREAM )->filename : \
|
||||
VIPS_OBJECT( STREAM )->nickname)
|
||||
|
||||
static void
|
||||
vips_stream_finalize( GObject *gobject )
|
||||
@ -139,7 +131,16 @@ vips_stream_finalize( GObject *gobject )
|
||||
VIPS_DEBUG_MSG( "\n" );
|
||||
#endif /*VIPS_DEBUG*/
|
||||
|
||||
vips_stream_close( stream );
|
||||
if( stream->close_descriptor >= 0 ) {
|
||||
close( stream->close_descriptor );
|
||||
stream->close_descriptor = -1;
|
||||
}
|
||||
|
||||
if( stream->tracked_descriptor >= 0 ) {
|
||||
vips_tracked_close( stream->tracked_descriptor );
|
||||
stream->tracked_descriptor = -1;
|
||||
}
|
||||
|
||||
VIPS_FREE( stream->filename );
|
||||
|
||||
G_OBJECT_CLASS( vips_stream_parent_class )->finalize( gobject );
|
||||
@ -178,11 +179,6 @@ vips_stream_init( VipsStream *stream )
|
||||
stream->close_descriptor = -1;
|
||||
}
|
||||
|
||||
#define STREAM_NAME( STREAM ) \
|
||||
(VIPS_STREAM( STREAM )->filename ? \
|
||||
VIPS_STREAM( STREAM )->filename : \
|
||||
VIPS_OBJECT( STREAM )->nickname)
|
||||
|
||||
G_DEFINE_TYPE( VipsStreamInput, vips_stream_input, VIPS_TYPE_STREAM );
|
||||
|
||||
static void
|
||||
@ -313,6 +309,12 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_input_minimise_real( VipsStreamInput *input )
|
||||
{
|
||||
VIPS_DEBUG_MSG( "vips_stream_minimise_real:\n" );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_input_class_init( VipsStreamInputClass *class )
|
||||
{
|
||||
@ -330,6 +332,7 @@ vips_stream_input_class_init( VipsStreamInputClass *class )
|
||||
|
||||
class->read = vips_stream_input_read_real;
|
||||
class->rewind = vips_stream_input_rewind_real;
|
||||
class->minimise = vips_stream_input_minimise_real;
|
||||
|
||||
VIPS_ARG_BOXED( class, "blob", 3,
|
||||
_( "Blob" ),
|
||||
@ -572,6 +575,14 @@ vips_stream_input_rewind( VipsStreamInput *input )
|
||||
return( class->rewind( input ) );
|
||||
}
|
||||
|
||||
void
|
||||
vips_stream_input_minimise( VipsStreamInput *input )
|
||||
{
|
||||
VipsStreamInputClass *class = VIPS_STREAM_INPUT_GET_CLASS( input );
|
||||
|
||||
class->minimise( input );
|
||||
}
|
||||
|
||||
gboolean
|
||||
vips_stream_input_eof( VipsStreamInput *input )
|
||||
{
|
||||
@ -592,6 +603,19 @@ vips_stream_input_decode( VipsStreamInput *input )
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_input_minimise_cb( VipsImage *image, VipsStreamInput *input )
|
||||
{
|
||||
vips_stream_input_minimise( input );
|
||||
}
|
||||
|
||||
void
|
||||
vips_stream_input_set_image( VipsStreamInput *input, VipsImage *image )
|
||||
{
|
||||
g_signal_connect( image, "minimise",
|
||||
G_CALLBACK( vips_stream_input_minimise_cb ), input );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_stream_input_sniff:
|
||||
* @bytes: number of bytes to sniff
|
||||
@ -704,6 +728,25 @@ vips_stream_output_write_real( VipsStreamOutput *output,
|
||||
return( len );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_output_finish_real( VipsStreamOutput *output )
|
||||
{
|
||||
VIPS_DEBUG_MSG( "vips_stream_output_finish_real:\n" );
|
||||
|
||||
/* Move the output buffer into the blob so it can be read out.
|
||||
*/
|
||||
if( output->memory ) {
|
||||
unsigned char *data;
|
||||
size_t length;
|
||||
|
||||
length = output->memory->len;
|
||||
data = g_byte_array_free( output->memory, FALSE );
|
||||
output->memory = NULL;
|
||||
vips_blob_set( output->blob,
|
||||
(VipsCallbackFn) g_free, data, length );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_output_class_init( VipsStreamOutputClass *class )
|
||||
{
|
||||
@ -720,6 +763,7 @@ vips_stream_output_class_init( VipsStreamOutputClass *class )
|
||||
object_class->build = vips_stream_output_build;
|
||||
|
||||
class->write = vips_stream_output_write_real;
|
||||
class->finish = vips_stream_output_finish_real;
|
||||
|
||||
/* SET_ALWAYS means that blob is set by C and the obj system is not
|
||||
* involved in creation or destruction. It can be read at any time.
|
||||
@ -866,20 +910,11 @@ vips_stream_output_write( VipsStreamOutput *output,
|
||||
}
|
||||
|
||||
void
|
||||
vips_stream_output_finish( VipsStreamOutput *output )
|
||||
vips_stream_output_finish( VipsStreamOutput *output )
|
||||
{
|
||||
VipsStreamOutputClass *class = VIPS_STREAM_OUTPUT_GET_CLASS( output );
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_stream_output_finish:\n" );
|
||||
|
||||
if( output->memory ) {
|
||||
unsigned char *data;
|
||||
size_t length;
|
||||
|
||||
length = output->memory->len;
|
||||
data = g_byte_array_free( output->memory, FALSE );
|
||||
output->memory = NULL;
|
||||
vips_blob_set( output->blob,
|
||||
(VipsCallbackFn) g_free, data, length );
|
||||
}
|
||||
|
||||
vips_stream_close( VIPS_STREAM( output ) );
|
||||
class->finish( output );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user