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 );
|
(void) readjpeg_free( jpeg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_stream_input_minimise_cb( VipsImage *image, VipsStreamInput *input )
|
||||||
|
{
|
||||||
|
vips_stream_input_minimise( input );
|
||||||
|
}
|
||||||
|
|
||||||
static ReadJpeg *
|
static ReadJpeg *
|
||||||
readjpeg_new( VipsStreamInput *input, VipsImage *out,
|
readjpeg_new( VipsStreamInput *input, VipsImage *out,
|
||||||
int shrink, gboolean fail, gboolean autorotate )
|
int shrink, gboolean fail, gboolean autorotate )
|
||||||
@ -370,6 +376,8 @@ readjpeg_new( VipsStreamInput *input, VipsImage *out,
|
|||||||
|
|
||||||
g_signal_connect( out, "close",
|
g_signal_connect( out, "close",
|
||||||
G_CALLBACK( readjpeg_close_cb ), jpeg );
|
G_CALLBACK( readjpeg_close_cb ), jpeg );
|
||||||
|
g_signal_connect( out, "minimise",
|
||||||
|
G_CALLBACK( vips_stream_input_minimise_cb ), input );
|
||||||
|
|
||||||
return( jpeg );
|
return( jpeg );
|
||||||
}
|
}
|
||||||
@ -777,11 +785,6 @@ read_jpeg_generate( VipsRegion *or,
|
|||||||
return( -1 );
|
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
|
/* If --fail is set, we make read fail on any warnings. This
|
||||||
* will stop on any errors from the previous jpeg_read_scanlines().
|
* will stop on any errors from the previous jpeg_read_scanlines().
|
||||||
* libjpeg warnings are used for serious image corruption, like
|
* 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_autorot_remove_angle( out );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vips_stream_input_minimise( jpeg->input );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( read_jpeg_image( jpeg, out ) )
|
if( read_jpeg_image( jpeg, out ) )
|
||||||
|
@ -122,10 +122,10 @@ typedef struct _VipsStreamInput {
|
|||||||
*/
|
*/
|
||||||
gboolean decode;
|
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.
|
* read during header phase in a buffer.
|
||||||
*/
|
*/
|
||||||
gboolean rewindable;
|
gboolean seekable;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
||||||
@ -183,8 +183,7 @@ VipsStreamInput *vips_stream_input_new_from_options( const char *options );
|
|||||||
ssize_t vips_stream_input_read( VipsStreamInput *input,
|
ssize_t vips_stream_input_read( VipsStreamInput *input,
|
||||||
unsigned char *data, size_t length );
|
unsigned char *data, size_t length );
|
||||||
int vips_stream_input_rewind( VipsStreamInput *input );
|
int vips_stream_input_rewind( VipsStreamInput *input );
|
||||||
void vips_stream_minimise( VipsStreamInput *input );
|
void vips_stream_input_minimise( VipsStreamInput *input );
|
||||||
void vips_stream_set_image( VipsStreamInput *input, VipsImage *image );
|
|
||||||
void vips_stream_input_decode( VipsStreamInput *input );
|
void vips_stream_input_decode( VipsStreamInput *input );
|
||||||
gboolean vips_stream_input_eof( VipsStreamInput *input );
|
gboolean vips_stream_input_eof( VipsStreamInput *input );
|
||||||
unsigned char *vips_stream_input_sniff( VipsStreamInput *input, size_t length );
|
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)
|
VIPS_OBJECT( STREAM )->nickname)
|
||||||
|
|
||||||
static void
|
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 ) {
|
if( stream->close_descriptor >= 0 ) {
|
||||||
close( stream->close_descriptor );
|
close( stream->close_descriptor );
|
||||||
stream->close_descriptor = -1;
|
stream->close_descriptor = -1;
|
||||||
@ -141,6 +133,21 @@ vips_stream_finalize( GObject *gobject )
|
|||||||
stream->tracked_descriptor = -1;
|
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 );
|
VIPS_FREE( stream->filename );
|
||||||
|
|
||||||
G_OBJECT_CLASS( vips_stream_parent_class )->finalize( gobject );
|
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 );
|
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
|
static int
|
||||||
vips_stream_input_build( VipsObject *object )
|
vips_stream_input_build( VipsObject *object )
|
||||||
{
|
{
|
||||||
@ -211,20 +253,9 @@ vips_stream_input_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( vips_object_argument_isset( object, "filename" ) ) {
|
if( vips_object_argument_isset( object, "filename" ) &&
|
||||||
int fd;
|
vips_stream_input_open( input ) )
|
||||||
|
return( -1 );
|
||||||
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, "descriptor" ) ) {
|
if( vips_object_argument_isset( object, "descriptor" ) ) {
|
||||||
stream->descriptor = dup( stream->descriptor );
|
stream->descriptor = dup( stream->descriptor );
|
||||||
@ -232,11 +263,11 @@ vips_stream_input_build( VipsObject *object )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( vips_object_argument_isset( object, "blob" ) )
|
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();
|
input->header_bytes = g_byte_array_new();
|
||||||
|
|
||||||
/* We always want a sniff buffer.
|
/* 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" );
|
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 ) {
|
if( input->blob ) {
|
||||||
VipsArea *area = (VipsArea *) input->blob;
|
VipsArea *area = (VipsArea *) input->blob;
|
||||||
ssize_t available = VIPS_MIN( length,
|
ssize_t available = VIPS_MIN( length,
|
||||||
@ -288,7 +324,7 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( input->rewindable &&
|
if( input->seekable &&
|
||||||
stream->descriptor != -1 ) {
|
stream->descriptor != -1 ) {
|
||||||
off_t new_pos;
|
off_t new_pos;
|
||||||
|
|
||||||
@ -312,7 +348,12 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
|||||||
static void
|
static void
|
||||||
vips_stream_input_minimise_real( VipsStreamInput *input )
|
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
|
static void
|
||||||
@ -341,11 +382,11 @@ vips_stream_input_class_init( VipsStreamInputClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsStreamInput, blob ),
|
G_STRUCT_OFFSET( VipsStreamInput, blob ),
|
||||||
VIPS_TYPE_BLOB );
|
VIPS_TYPE_BLOB );
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "rewindable", 4,
|
VIPS_ARG_BOOL( class, "seekable", 4,
|
||||||
_( "rewindable" ),
|
_( "Seekable" ),
|
||||||
_( "'descriptor' supports rewind" ),
|
_( "'descriptor' supports lseek()" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsStreamInput, rewindable ),
|
G_STRUCT_OFFSET( VipsStreamInput, seekable ),
|
||||||
FALSE );
|
FALSE );
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -544,11 +585,11 @@ vips_stream_input_read( VipsStreamInput *input,
|
|||||||
if( n == 0 )
|
if( n == 0 )
|
||||||
input->eof = TRUE;
|
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.
|
* reuse.
|
||||||
*/
|
*/
|
||||||
if( input->header_bytes &&
|
if( input->header_bytes &&
|
||||||
!input->rewindable &&
|
!input->seekable &&
|
||||||
!input->decode &&
|
!input->decode &&
|
||||||
n > 0 )
|
n > 0 )
|
||||||
g_byte_array_append( input->header_bytes,
|
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:
|
* vips_stream_input_sniff:
|
||||||
* @bytes: number of bytes to sniff
|
* @bytes: number of bytes to sniff
|
||||||
|
@ -7,10 +7,9 @@ set -e
|
|||||||
|
|
||||||
. ./variables.sh
|
. ./variables.sh
|
||||||
|
|
||||||
# reenable when we have minise support ini stream
|
if test_supported jpegload; then
|
||||||
# if test_supported jpegload; then
|
./test_descriptors $image
|
||||||
# ./test_descriptors $image
|
fi
|
||||||
# fi
|
|
||||||
|
|
||||||
if test_supported heifload; then
|
if test_supported heifload; then
|
||||||
./test_descriptors $test_images/Example1.heic
|
./test_descriptors $test_images/Example1.heic
|
||||||
|
Loading…
Reference in New Issue
Block a user