add rd mode to im_open()
This commit is contained in:
parent
f822234c4e
commit
9ea66365c4
@ -3,6 +3,7 @@
|
|||||||
image and header
|
image and header
|
||||||
- added im_vips2bufpng()
|
- added im_vips2bufpng()
|
||||||
- use GetTempPath() to pick a temp dir on Windows
|
- use GetTempPath() to pick a temp dir on Windows
|
||||||
|
- added "rd" mode to im_open()
|
||||||
|
|
||||||
12/5/10 started 7.22.2
|
12/5/10 started 7.22.2
|
||||||
- the conditional image of ifthenelse can be any format, a (!=0) is added if
|
- the conditional image of ifthenelse can be any format, a (!=0) is added if
|
||||||
|
1
TODO
1
TODO
@ -1,3 +1,4 @@
|
|||||||
|
- vipsthumbnail should use "rd" mode
|
||||||
|
|
||||||
- lcms2 needs testing
|
- lcms2 needs testing
|
||||||
|
|
||||||
|
@ -195,14 +195,12 @@ attach_sb( IMAGE *out, int (*save_fn)(), const char *filename )
|
|||||||
* delay actually decoding pixels until the first call to a start function.
|
* delay actually decoding pixels until the first call to a start function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int (*OpenLazyFn)( const char *filename, IMAGE *im );
|
|
||||||
|
|
||||||
/* What we track during a delayed open.
|
/* What we track during a delayed open.
|
||||||
*/
|
*/
|
||||||
typedef struct _OpenLazy {
|
typedef struct _OpenLazy {
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
OpenLazyFn read_pixels; /* Read in pixels with this */
|
VipsFormatClass *format;/* Read in pixels with this */
|
||||||
IMAGE *lazy_im; /* Image we read to .. copy from this */
|
IMAGE *lazy_im; /* Image we read to .. copy from this */
|
||||||
} OpenLazy;
|
} OpenLazy;
|
||||||
|
|
||||||
@ -216,7 +214,7 @@ open_lazy_start( IMAGE *out, void *a, void *dummy )
|
|||||||
|
|
||||||
if( !lazy->lazy_im ) {
|
if( !lazy->lazy_im ) {
|
||||||
if( !(lazy->lazy_im = im_open_local( out, "read", "p" )) ||
|
if( !(lazy->lazy_im = im_open_local( out, "read", "p" )) ||
|
||||||
lazy->read_pixels( lazy->filename, lazy->lazy_im ) ) {
|
lazy->format->load( lazy->filename, lazy->lazy_im ) ) {
|
||||||
IM_FREEF( im_close, lazy->lazy_im );
|
IM_FREEF( im_close, lazy->lazy_im );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
@ -251,18 +249,17 @@ open_lazy_generate( REGION *or, void *seq, void *a, void *b )
|
|||||||
* decoding pixels with the second OpenLazyFn until the first generate().
|
* decoding pixels with the second OpenLazyFn until the first generate().
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
open_lazy( OpenLazyFn read_header, OpenLazyFn read_pixels,
|
open_lazy( VipsFormatClass *format, const char *filename, IMAGE *out )
|
||||||
const char *filename, IMAGE *out )
|
|
||||||
{
|
{
|
||||||
OpenLazy *lazy = IM_NEW( out, OpenLazy );
|
OpenLazy *lazy = IM_NEW( out, OpenLazy );
|
||||||
|
|
||||||
if( !lazy ||
|
if( !lazy ||
|
||||||
!(lazy->filename = im_strdup( out, filename )) )
|
!(lazy->filename = im_strdup( out, filename )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
lazy->read_pixels = read_pixels;
|
lazy->format = format;
|
||||||
lazy->lazy_im = NULL;
|
lazy->lazy_im = NULL;
|
||||||
|
|
||||||
if( read_header( filename, out ) ||
|
if( format->header( filename, out ) ||
|
||||||
im_demand_hint( out, IM_ANY, NULL ) )
|
im_demand_hint( out, IM_ANY, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -274,13 +271,55 @@ open_lazy( OpenLazyFn read_header, OpenLazyFn read_pixels,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static IMAGE *
|
static size_t
|
||||||
open_sub( OpenLazyFn read_header, OpenLazyFn read_pixels, const char *filename )
|
guess_size( VipsFormatClass *format, const char *filename )
|
||||||
{
|
{
|
||||||
IMAGE *im;
|
IMAGE *im;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
if( !(im = im_open( filename, "p" )) ||
|
if( !(im = im_open( "header", "p" )) )
|
||||||
open_lazy( read_header, read_pixels, filename, im ) ) {
|
return( 0 );
|
||||||
|
if( format->header( filename, im ) ) {
|
||||||
|
im_close( im );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
size = IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize;
|
||||||
|
im_close( im );
|
||||||
|
|
||||||
|
return( size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static IMAGE *
|
||||||
|
open_sub( VipsFormatClass *format, const char *filename, gboolean disc )
|
||||||
|
{
|
||||||
|
static const int use_disc_threshold = 1024 * 1024;
|
||||||
|
|
||||||
|
IMAGE *im;
|
||||||
|
|
||||||
|
/* We open to disc if:
|
||||||
|
* - 'disc' is set
|
||||||
|
* - the format does not support lazy read
|
||||||
|
* - the image will be more than a megabyte, uncompressed
|
||||||
|
*/
|
||||||
|
im = NULL;
|
||||||
|
if( disc )
|
||||||
|
if( !(vips_format_get_flags( format, filename ) &
|
||||||
|
VIPS_FORMAT_PARTIAL) ) {
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
size = guess_size( format, filename );
|
||||||
|
if( size > use_disc_threshold )
|
||||||
|
if( !(im = im__open_temp( "%s.v" )) )
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, fall back to a "p".
|
||||||
|
*/
|
||||||
|
if( !im &&
|
||||||
|
!(im = im_open( filename, "p" )) )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
if( open_lazy( format, filename, im ) ) {
|
||||||
im_close( im );
|
im_close( im );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
@ -353,9 +392,10 @@ evalend_cb( Progress *progress )
|
|||||||
* file for you in memory.
|
* file for you in memory.
|
||||||
*
|
*
|
||||||
* For some large files (eg. TIFF) this may
|
* For some large files (eg. TIFF) this may
|
||||||
* not be what you want: you should call the appropriate converter
|
* not be what you want, it can fill memory very quickly. Instead, you
|
||||||
* yourself, and arrange for the conversion to take place on disc.
|
* can either use "rd" mode (see below), or you can use the lower-level
|
||||||
* See #VipsFormat.
|
* API and control the loading process yourself. See
|
||||||
|
* #VipsFormat.
|
||||||
*
|
*
|
||||||
* im_open() can read files in most formats.
|
* im_open() can read files in most formats.
|
||||||
*
|
*
|
||||||
@ -366,6 +406,19 @@ evalend_cb( Progress *progress )
|
|||||||
* </listitem>
|
* </listitem>
|
||||||
* <listitem>
|
* <listitem>
|
||||||
* <para>
|
* <para>
|
||||||
|
* <emphasis>"rd"</emphasis>
|
||||||
|
* opens the named file for reading. If the uncompressed image is larger
|
||||||
|
* than a megabyte and the file format does not support random access,
|
||||||
|
* rather than uncompressing to memory, im_open() will uncompress to a
|
||||||
|
* temporary disc file. This file will be automatically deleted when the
|
||||||
|
* IMAGE is closed.
|
||||||
|
*
|
||||||
|
* See im_system_image() for an explanation of how VIPS selects a
|
||||||
|
* location for the temporary file.
|
||||||
|
* </para>
|
||||||
|
* </listitem>
|
||||||
|
* <listitem>
|
||||||
|
* <para>
|
||||||
* <emphasis>"w"</emphasis>
|
* <emphasis>"w"</emphasis>
|
||||||
* opens the named file for writing. It looks at the file name
|
* opens the named file for writing. It looks at the file name
|
||||||
* suffix to determine the type to write -- for example:
|
* suffix to determine the type to write -- for example:
|
||||||
@ -440,8 +493,8 @@ im_open( const char *filename, const char *mode )
|
|||||||
if( !(im = im_open_vips( filename )) )
|
if( !(im = im_open_vips( filename )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
else if( !(im = open_sub(
|
else if( !(im = open_sub( format, filename,
|
||||||
format->header, format->load, filename )) )
|
mode[1] == 'd' )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user