add minimise support to VipsStreamInput
This commit is contained in:
parent
6f0002c023
commit
c01c3b9100
@ -335,6 +335,12 @@ readjpeg_close_cb( VipsObject *object, ReadJpeg *jpeg )
|
||||
(void) readjpeg_free( jpeg );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_input_minimise_cb( VipsImage *image, VipsStreamInput *input )
|
||||
{
|
||||
vips_stream_input_minimise( input );
|
||||
}
|
||||
|
||||
static ReadJpeg *
|
||||
readjpeg_new( VipsStreamInput *input, VipsImage *out,
|
||||
int shrink, gboolean fail, gboolean autorotate )
|
||||
@ -370,6 +376,8 @@ readjpeg_new( VipsStreamInput *input, VipsImage *out,
|
||||
|
||||
g_signal_connect( out, "close",
|
||||
G_CALLBACK( readjpeg_close_cb ), jpeg );
|
||||
g_signal_connect( out, "minimise",
|
||||
G_CALLBACK( vips_stream_input_minimise_cb ), input );
|
||||
|
||||
return( jpeg );
|
||||
}
|
||||
@ -777,11 +785,6 @@ read_jpeg_generate( VipsRegion *or,
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* We may have been minimised.
|
||||
*/
|
||||
if( readjpeg_open_input( jpeg ) )
|
||||
return( -1 );
|
||||
|
||||
/* If --fail is set, we make read fail on any warnings. This
|
||||
* will stop on any errors from the previous jpeg_read_scanlines().
|
||||
* libjpeg warnings are used for serious image corruption, like
|
||||
@ -946,6 +949,8 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
||||
*/
|
||||
vips_autorot_remove_angle( out );
|
||||
}
|
||||
|
||||
vips_stream_input_minimise( jpeg->input );
|
||||
}
|
||||
else {
|
||||
if( read_jpeg_image( jpeg, out ) )
|
||||
|
@ -122,10 +122,10 @@ typedef struct _VipsStreamInput {
|
||||
*/
|
||||
gboolean decode;
|
||||
|
||||
/* TRUE is this input source supports rewind. If not, then we save data
|
||||
/* TRUE is this descriptor supports lseek(). If not, then we save data
|
||||
* read during header phase in a buffer.
|
||||
*/
|
||||
gboolean rewindable;
|
||||
gboolean seekable;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
@ -183,8 +183,7 @@ 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_minimise( VipsStreamInput *input );
|
||||
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 );
|
||||
|
@ -121,16 +121,8 @@ G_DEFINE_ABSTRACT_TYPE( VipsStream, vips_stream, VIPS_TYPE_OBJECT );
|
||||
VIPS_OBJECT( STREAM )->nickname)
|
||||
|
||||
static void
|
||||
vips_stream_finalize( GObject *gobject )
|
||||
vips_stream_close( VipsStream *stream )
|
||||
{
|
||||
VipsStream *stream = (VipsStream *) gobject;
|
||||
|
||||
#ifdef VIPS_DEBUG
|
||||
VIPS_DEBUG_MSG( "vips_stream_finalize: " );
|
||||
vips_object_print_name( VIPS_OBJECT( gobject ) );
|
||||
VIPS_DEBUG_MSG( "\n" );
|
||||
#endif /*VIPS_DEBUG*/
|
||||
|
||||
if( stream->close_descriptor >= 0 ) {
|
||||
close( stream->close_descriptor );
|
||||
stream->close_descriptor = -1;
|
||||
@ -141,6 +133,21 @@ vips_stream_finalize( GObject *gobject )
|
||||
stream->tracked_descriptor = -1;
|
||||
}
|
||||
|
||||
stream->descriptor = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_stream_finalize( GObject *gobject )
|
||||
{
|
||||
VipsStream *stream = (VipsStream *) gobject;
|
||||
|
||||
#ifdef VIPS_DEBUG
|
||||
VIPS_DEBUG_MSG( "vips_stream_finalize: " );
|
||||
vips_object_print_name( VIPS_OBJECT( gobject ) );
|
||||
VIPS_DEBUG_MSG( "\n" );
|
||||
#endif /*VIPS_DEBUG*/
|
||||
|
||||
vips_stream_close( stream );
|
||||
VIPS_FREE( stream->filename );
|
||||
|
||||
G_OBJECT_CLASS( vips_stream_parent_class )->finalize( gobject );
|
||||
@ -192,6 +199,41 @@ vips_stream_input_finalize( GObject *gobject )
|
||||
G_OBJECT_CLASS( vips_stream_input_parent_class )->finalize( gobject );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_stream_input_open( VipsStreamInput *input )
|
||||
{
|
||||
VipsStream *stream = VIPS_STREAM( input );
|
||||
|
||||
if( stream->descriptor == -1 &&
|
||||
stream->tracked_descriptor == -1 &&
|
||||
stream->filename ) {
|
||||
int fd;
|
||||
off_t new_pos;
|
||||
|
||||
if( (fd = vips_tracked_open( stream->filename,
|
||||
MODE_READ )) == -1 ) {
|
||||
vips_error_system( errno, STREAM_NAME( stream ),
|
||||
"%s", _( "unable to open for read" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
stream->tracked_descriptor = fd;
|
||||
stream->descriptor = fd;
|
||||
input->seekable = TRUE;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_stream_input_open: "
|
||||
"restoring read position %zd\n", input->read_position );
|
||||
new_pos = lseek( stream->descriptor, 0, SEEK_SET );
|
||||
if( new_pos == -1 ) {
|
||||
vips_error_system( errno, STREAM_NAME( stream ),
|
||||
"%s", _( "unable to lseek()" ) );
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_stream_input_build( VipsObject *object )
|
||||
{
|
||||
@ -211,20 +253,9 @@ vips_stream_input_build( VipsObject *object )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips_object_argument_isset( object, "filename" ) ) {
|
||||
int fd;
|
||||
|
||||
if( (fd = vips_tracked_open( stream->filename,
|
||||
MODE_READ )) == -1 ) {
|
||||
vips_error_system( errno, STREAM_NAME( stream ),
|
||||
"%s", _( "unable to open for read" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
stream->tracked_descriptor = fd;
|
||||
stream->descriptor = fd;
|
||||
input->rewindable = TRUE;
|
||||
}
|
||||
if( vips_object_argument_isset( object, "filename" ) &&
|
||||
vips_stream_input_open( input ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_object_argument_isset( object, "descriptor" ) ) {
|
||||
stream->descriptor = dup( stream->descriptor );
|
||||
@ -232,11 +263,11 @@ vips_stream_input_build( VipsObject *object )
|
||||
}
|
||||
|
||||
if( vips_object_argument_isset( object, "blob" ) )
|
||||
input->rewindable = TRUE;
|
||||
input->seekable = TRUE;
|
||||
|
||||
/* Need to save the header if the source is not rewindable.
|
||||
/* Need to save the header if the source is not seekable.
|
||||
*/
|
||||
if( !input->rewindable )
|
||||
if( !input->seekable )
|
||||
input->header_bytes = g_byte_array_new();
|
||||
|
||||
/* We always want a sniff buffer.
|
||||
@ -254,6 +285,11 @@ vips_stream_input_read_real( VipsStreamInput *input,
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_stream_input_read_real:\n" );
|
||||
|
||||
/* Make sure we are open, in case we've been minimised.
|
||||
*/
|
||||
if( vips_stream_input_open( input ) )
|
||||
return( -1 );
|
||||
|
||||
if( input->blob ) {
|
||||
VipsArea *area = (VipsArea *) input->blob;
|
||||
ssize_t available = VIPS_MIN( length,
|
||||
@ -288,7 +324,7 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( input->rewindable &&
|
||||
if( input->seekable &&
|
||||
stream->descriptor != -1 ) {
|
||||
off_t new_pos;
|
||||
|
||||
@ -312,7 +348,12 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
||||
static void
|
||||
vips_stream_input_minimise_real( VipsStreamInput *input )
|
||||
{
|
||||
VIPS_DEBUG_MSG( "vips_stream_minimise_real:\n" );
|
||||
VipsStream *stream = VIPS_STREAM( input );
|
||||
|
||||
if( stream->filename &&
|
||||
stream->descriptor != -1 &&
|
||||
input->seekable )
|
||||
vips_stream_close( stream );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -341,11 +382,11 @@ vips_stream_input_class_init( VipsStreamInputClass *class )
|
||||
G_STRUCT_OFFSET( VipsStreamInput, blob ),
|
||||
VIPS_TYPE_BLOB );
|
||||
|
||||
VIPS_ARG_BOOL( class, "rewindable", 4,
|
||||
_( "rewindable" ),
|
||||
_( "'descriptor' supports rewind" ),
|
||||
VIPS_ARG_BOOL( class, "seekable", 4,
|
||||
_( "Seekable" ),
|
||||
_( "'descriptor' supports lseek()" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsStreamInput, rewindable ),
|
||||
G_STRUCT_OFFSET( VipsStreamInput, seekable ),
|
||||
FALSE );
|
||||
|
||||
}
|
||||
@ -544,11 +585,11 @@ vips_stream_input_read( VipsStreamInput *input,
|
||||
if( n == 0 )
|
||||
input->eof = TRUE;
|
||||
|
||||
/* If we're not rewindable, we need to save header bytes for
|
||||
/* If we're not seekable, we need to save header bytes for
|
||||
* reuse.
|
||||
*/
|
||||
if( input->header_bytes &&
|
||||
!input->rewindable &&
|
||||
!input->seekable &&
|
||||
!input->decode &&
|
||||
n > 0 )
|
||||
g_byte_array_append( input->header_bytes,
|
||||
@ -603,19 +644,6 @@ 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
|
||||
|
@ -7,10 +7,9 @@ set -e
|
||||
|
||||
. ./variables.sh
|
||||
|
||||
# reenable when we have minise support ini stream
|
||||
# if test_supported jpegload; then
|
||||
# ./test_descriptors $image
|
||||
# fi
|
||||
if test_supported jpegload; then
|
||||
./test_descriptors $image
|
||||
fi
|
||||
|
||||
if test_supported heifload; then
|
||||
./test_descriptors $test_images/Example1.heic
|
||||
|
Loading…
Reference in New Issue
Block a user