fix map of input streams

The logic was a bit wonky. Thanks Kleis.

See https://github.com/kleisauke/net-vips/issues/33#issuecomment-559971456
This commit is contained in:
John Cupitt 2019-11-30 19:13:26 +00:00
parent 5121e203f8
commit 43fff7b10d
2 changed files with 49 additions and 60 deletions

View File

@ -211,8 +211,8 @@ void vips_streami_minimise( VipsStreami *streami );
int vips_streami_unminimise( VipsStreami *streami );
int vips_streami_decode( VipsStreami *streami );
ssize_t vips_streami_read( VipsStreami *streami, void *data, size_t length );
const void *vips_streami_map( VipsStreami *streami, size_t *length );
gboolean vips_streami_is_mappable( VipsStreami *streami );
const void *vips_streami_map( VipsStreami *streami, size_t *length );
gint64 vips_streami_seek( VipsStreami *streami, gint64 offset, int whence );
int vips_streami_rewind( VipsStreami *streami );
size_t vips_streami_sniff_at_most( VipsStreami *streami,

View File

@ -811,66 +811,10 @@ vips_streami_descriptor_to_memory( VipsStreami *streami )
}
/**
* vips_streami_map:
* vips_streami_is_mappable:
* @streami: input stream to operate on
* @length_out: return the file length here, or NULL
*
* Map the stream object entirely into memory and return a pointer to the
* start. If @length_out is non-NULL, the file size if written to it.
*
* This operation can take a long time. Use vips_streami_is_mappable() to
* check if a streami can be mapped efficiently.
*
* Returns: a pointer to the start of the file contents, or NULL on error.
*/
const void *
vips_streami_map( VipsStreami *streami, size_t *length_out )
{
VipsStream *stream = VIPS_STREAM( streami );
VIPS_DEBUG_MSG( "vips_streami_map:\n" );
SANITY( streami );
if( vips_streami_unminimise( streami ) )
return( NULL );
/* Pipes need to be read into memory.
*/
if( streami->is_pipe &&
vips_streami_pipe_to_memory( streami ) )
return( NULL );
/* Seekable descriptors can be mmaped and become memory
* sources.
*/
if( !streami->data &&
!streami->mmap_baseaddr &&
streami->length > 0 &&
stream->descriptor != -1 &&
vips_streami_descriptor_to_memory( streami ) )
return( NULL );
if( length_out )
*length_out = streami->length;
SANITY( streami );
return( streami->data );
}
/**
* vips_streami_map:
* @streami: input stream to operate on
* @length_out: return the file length here, or NULL
*
* Map the stream object entirely into memory and return a pointer to the
* start. If @length_out is non-NULL, the file size if written to it.
*
* This operation can take a long time. Use vips_streami_is_mappable() to check
* if a streami can be mapped efficiently.
*
* Returns: a pointer to the start of the file contents, or NULL on error.
* Returns: %TRUE if the stream can be efficiently mapped into memory.
*/
gboolean
vips_streami_is_mappable( VipsStreami *streami )
@ -880,10 +824,55 @@ vips_streami_is_mappable( VipsStreami *streami )
*/
return( streami->data ||
VIPS_STREAM( streami )->filename ||
(streami->is_pipe &&
(!streami->is_pipe &&
VIPS_STREAM( streami )->descriptor) );
}
/**
* vips_streami_map:
* @streami: input stream to operate on
* @length_out: return the file length here, or NULL
*
* Map the stream object entirely into memory and return a pointer to the
* start. If @length_out is non-NULL, the stream size is written to it.
*
* This operation can take a long time. Use vips_streami_is_mappable() to
* check if a streami can be mapped efficiently.
*
* Returns: a pointer to the start of the file contents, or NULL on error.
*/
const void *
vips_streami_map( VipsStreami *streami, size_t *length_out )
{
VIPS_DEBUG_MSG( "vips_streami_map:\n" );
SANITY( streami );
if( vips_streami_unminimise( streami ) )
return( NULL );
if( !streami->data ) {
/* Seekable descriptors can simply be mmaped. All other sources
* must be read into memory.
*/
if( vips_streami_is_mappable( streami ) ) {
if( vips_streami_descriptor_to_memory( streami ) )
return( NULL );
}
else {
if( vips_streami_pipe_to_memory( streami ) )
return( NULL );
}
}
if( length_out )
*length_out = streami->length;
SANITY( streami );
return( streami->data );
}
/**
* vips_streami_seek:
* @streami: input stream to operate on