first try, not very good
This commit is contained in:
parent
2acd185ee2
commit
14d7ce1e91
15
TODO
15
TODO
@ -1,11 +1,14 @@
|
|||||||
|
- the jpeg loader needs _header() and _load() to return the same dimensions
|
||||||
|
|
||||||
- python:
|
this is going to be tough with read_jpeg_image(): it uses the read-header
|
||||||
|
thing to set up the image that it generates
|
||||||
|
|
||||||
- update examples with new image constant rules
|
|
||||||
|
|
||||||
update blog post with new examples/try12.py
|
|
||||||
|
|
||||||
- do more tests
|
|
||||||
|
- update blog post with new examples/try12.py
|
||||||
|
|
||||||
|
- fix up aconv
|
||||||
|
|
||||||
- put exif autorotate into jpeg load
|
- put exif autorotate into jpeg load
|
||||||
|
|
||||||
@ -13,12 +16,12 @@
|
|||||||
|
|
||||||
https://github.com/jcupitt/ruby-vips/issues/53
|
https://github.com/jcupitt/ruby-vips/issues/53
|
||||||
|
|
||||||
|
- more python tests
|
||||||
|
|
||||||
- can we pick the vipsthumbnail int shrink factor more intelligently?
|
- can we pick the vipsthumbnail int shrink factor more intelligently?
|
||||||
|
|
||||||
- vips_resize() should use vipsthumbnail's block/cache/affine/sharpen chain
|
- vips_resize() should use vipsthumbnail's block/cache/affine/sharpen chain
|
||||||
|
|
||||||
- fix up aconv
|
|
||||||
|
|
||||||
- rewrite im_conv() etc. as vips_conv(), also the mosaicing functions
|
- rewrite im_conv() etc. as vips_conv(), also the mosaicing functions
|
||||||
|
|
||||||
finally finish --disable-deprecated option
|
finally finish --disable-deprecated option
|
||||||
|
@ -113,7 +113,7 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
|
|||||||
|
|
||||||
#ifdef HAVE_JPEG
|
#ifdef HAVE_JPEG
|
||||||
if( vips__jpeg_read_file( filename, out,
|
if( vips__jpeg_read_file( filename, out,
|
||||||
header_only, shrink, fail_on_warn, TRUE ) )
|
header_only, shrink, fail_on_warn, TRUE, FALSE ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
#else
|
#else
|
||||||
vips_error( "im_jpeg2vips",
|
vips_error( "im_jpeg2vips",
|
||||||
|
@ -682,36 +682,6 @@ vips_foreign_load_new_from_string( const char *string )
|
|||||||
return( VIPS_OBJECT( load ) );
|
return( VIPS_OBJECT( load ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint64
|
|
||||||
vips_get_disc_threshold( void )
|
|
||||||
{
|
|
||||||
static gboolean done = FALSE;
|
|
||||||
static guint64 threshold;
|
|
||||||
|
|
||||||
if( !done ) {
|
|
||||||
const char *env;
|
|
||||||
|
|
||||||
done = TRUE;
|
|
||||||
|
|
||||||
/* 100mb default.
|
|
||||||
*/
|
|
||||||
threshold = 100 * 1024 * 1024;
|
|
||||||
|
|
||||||
if( (env = g_getenv( "VIPS_DISC_THRESHOLD" )) ||
|
|
||||||
(env = g_getenv( "IM_DISC_THRESHOLD" )) )
|
|
||||||
threshold = vips__parse_size( env );
|
|
||||||
|
|
||||||
if( vips__disc_threshold )
|
|
||||||
threshold = vips__parse_size( vips__disc_threshold );
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "vips_get_disc_threshold: %zd bytes\n", threshold );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
}
|
|
||||||
|
|
||||||
return( threshold );
|
|
||||||
}
|
|
||||||
|
|
||||||
static VipsImage *
|
static VipsImage *
|
||||||
vips_foreign_load_temp( VipsForeignLoad *load )
|
vips_foreign_load_temp( VipsForeignLoad *load )
|
||||||
{
|
{
|
||||||
@ -742,12 +712,10 @@ vips_foreign_load_temp( VipsForeignLoad *load )
|
|||||||
|
|
||||||
/* We open via disc if:
|
/* We open via disc if:
|
||||||
* - 'disc' is set
|
* - 'disc' is set
|
||||||
* - disc-threshold has not been set to zero
|
|
||||||
* - the uncompressed image will be larger than
|
* - the uncompressed image will be larger than
|
||||||
* vips_get_disc_threshold()
|
* vips_get_disc_threshold()
|
||||||
*/
|
*/
|
||||||
if( load->disc &&
|
if( load->disc &&
|
||||||
disc_threshold &&
|
|
||||||
image_size > disc_threshold ) {
|
image_size > disc_threshold ) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips_foreign_load_temp: disc temp\n" );
|
printf( "vips_foreign_load_temp: disc temp\n" );
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
* - don't write to our input buffer, thanks Lovell
|
* - don't write to our input buffer, thanks Lovell
|
||||||
* 9/9/14
|
* 9/9/14
|
||||||
* - support "none" as a resolution unit
|
* - support "none" as a resolution unit
|
||||||
|
* 16/10/14
|
||||||
|
* - add "autorotate" option
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -131,6 +133,12 @@
|
|||||||
typedef struct _ReadJpeg {
|
typedef struct _ReadJpeg {
|
||||||
VipsImage *out;
|
VipsImage *out;
|
||||||
|
|
||||||
|
/* The raw image size: out may have width and height swapped if we are
|
||||||
|
* autorotating.
|
||||||
|
*/
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
/* Shrink by this much during load. 1, 2, 4, 8.
|
/* Shrink by this much during load. 1, 2, 4, 8.
|
||||||
*/
|
*/
|
||||||
int shrink;
|
int shrink;
|
||||||
@ -158,6 +166,10 @@ typedef struct _ReadJpeg {
|
|||||||
/* Track the y pos during a read with this.
|
/* Track the y pos during a read with this.
|
||||||
*/
|
*/
|
||||||
int y_pos;
|
int y_pos;
|
||||||
|
|
||||||
|
/* Use exif tags to automatically rotate and flip image.
|
||||||
|
*/
|
||||||
|
gboolean autorotate;
|
||||||
} ReadJpeg;
|
} ReadJpeg;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -211,7 +223,8 @@ readjpeg_close( VipsObject *object, ReadJpeg *jpeg )
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ReadJpeg *
|
static ReadJpeg *
|
||||||
readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean readbehind )
|
readjpeg_new( VipsImage *out,
|
||||||
|
int shrink, gboolean fail, gboolean readbehind, gboolean autorotate )
|
||||||
{
|
{
|
||||||
ReadJpeg *jpeg;
|
ReadJpeg *jpeg;
|
||||||
|
|
||||||
@ -224,13 +237,12 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean readbehind )
|
|||||||
jpeg->readbehind = readbehind;
|
jpeg->readbehind = readbehind;
|
||||||
jpeg->filename = NULL;
|
jpeg->filename = NULL;
|
||||||
jpeg->decompressing = FALSE;
|
jpeg->decompressing = FALSE;
|
||||||
|
|
||||||
jpeg->cinfo.err = jpeg_std_error( &jpeg->eman.pub );
|
jpeg->cinfo.err = jpeg_std_error( &jpeg->eman.pub );
|
||||||
jpeg->eman.pub.error_exit = vips__new_error_exit;
|
jpeg->eman.pub.error_exit = vips__new_error_exit;
|
||||||
jpeg->eman.pub.output_message = vips__new_output_message;
|
jpeg->eman.pub.output_message = vips__new_output_message;
|
||||||
jpeg->eman.fp = NULL;
|
jpeg->eman.fp = NULL;
|
||||||
|
|
||||||
jpeg->y_pos = 0;
|
jpeg->y_pos = 0;
|
||||||
|
jpeg->autorotate = autorotate;
|
||||||
|
|
||||||
/* jpeg_create_decompress() can fail on some sanity checks. Don't
|
/* jpeg_create_decompress() can fail on some sanity checks. Don't
|
||||||
* readjpeg_free() since we don't want to jpeg_destroy_decompress().
|
* readjpeg_free() since we don't want to jpeg_destroy_decompress().
|
||||||
@ -678,6 +690,35 @@ attach_blob( VipsImage *im, const char *field, void *data, int data_length )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ORIENTATION ("exif-ifd0-Orientation")
|
||||||
|
|
||||||
|
static VipsAngle
|
||||||
|
get_angle( VipsImage *im )
|
||||||
|
{
|
||||||
|
VipsAngle angle;
|
||||||
|
const char *orientation;
|
||||||
|
|
||||||
|
angle = VIPS_ANGLE_D0;
|
||||||
|
if( vips_image_get_typeof( im, ORIENTATION ) &&
|
||||||
|
!vips_image_get_string( im, ORIENTATION, &orientation ) ) {
|
||||||
|
if( vips_isprefix( "6", orientation ) )
|
||||||
|
angle = VIPS_ANGLE_D90;
|
||||||
|
else if( vips_isprefix( "8", orientation ) )
|
||||||
|
angle = VIPS_ANGLE_D270;
|
||||||
|
else if( vips_isprefix( "3", orientation ) )
|
||||||
|
angle = VIPS_ANGLE_D180;
|
||||||
|
/* Other values do rotate + mirror, don't bother handling them
|
||||||
|
* though, how common can mirroring be.
|
||||||
|
*
|
||||||
|
* See:
|
||||||
|
*
|
||||||
|
* http://www.80sidea.com/archives/2316
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return( angle );
|
||||||
|
}
|
||||||
|
|
||||||
/* Number of app2 sections we can capture. Each one can be 64k, so 6400k should
|
/* Number of app2 sections we can capture. Each one can be 64k, so 6400k should
|
||||||
* be enough for anyone (haha).
|
* be enough for anyone (haha).
|
||||||
*/
|
*/
|
||||||
@ -892,6 +933,20 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
(VipsCallbackFn) vips_free, data, data_length );
|
(VipsCallbackFn) vips_free, data, data_length );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Swap width and height if we're going to rotate this image. Keep the
|
||||||
|
* unrotated dimensions around too.
|
||||||
|
*/
|
||||||
|
jpeg->width = out->Xsize;
|
||||||
|
jpeg->height = out->Ysize;
|
||||||
|
|
||||||
|
if( jpeg->autorotate ) {
|
||||||
|
VipsAngle angle = get_angle( out );
|
||||||
|
|
||||||
|
if( angle == VIPS_ANGLE_D90 ||
|
||||||
|
angle == VIPS_ANGLE_D270 )
|
||||||
|
VIPS_SWAP( int, out->Xsize, out->Ysize )
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,6 +1021,35 @@ read_jpeg_generate( VipsRegion *or,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Auto-rotate, if rotate_image is set.
|
||||||
|
*/
|
||||||
|
static VipsImage *
|
||||||
|
read_jpeg_rotate( VipsObject *process, VipsImage *im )
|
||||||
|
{
|
||||||
|
VipsImage **t = (VipsImage **) vips_object_local_array( process, 2 );
|
||||||
|
VipsAngle angle = get_angle( im );
|
||||||
|
|
||||||
|
if( angle != VIPS_ANGLE_D0 ) {
|
||||||
|
/* Need to copy to memory or disc, we have to stay seq.
|
||||||
|
*/
|
||||||
|
const guint64 image_size = VIPS_IMAGE_SIZEOF_IMAGE( im );
|
||||||
|
const guint64 disc_threshold = vips_get_disc_threshold();
|
||||||
|
|
||||||
|
if( image_size > disc_threshold )
|
||||||
|
t[0] = vips_image_new_temp_file( "%s.v" );
|
||||||
|
else
|
||||||
|
t[0] = vips_image_new_memory();
|
||||||
|
|
||||||
|
if( vips_image_write( im, t[0] ) ||
|
||||||
|
vips_rot( t[0], &t[1], angle, NULL ) )
|
||||||
|
return( NULL );
|
||||||
|
im = t[1];
|
||||||
|
(void) vips_image_remove( im, ORIENTATION );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( im );
|
||||||
|
}
|
||||||
|
|
||||||
/* Read a cinfo to a VIPS image.
|
/* Read a cinfo to a VIPS image.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@ -975,6 +1059,8 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
VipsImage **t = (VipsImage **)
|
VipsImage **t = (VipsImage **)
|
||||||
vips_object_local_array( VIPS_OBJECT( out ), 3 );
|
vips_object_local_array( VIPS_OBJECT( out ), 3 );
|
||||||
|
|
||||||
|
VipsImage *im;
|
||||||
|
|
||||||
/* Here for longjmp() from vips__new_error_exit().
|
/* Here for longjmp() from vips__new_error_exit().
|
||||||
*/
|
*/
|
||||||
if( setjmp( jpeg->eman.jmp ) )
|
if( setjmp( jpeg->eman.jmp ) )
|
||||||
@ -1002,8 +1088,14 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
"access", jpeg->readbehind ?
|
"access", jpeg->readbehind ?
|
||||||
VIPS_ACCESS_SEQUENTIAL :
|
VIPS_ACCESS_SEQUENTIAL :
|
||||||
VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
|
||||||
NULL ) ||
|
NULL ) )
|
||||||
vips_image_write( t[1], out ) )
|
return( -1 );
|
||||||
|
|
||||||
|
im = t[1];
|
||||||
|
if( jpeg->autorotate )
|
||||||
|
im = read_jpeg_rotate( VIPS_OBJECT( out ), im );
|
||||||
|
|
||||||
|
if( vips_image_write( im, out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -1013,12 +1105,14 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
vips__jpeg_read_file( const char *filename, VipsImage *out,
|
vips__jpeg_read_file( const char *filename, VipsImage *out,
|
||||||
gboolean header_only, int shrink, gboolean fail, gboolean readbehind )
|
gboolean header_only, int shrink, gboolean fail, gboolean readbehind,
|
||||||
|
gboolean autorotate )
|
||||||
{
|
{
|
||||||
ReadJpeg *jpeg;
|
ReadJpeg *jpeg;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if( !(jpeg = readjpeg_new( out, shrink, fail, readbehind )) )
|
if( !(jpeg = readjpeg_new( out,
|
||||||
|
shrink, fail, readbehind, autorotate )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Here for longjmp() from vips__new_error_exit() during startup.
|
/* Here for longjmp() from vips__new_error_exit() during startup.
|
||||||
@ -1231,12 +1325,14 @@ readjpeg_buffer (ReadJpeg *jpeg, void *buf, size_t len)
|
|||||||
|
|
||||||
int
|
int
|
||||||
vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
|
vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
|
||||||
gboolean header_only, int shrink, int fail, gboolean readbehind )
|
gboolean header_only, int shrink, int fail, gboolean readbehind,
|
||||||
|
gboolean autorotate )
|
||||||
{
|
{
|
||||||
ReadJpeg *jpeg;
|
ReadJpeg *jpeg;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if( !(jpeg = readjpeg_new( out, shrink, fail, readbehind )) )
|
if( !(jpeg = readjpeg_new( out,
|
||||||
|
shrink, fail, readbehind, autorotate )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( setjmp( jpeg->eman.jmp ) ) {
|
if( setjmp( jpeg->eman.jmp ) ) {
|
||||||
|
@ -81,6 +81,10 @@ typedef struct _VipsForeignLoadJpeg {
|
|||||||
*/
|
*/
|
||||||
gboolean fail;
|
gboolean fail;
|
||||||
|
|
||||||
|
/* Autorotate using exif orientation tag.
|
||||||
|
*/
|
||||||
|
gboolean autorotate;
|
||||||
|
|
||||||
} VipsForeignLoadJpeg;
|
} VipsForeignLoadJpeg;
|
||||||
|
|
||||||
typedef VipsForeignLoadClass VipsForeignLoadJpegClass;
|
typedef VipsForeignLoadClass VipsForeignLoadJpegClass;
|
||||||
@ -146,6 +150,13 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class )
|
|||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsForeignLoadJpeg, fail ),
|
G_STRUCT_OFFSET( VipsForeignLoadJpeg, fail ),
|
||||||
FALSE );
|
FALSE );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( class, "autorotate", 12,
|
||||||
|
_( "Autorotate" ),
|
||||||
|
_( "Automatically rotate image using exif orientation" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadJpeg, autorotate ),
|
||||||
|
FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -189,7 +200,7 @@ vips_foreign_load_jpeg_file_header( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||||
|
|
||||||
if( vips__jpeg_read_file( file->filename, load->out,
|
if( vips__jpeg_read_file( file->filename, load->out,
|
||||||
TRUE, jpeg->shrink, jpeg->fail, FALSE ) )
|
TRUE, jpeg->shrink, jpeg->fail, FALSE, jpeg->autorotate ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
VIPS_SETSTR( load->out->filename, file->filename );
|
VIPS_SETSTR( load->out->filename, file->filename );
|
||||||
@ -205,7 +216,7 @@ vips_foreign_load_jpeg_file_load( VipsForeignLoad *load )
|
|||||||
|
|
||||||
if( vips__jpeg_read_file( file->filename, load->real,
|
if( vips__jpeg_read_file( file->filename, load->real,
|
||||||
FALSE, jpeg->shrink, jpeg->fail,
|
FALSE, jpeg->shrink, jpeg->fail,
|
||||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
load->access == VIPS_ACCESS_SEQUENTIAL, jpeg->autorotate ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -269,7 +280,8 @@ vips_foreign_load_jpeg_buffer_header( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||||
|
|
||||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
||||||
load->out, TRUE, jpeg->shrink, jpeg->fail, FALSE ) )
|
load->out, TRUE, jpeg->shrink, jpeg->fail, FALSE,
|
||||||
|
jpeg->autorotate ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -283,7 +295,7 @@ vips_foreign_load_jpeg_buffer_load( VipsForeignLoad *load )
|
|||||||
|
|
||||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
||||||
load->real, FALSE, jpeg->shrink, jpeg->fail,
|
load->real, FALSE, jpeg->shrink, jpeg->fail,
|
||||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
load->access == VIPS_ACCESS_SEQUENTIAL, jpeg->autorotate ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
@ -49,9 +49,11 @@ int vips__jpeg_write_buffer( VipsImage *in,
|
|||||||
int vips__isjpeg_buffer( void *buf, size_t len );
|
int vips__isjpeg_buffer( void *buf, size_t len );
|
||||||
int vips__isjpeg( const char *filename );
|
int vips__isjpeg( const char *filename );
|
||||||
int vips__jpeg_read_file( const char *name, VipsImage *out,
|
int vips__jpeg_read_file( const char *name, VipsImage *out,
|
||||||
gboolean header_only, int shrink, gboolean fail, gboolean readbehind );
|
gboolean header_only, int shrink, gboolean fail, gboolean readbehind,
|
||||||
|
gboolean autorotate );
|
||||||
int vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
|
int vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
|
||||||
gboolean header_only, int shrink, int fail, gboolean readbehind );
|
gboolean header_only, int shrink, int fail, gboolean readbehind,
|
||||||
|
gboolean autorotate );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -427,6 +427,7 @@ VipsImage *vips_image_new_matrix_from_array( int width, int height,
|
|||||||
double *array, int size );
|
double *array, int size );
|
||||||
void vips_image_set_delete_on_close( VipsImage *image,
|
void vips_image_set_delete_on_close( VipsImage *image,
|
||||||
gboolean delete_on_close );
|
gboolean delete_on_close );
|
||||||
|
guint64 vips_get_disc_threshold( void );
|
||||||
VipsImage *vips_image_new_temp_file( const char *format );
|
VipsImage *vips_image_new_temp_file( const char *format );
|
||||||
|
|
||||||
int vips_image_write( VipsImage *image, VipsImage *out );
|
int vips_image_write( VipsImage *image, VipsImage *out );
|
||||||
|
@ -2204,6 +2204,46 @@ vips_image_set_delete_on_close( VipsImage *image, gboolean delete_on_close )
|
|||||||
VIPS_SETSTR( image->delete_on_close_filename, image->filename );
|
VIPS_SETSTR( image->delete_on_close_filename, image->filename );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_get_disc_threshold:
|
||||||
|
*
|
||||||
|
* Return the number of bytes at which we flip between open via memory and
|
||||||
|
* open via disc. This defaults to 100mb, but can be changed with the
|
||||||
|
* VIPS_DISC_THRESHOLD environment variable or the --vips-disc-threshold
|
||||||
|
* command-line flag. See vips_image_new_from_file().
|
||||||
|
*
|
||||||
|
* Returns: disc threshold in bytes.
|
||||||
|
*/
|
||||||
|
guint64
|
||||||
|
vips_get_disc_threshold( void )
|
||||||
|
{
|
||||||
|
static gboolean done = FALSE;
|
||||||
|
static guint64 threshold;
|
||||||
|
|
||||||
|
if( !done ) {
|
||||||
|
const char *env;
|
||||||
|
|
||||||
|
done = TRUE;
|
||||||
|
|
||||||
|
/* 100mb default.
|
||||||
|
*/
|
||||||
|
threshold = 100 * 1024 * 1024;
|
||||||
|
|
||||||
|
if( (env = g_getenv( "VIPS_DISC_THRESHOLD" )) ||
|
||||||
|
(env = g_getenv( "IM_DISC_THRESHOLD" )) )
|
||||||
|
threshold = vips__parse_size( env );
|
||||||
|
|
||||||
|
if( vips__disc_threshold )
|
||||||
|
threshold = vips__parse_size( vips__disc_threshold );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "vips_get_disc_threshold: %zd bytes\n", threshold );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return( threshold );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_new_temp_file:
|
* vips_image_new_temp_file:
|
||||||
* @format: format of file
|
* @format: format of file
|
||||||
|
Loading…
Reference in New Issue
Block a user