add mmap ppm input
This commit is contained in:
parent
5f4b995551
commit
9a3842919a
@ -64,7 +64,7 @@
|
||||
|
||||
/* TODO
|
||||
*
|
||||
* - load filename streams with mmap ... we'll need to add get_flags_stream
|
||||
* - load filename streams with mmap
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -330,22 +330,25 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_ppm_get_flags( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadPpm *ppm = (VipsForeignLoadPpm *) load;
|
||||
|
||||
VipsForeignFlags flags;
|
||||
|
||||
flags = 0;
|
||||
|
||||
/* reenable this when mmap load goes back in
|
||||
*
|
||||
VipsForeignLoadPpm *ppm = (VipsForeignLoadPpm *) load;
|
||||
|
||||
/* If this streami supports fast mmap and this PPM is >=8 bit binary,
|
||||
* then we can mmap the file and support partial load. Otherwise,
|
||||
* it's sequential.
|
||||
*/
|
||||
if( !ppm->have_read_header &&
|
||||
vips_foreign_load_ppm_parse_header( ppm ) )
|
||||
return( 0 );
|
||||
if( !ppm->ascii && ppm->bits >= 8 )
|
||||
if( vips_streami_is_mappable( ppm->streami ) &&
|
||||
!ppm->ascii &&
|
||||
ppm->bits >= 8 )
|
||||
flags |= VIPS_FOREIGN_PARTIAL;
|
||||
*/
|
||||
|
||||
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
||||
else
|
||||
flags |= VIPS_FOREIGN_SEQUENTIAL;
|
||||
|
||||
return( flags );
|
||||
}
|
||||
@ -388,7 +391,9 @@ vips_foreign_load_ppm_header( VipsForeignLoad *load )
|
||||
}
|
||||
|
||||
/* Read a ppm/pgm file using mmap().
|
||||
load_mmap( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
*/
|
||||
static int
|
||||
vips_foreign_load_ppm_map( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
{
|
||||
VipsImage **t = (VipsImage **)
|
||||
vips_object_local_array( VIPS_OBJECT( ppm ), 3 );
|
||||
@ -400,7 +405,8 @@ load_mmap( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
vips_streamib_unbuffer( ppm->streamib );
|
||||
header_offset = vips_streami_seek( ppm->streami, 0, SEEK_CUR );
|
||||
data = vips_streami_map( ppm->streami, &length );
|
||||
if( header_offset < 0 || !data )
|
||||
if( header_offset < 0 ||
|
||||
!data )
|
||||
return( -1 );
|
||||
data += header_offset;
|
||||
length -= header_offset;
|
||||
@ -416,7 +422,6 @@ load_mmap( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
*/
|
||||
|
||||
static int
|
||||
vips_foreign_load_ppm_generate_binary( VipsRegion *or,
|
||||
@ -556,34 +561,46 @@ vips_foreign_load_ppm_load( VipsForeignLoad *load )
|
||||
VipsImage **t = (VipsImage **)
|
||||
vips_object_local_array( (VipsObject *) load, 2 );
|
||||
|
||||
VipsGenerateFn generate;
|
||||
|
||||
if( !ppm->have_read_header &&
|
||||
vips_foreign_load_ppm_parse_header( ppm ) )
|
||||
return( 0 );
|
||||
|
||||
/* What sort of read are we doing?
|
||||
/* If the stream is mappable and this is a binary file, we can map it.
|
||||
*/
|
||||
if( !ppm->ascii && ppm->bits >= 8 ) {
|
||||
generate = vips_foreign_load_ppm_generate_binary;
|
||||
|
||||
/* The binary loader does not use the buffered IO object.
|
||||
*/
|
||||
vips_streamib_unbuffer( ppm->streamib );
|
||||
if( vips_streami_is_mappable( ppm->streami ) &&
|
||||
!ppm->ascii &&
|
||||
ppm->bits >= 8 ) {
|
||||
if( vips_foreign_load_ppm_map( ppm, load->real ) )
|
||||
return( -1 );
|
||||
}
|
||||
else if( !ppm->ascii && ppm->bits == 1 )
|
||||
generate = vips_foreign_load_ppm_generate_1bit_binary;
|
||||
else if( ppm->ascii && ppm->bits == 1 )
|
||||
generate = vips_foreign_load_ppm_generate_1bit_ascii;
|
||||
else
|
||||
generate = vips_foreign_load_ppm_generate_ascii_int;
|
||||
else {
|
||||
VipsGenerateFn generate;
|
||||
|
||||
t[0] = vips_image_new();
|
||||
vips_foreign_load_ppm_set_image( ppm, t[0] );
|
||||
if( vips_image_generate( t[0], NULL, generate, NULL, ppm, NULL ) ||
|
||||
vips_sequential( t[0], &t[1], NULL ) ||
|
||||
vips_image_write( t[1], load->real ) )
|
||||
return( -1 );
|
||||
/* What sort of read are we doing?
|
||||
*/
|
||||
if( !ppm->ascii && ppm->bits >= 8 ) {
|
||||
generate = vips_foreign_load_ppm_generate_binary;
|
||||
|
||||
/* The binary loader does not use the buffered IO
|
||||
* object.
|
||||
*/
|
||||
vips_streamib_unbuffer( ppm->streamib );
|
||||
}
|
||||
else if( !ppm->ascii && ppm->bits == 1 )
|
||||
generate = vips_foreign_load_ppm_generate_1bit_binary;
|
||||
else if( ppm->ascii && ppm->bits == 1 )
|
||||
generate = vips_foreign_load_ppm_generate_1bit_ascii;
|
||||
else
|
||||
generate = vips_foreign_load_ppm_generate_ascii_int;
|
||||
|
||||
t[0] = vips_image_new();
|
||||
vips_foreign_load_ppm_set_image( ppm, t[0] );
|
||||
if( vips_image_generate( t[0],
|
||||
NULL, generate, NULL, ppm, NULL ) ||
|
||||
vips_sequential( t[0], &t[1], NULL ) ||
|
||||
vips_image_write( t[1], load->real ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips_streami_decode( ppm->streami ) )
|
||||
return( -1 );
|
||||
|
@ -197,7 +197,8 @@ typedef struct _VipsForeignLoadClass {
|
||||
* of flags. If you don't define it, vips will default to 0 (no flags
|
||||
* set).
|
||||
*
|
||||
* This operation is necessary for vips7 compatibility.
|
||||
* This method is necessary for vips7 compatibility. Don't define
|
||||
* it if you don't need vips7.
|
||||
*/
|
||||
VipsForeignFlags (*get_flags_filename)( const char *filename );
|
||||
|
||||
@ -217,8 +218,7 @@ typedef struct _VipsForeignLoadClass {
|
||||
* @header() needs to set the dhint on the image .. otherwise you get
|
||||
* the default SMALLTILE.
|
||||
*
|
||||
* Return 0 for success, -1 for error, setting
|
||||
* vips_error().
|
||||
* Return 0 for success, -1 for error, setting vips_error().
|
||||
*/
|
||||
int (*header)( VipsForeignLoad *load );
|
||||
|
||||
|
@ -209,6 +209,7 @@ 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 );
|
||||
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,
|
||||
|
@ -817,10 +817,11 @@ vips_streami_descriptor_to_memory( VipsStreami *streami )
|
||||
* @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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
@ -860,6 +861,30 @@ vips_streami_map( VipsStreami *streami, size_t *length_out )
|
||||
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.
|
||||
*/
|
||||
gboolean
|
||||
vips_streami_is_mappable( VipsStreami *streami )
|
||||
{
|
||||
/* Already a memory object, or there's a filename we can map, or
|
||||
* there's a seekable descriptor.
|
||||
*/
|
||||
return( streami->data ||
|
||||
VIPS_STREAM( streami )->filename ||
|
||||
(streami->is_pipe && VIPS_STREAM( streami )->descriptor) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streami_seek:
|
||||
* @streami: input stream to operate on
|
||||
|
Loading…
Reference in New Issue
Block a user