revise pipe sources (again)

Simplify and cleanup.
This commit is contained in:
John Cupitt 2020-10-04 14:05:53 +01:00
parent 0ee8b1e844
commit edbe9bf8ef
2 changed files with 55 additions and 81 deletions

View File

@ -872,6 +872,9 @@ vips_foreign_load_heif_load( VipsForeignLoad *load )
vips_image_write( t[1], load->real ) )
return( -1 );
if( vips_source_decode( heif->source ) )
return( -1 );
return( 0 );
}

View File

@ -42,8 +42,8 @@
*/
/*
#define TEST_SANITY
#define VIPS_DEBUG
#define TEST_SANITY
*/
#ifdef HAVE_CONFIG_H
@ -639,13 +639,15 @@ vips_source_decode( VipsSource *source )
SANITY( source );
/* We have finished reading the header. We can discard the header bytes
* we saved.
*/
if( !source->decode ) {
source->decode = TRUE;
VIPS_FREEF( g_byte_array_unref, source->header_bytes );
VIPS_FREEF( g_byte_array_unref, source->sniff );
/* If this is still a pipe source, we can discard the header
* bytes we saved.
*/
if( source->is_pipe )
VIPS_FREEF( g_byte_array_unref, source->header_bytes );
}
vips_source_minimise( source );
@ -655,6 +657,25 @@ vips_source_decode( VipsSource *source )
return( 0 );
}
#ifdef VIPS_DEBUG
static void
vips_source_print( VipsSource *source )
{
printf( "vips_source_print: %p\n", source );
printf( " source->read_position = %zd\n", source->read_position );
printf( " source->is_pipe = %d\n", source->is_pipe );
printf( " source->length = %zd\n", source->length );
printf( " source->data = %p\n", source->data );
printf( " source->header_bytes = %p\n", source->header_bytes );
if( source->header_bytes )
printf( " source->header_bytes->len = %d\n",
source->header_bytes->len );
printf( " source->sniff = %p\n", source->sniff );
if( source->sniff )
printf( " source->sniff->len = %d\n", source->sniff->len );
}
#endif /*VIPS_DEBUG*/
/**
* vips_source_read:
* @source: source to operate on
@ -761,31 +782,13 @@ vips_source_read( VipsSource *source, void *buffer, size_t length )
return( total_read );
}
#ifdef DEBUG
static void
vips_source_print( VipsSource *source )
{
printf( "vips_source_print: %p\n", source );
printf( " source->read_position = %zd\n", source->read_position );
printf( " source->is_pipe = %d\n", source->is_pipe );
printf( " source->length = %zd\n", source->length );
printf( " source->data = %p\n", source->data );
printf( " source->header_bytes = %p\n", source->header_bytes );
if( source->header_bytes )
printf( " source->header_bytes->len = %d\n",
source->header_bytes->len );
printf( " source->sniff = %p\n", source->sniff );
if( source->sniff )
printf( " source->sniff->len = %d\n", source->sniff->len );
}
#endif /*DEBUG*/
/* Read to a position.
*
* target == -1 means read to end of source -- useful for forcing a pipe into
* memory, for example.
* memory, for example. This will always set length to the pipe length.
*
* If we hit EOF, set length on the pipe.
* If we hit EOF and we're buffering, set length on the pipe and turn it into
* a memory source.
*
* read_position is left somewhere indeterminate.
*/
@ -800,6 +803,7 @@ vips_source_pipe_read_to_position( VipsSource *source, gint64 target )
* length).
*/
g_assert( source->length == -1 );
g_assert( source->is_pipe );
while( target == -1 ||
source->read_position < target ) {
@ -813,6 +817,19 @@ vips_source_pipe_read_to_position( VipsSource *source, gint64 target )
/* No more bytes available, we must be at EOF.
*/
source->length = source->read_position;
/* Have we been buffering the whole thing? We can
* become a memory source.
*/
if( source->header_bytes ) {
source->data = source->header_bytes->data;
source->is_pipe = FALSE;
/* TODO ... we could close more fds here.
*/
vips_source_minimise( source );
}
break;
}
@ -853,8 +870,6 @@ vips_source_read_to_memory( VipsSource *source )
byte_array = g_byte_array_new();
g_byte_array_set_size( byte_array, source->length );
/* Read in a series of chunks to reduce stress upstream.
*/
read_position = 0;
q = byte_array->data;
while( read_position < source->length ) {
@ -887,34 +902,6 @@ vips_source_read_to_memory( VipsSource *source )
return( 0 );
}
/* Read the entire pipe into memory and turn this into a memory source.
*/
static int
vips_source_pipe_to_memory( VipsSource *source )
{
VIPS_DEBUG_MSG( "vips_source_pipe_to_memory:\n" );
g_assert( source->is_pipe );
g_assert( !source->blob );
g_assert( !source->decode );
g_assert( source->header_bytes );
if( vips_source_pipe_read_to_position( source, -1 ) )
return( -1 );
/* Steal the header_bytes pointer and turn into a memory source.
*/
source->length = source->header_bytes->len;
source->data = source->header_bytes->data;
source->is_pipe = FALSE;
/* TODO ... we could close more fds here.
*/
vips_source_minimise( source );
return( 0 );
}
static int
vips_source_descriptor_to_memory( VipsSource *source )
{
@ -1002,7 +989,7 @@ vips_source_map( VipsSource *source, size_t *length_out )
return( NULL );
}
else {
if( vips_source_pipe_to_memory( source ) )
if( vips_source_pipe_read_to_position( source, -1 ) )
return( NULL );
}
}
@ -1113,8 +1100,7 @@ vips_source_seek( VipsSource *source, gint64 offset, int whence )
/* We have to read the whole source into memory to get
* the length.
*/
if( source->length == -1 &&
vips_source_pipe_to_memory( source ) )
if( vips_source_pipe_read_to_position( source, -1 ) )
return( -1 );
new_pos = source->length + offset;
@ -1130,6 +1116,13 @@ vips_source_seek( VipsSource *source, gint64 offset, int whence )
return( -1 );
}
/* For pipes, we have to fake seek by reading to that point. This
* might hit EOF and turn the pipe into a memory source.
*/
if( source->is_pipe &&
vips_source_pipe_read_to_position( source, new_pos ) )
return( -1 );
/* Don't allow out of range seeks.
*/
if( new_pos < 0 ||
@ -1140,28 +1133,6 @@ vips_source_seek( VipsSource *source, gint64 offset, int whence )
return( -1 );
}
/* For pipes, we have to fake seek by reading to that point.
*/
if( source->is_pipe ) {
if( vips_source_pipe_read_to_position( source, new_pos ) )
return( -1 );
/* We've hit EOF in the pipe, and we've got the whole thing
* buffered. Steal the header_bytes pointer and turn into a
* memory source.
*/
if( source->length != -1 &&
source->header_bytes ) {
source->length = source->header_bytes->len;
source->data = source->header_bytes->data;
source->is_pipe = FALSE;
/* TODO ... we could close more fds here.
*/
vips_source_minimise( source );
}
}
source->read_position = new_pos;
VIPS_DEBUG_MSG( " new_pos = %" G_GINT64_FORMAT "\n", new_pos );