add mmap input sources
falls back to read() if no mmap
This commit is contained in:
parent
28daeb1a8a
commit
5a788b89cf
@ -166,6 +166,7 @@ typedef struct _VipsStreamInputClass {
|
|||||||
/* Subclasses can define these to implement other input methods.
|
/* Subclasses can define these to implement other input methods.
|
||||||
*/
|
*/
|
||||||
ssize_t (*read)( VipsStreamInput *, unsigned char *, size_t );
|
ssize_t (*read)( VipsStreamInput *, unsigned char *, size_t );
|
||||||
|
const void * (*map)( VipsStreamInput *, size_t * );
|
||||||
int (*rewind)( VipsStreamInput * );
|
int (*rewind)( VipsStreamInput * );
|
||||||
|
|
||||||
/* Shut down anything that can safely restarted. For example, if
|
/* Shut down anything that can safely restarted. For example, if
|
||||||
|
@ -325,6 +325,27 @@ vips_stream_input_read_real( VipsStreamInput *input,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const void *
|
||||||
|
vips_stream_input_map_real( VipsStreamInput *input, size_t *length )
|
||||||
|
{
|
||||||
|
VipsStream *stream = VIPS_STREAM( input );
|
||||||
|
|
||||||
|
gint64 file_length;
|
||||||
|
const void *file_baseaddr;
|
||||||
|
|
||||||
|
if( (file_length = vips_file_length( stream->descriptor )) < 0 )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
if( !(file_baseaddr = vips__mmap( stream->descriptor,
|
||||||
|
FALSE, file_length, 0 )) )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
if( length )
|
||||||
|
*length = file_length;
|
||||||
|
|
||||||
|
return( file_baseaddr );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips_stream_input_rewind_real( VipsStreamInput *input )
|
vips_stream_input_rewind_real( VipsStreamInput *input )
|
||||||
{
|
{
|
||||||
@ -332,12 +353,6 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
|||||||
|
|
||||||
VIPS_DEBUG_MSG( "vips_stream_input_rewind_real:\n" );
|
VIPS_DEBUG_MSG( "vips_stream_input_rewind_real:\n" );
|
||||||
|
|
||||||
if( input->decode ) {
|
|
||||||
vips_error( STREAM_NAME( stream ),
|
|
||||||
"%s", _( "can't rewind after decode begins" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( input->seekable &&
|
if( input->seekable &&
|
||||||
stream->descriptor != -1 ) {
|
stream->descriptor != -1 ) {
|
||||||
off_t new_pos;
|
off_t new_pos;
|
||||||
@ -353,8 +368,6 @@ vips_stream_input_rewind_real( VipsStreamInput *input )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input->read_position = 0;
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,6 +398,7 @@ vips_stream_input_class_init( VipsStreamInputClass *class )
|
|||||||
object_class->build = vips_stream_input_build;
|
object_class->build = vips_stream_input_build;
|
||||||
|
|
||||||
class->read = vips_stream_input_read_real;
|
class->read = vips_stream_input_read_real;
|
||||||
|
class->map = vips_stream_input_map_real;
|
||||||
class->rewind = vips_stream_input_rewind_real;
|
class->rewind = vips_stream_input_rewind_real;
|
||||||
class->minimise = vips_stream_input_minimise_real;
|
class->minimise = vips_stream_input_minimise_real;
|
||||||
|
|
||||||
@ -611,43 +625,28 @@ vips_stream_input_read( VipsStreamInput *input,
|
|||||||
return( bytes_read );
|
return( bytes_read );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const void *
|
|
||||||
vips_stream_input_try_map( VipsStreamInput *input, size_t *length )
|
|
||||||
{
|
|
||||||
VipsStream *stream = VIPS_STREAM( input );
|
|
||||||
|
|
||||||
if( input->length < 0 )
|
|
||||||
input->length = vips_file_length( stream->descriptor );
|
|
||||||
if( input->length < 0 )
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
if( !input->baseaddr ) {
|
|
||||||
input->baseaddr = vips__mmap( stream->descriptor,
|
|
||||||
FALSE, input->length, 0 );
|
|
||||||
if( !input->baseaddr )
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( length )
|
|
||||||
*length = input->length;
|
|
||||||
|
|
||||||
return( input->baseaddr );
|
|
||||||
}
|
|
||||||
|
|
||||||
const void *
|
const void *
|
||||||
vips_stream_input_map( VipsStreamInput *input, size_t *length )
|
vips_stream_input_map( VipsStreamInput *input, size_t *length )
|
||||||
{
|
{
|
||||||
|
VipsStreamInputClass *class = VIPS_STREAM_INPUT_GET_CLASS( input );
|
||||||
|
|
||||||
|
unsigned char buffer[4096];
|
||||||
|
|
||||||
|
VIPS_DEBUG_MSG( "vips_stream_input_map:\n" );
|
||||||
|
|
||||||
/* Memory source ... easy!
|
/* Memory source ... easy!
|
||||||
*/
|
*/
|
||||||
if( input->blob )
|
if( input->blob ) {
|
||||||
|
VIPS_DEBUG_MSG( " memory source\n" );
|
||||||
return( vips_blob_get( input->blob, length ) );
|
return( vips_blob_get( input->blob, length ) );
|
||||||
|
}
|
||||||
|
|
||||||
/* An input that supports mmap.
|
/* An input that supports mmap.
|
||||||
*/
|
*/
|
||||||
if( input->mapable ) {
|
if( input->mapable ) {
|
||||||
|
VIPS_DEBUG_MSG( " mmaping source\n" );
|
||||||
if( !input->baseaddr ) {
|
if( !input->baseaddr ) {
|
||||||
input->baseaddr = vips_stream_input_try_map( input,
|
input->baseaddr = class->map( input, &input->length );
|
||||||
&input->length );
|
|
||||||
if( !input->baseaddr )
|
if( !input->baseaddr )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
@ -658,10 +657,19 @@ vips_stream_input_map( VipsStreamInput *input, size_t *length )
|
|||||||
return( input->baseaddr );
|
return( input->baseaddr );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Have to read() the whole thing.
|
/* Have to read() the whole thing. header_bytes will keep a copy of
|
||||||
|
* the file.
|
||||||
*/
|
*/
|
||||||
|
VIPS_DEBUG_MSG( " read() of entire source\n" );
|
||||||
|
if( vips_stream_input_rewind( input ) )
|
||||||
|
return( NULL );
|
||||||
|
while( vips_stream_input_read( input, buffer, 4096 ) > 0 )
|
||||||
|
;
|
||||||
|
|
||||||
return( NULL );
|
if( length )
|
||||||
|
*length = input->header_bytes->len;
|
||||||
|
|
||||||
|
return( input->header_bytes->data );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -671,6 +679,14 @@ vips_stream_input_rewind( VipsStreamInput *input )
|
|||||||
|
|
||||||
VIPS_DEBUG_MSG( "vips_stream_input_rewind:\n" );
|
VIPS_DEBUG_MSG( "vips_stream_input_rewind:\n" );
|
||||||
|
|
||||||
|
if( input->decode ) {
|
||||||
|
vips_error( STREAM_NAME( input ),
|
||||||
|
"%s", _( "can't rewind after decode begins" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
input->read_position = 0;
|
||||||
|
|
||||||
return( class->rewind( input ) );
|
return( class->rewind( input ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user