finish reviding the fixed-up image load/save API
This commit is contained in:
parent
d426abdcd8
commit
35533a54cf
@ -25,7 +25,7 @@
|
|||||||
- dzsave can directly write a ZIP file
|
- dzsave can directly write a ZIP file
|
||||||
- add ".vips" as an alternative suffix for vips files
|
- add ".vips" as an alternative suffix for vips files
|
||||||
- added vips_tiffload_buffer()
|
- added vips_tiffload_buffer()
|
||||||
- added vips_foreign_load_buffer(), vips_foreign_save_buffer()
|
- added vips_image_new_from_buffer(), vips_image_write_to_buffer()
|
||||||
- added vips_object_set_from_string()
|
- added vips_object_set_from_string()
|
||||||
- added @container option to dzsave
|
- added @container option to dzsave
|
||||||
- support 1/2/4 bit palette tiff images with alpha
|
- support 1/2/4 bit palette tiff images with alpha
|
||||||
@ -36,6 +36,7 @@
|
|||||||
- im_*merge(), im_*mosaic(), im_match*(), im_global_balance*(), im_remosaic(),
|
- im_*merge(), im_*mosaic(), im_match*(), im_global_balance*(), im_remosaic(),
|
||||||
im_*mosaic1(), im_*merge1() redone as classes
|
im_*mosaic1(), im_*merge1() redone as classes
|
||||||
- better filename tracking for globalbalance
|
- better filename tracking for globalbalance
|
||||||
|
- revised vips8 image load/save API, now simpler and more logical
|
||||||
|
|
||||||
6/3/14 started 7.38.6
|
6/3/14 started 7.38.6
|
||||||
- grey ramp minimum was wrong
|
- grey ramp minimum was wrong
|
||||||
|
23
TODO
23
TODO
@ -1,25 +1,10 @@
|
|||||||
- vips_image_new_from_file() should take a set of options
|
- need something to write an image to an area of memory
|
||||||
|
|
||||||
implement it using vips_foreign_load()?
|
eg.:
|
||||||
|
|
||||||
foreign/vipsload.c uses vips_image_new_from_file() ... instead it should use
|
int vips_image_write_to_memory( VipsImage *x, void **buf, size_t *len )
|
||||||
the _mode thing
|
|
||||||
|
|
||||||
- likewise, vips_image_write_to_file() should take options. Implement in terms
|
maybe?
|
||||||
of vips_foreign_save()?
|
|
||||||
|
|
||||||
- also new_from_memory() (new from buffer?)
|
|
||||||
|
|
||||||
see vips_foreign_load_buffer() for API
|
|
||||||
|
|
||||||
- can get rid of vips_foreign_load() / vips_foreign_save()
|
|
||||||
|
|
||||||
also vips_foreign_load_from_buffer() or whatever it's called, and save too.
|
|
||||||
|
|
||||||
- do we still need all the vips_image_build() machinery? can't we just use
|
|
||||||
the foreign system?
|
|
||||||
|
|
||||||
only need a couple of basic modes:wq
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ vips_hough_new_accumulator( VipsHough *hough )
|
|||||||
|
|
||||||
VipsImage *accumulator;
|
VipsImage *accumulator;
|
||||||
|
|
||||||
accumulator = vips_image_new_buffer();
|
accumulator = vips_image_new_memory();
|
||||||
|
|
||||||
vips_image_pipelinev( accumulator,
|
vips_image_pipelinev( accumulator,
|
||||||
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL );
|
VIPS_DEMAND_STYLE_ANY, statistic->ready, NULL );
|
||||||
|
@ -249,7 +249,7 @@ vips__vector_to_ink( const char *domain,
|
|||||||
/* And now recode the vec to match the original im.
|
/* And now recode the vec to match the original im.
|
||||||
*/
|
*/
|
||||||
if( vips_image_encode( t[3], &t[4], im->Coding ) ||
|
if( vips_image_encode( t[3], &t[4], im->Coding ) ||
|
||||||
!(t[5] = vips_image_new_buffer()) ||
|
!(t[5] = vips_image_new_memory()) ||
|
||||||
vips_image_write( t[4], t[5] ) ) {
|
vips_image_write( t[4], t[5] ) ) {
|
||||||
g_object_unref( context );
|
g_object_unref( context );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -322,7 +322,7 @@ vips__ink_to_vector( const char *domain, VipsImage *im, VipsPel *ink, int *n )
|
|||||||
|
|
||||||
/* To a mem buffer, then copy to out.
|
/* To a mem buffer, then copy to out.
|
||||||
*/
|
*/
|
||||||
if( !(t[4] = vips_image_new_buffer()) ||
|
if( !(t[4] = vips_image_new_memory()) ||
|
||||||
vips_image_write( t[3], t[4] ) )
|
vips_image_write( t[3], t[4] ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ vips_rot45_build( VipsObject *object )
|
|||||||
if( vips_image_wio_input( rot45->in ) )
|
if( vips_image_wio_input( rot45->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
t[0] = vips_image_new_buffer();
|
t[0] = vips_image_new_memory();
|
||||||
if( vips_image_pipelinev( t[0],
|
if( vips_image_pipelinev( t[0],
|
||||||
VIPS_DEMAND_STYLE_ANY, rot45->in, NULL ) )
|
VIPS_DEMAND_STYLE_ANY, rot45->in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -1052,7 +1052,7 @@ strip_work( VipsThreadState *state, void *a )
|
|||||||
printf( "strip_work: writing to %s\n", buf );
|
printf( "strip_work: writing to %s\n", buf );
|
||||||
#endif /*DEBUG_VERBOSE*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
if( vips_foreign_save_buffer( x, dz->suffix, &buf, &len, NULL ) ) {
|
if( vips_image_write_to_buffer( x, dz->suffix, &buf, &len, NULL ) ) {
|
||||||
g_object_unref( x );
|
g_object_unref( x );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -540,22 +540,10 @@ vips_foreign_find_load( const char *name )
|
|||||||
return( G_OBJECT_CLASS_NAME( load_class ) );
|
return( G_OBJECT_CLASS_NAME( load_class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Kept for compat with earlier version of the vip8 API. Use
|
||||||
* vips_foreign_load:
|
* vips_image_new_from_file() now.
|
||||||
* @filename: file to load
|
|
||||||
* @out: output image
|
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
|
||||||
*
|
|
||||||
* Loads @filename into @out using the loader recommended by
|
|
||||||
* vips_foreign_find_load().
|
|
||||||
*
|
|
||||||
* Load options may be appended to @filename as "[name=value,...]" or given as
|
|
||||||
* a NULL-terminated list of name-value pairs at the end of the arguments.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_save().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_foreign_load( const char *name, VipsImage **out, ... )
|
vips_foreign_load( const char *name, VipsImage **out, ... )
|
||||||
{
|
{
|
||||||
@ -597,7 +585,7 @@ vips_foreign_find_load_buffer_sub( VipsForeignLoadClass *load_class,
|
|||||||
*
|
*
|
||||||
* Searches for an operation you could use to load a memory buffer.
|
* Searches for an operation you could use to load a memory buffer.
|
||||||
*
|
*
|
||||||
* See also: vips_foreign_load_buffer().
|
* See also: vips_image_new_from_buffer().
|
||||||
*
|
*
|
||||||
* Returns: the name of an operation on success, %NULL on error
|
* Returns: the name of an operation on success, %NULL on error
|
||||||
*/
|
*/
|
||||||
@ -618,48 +606,6 @@ vips_foreign_find_load_buffer( void *buf, size_t len )
|
|||||||
return( G_OBJECT_CLASS_NAME( load_class ) );
|
return( G_OBJECT_CLASS_NAME( load_class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_load_buffer:
|
|
||||||
* @buf: start of memory buffer
|
|
||||||
* @len: length of memory buffer
|
|
||||||
* @option_string: set of extra options as a string
|
|
||||||
* @out: output image
|
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
|
||||||
*
|
|
||||||
* Loads @buf, @len into @out using the loader recommended by
|
|
||||||
* vips_foreign_find_load_buffer(). @option_string can be used to give an
|
|
||||||
* extra set of load options.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_save().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
vips_foreign_load_buffer( void *buf, size_t len, const char *option_string,
|
|
||||||
VipsImage **out, ... )
|
|
||||||
{
|
|
||||||
const char *operation_name;
|
|
||||||
VipsArea *area;
|
|
||||||
va_list ap;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if( !(operation_name = vips_foreign_find_load_buffer( buf, len )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* We don't take a copy of the data or free it.
|
|
||||||
*/
|
|
||||||
area = vips_area_new_blob( NULL, buf, len );
|
|
||||||
|
|
||||||
va_start( ap, out );
|
|
||||||
result = vips_call_split_option_string( operation_name,
|
|
||||||
option_string, ap, area, out );
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
vips_area_unref( area );
|
|
||||||
|
|
||||||
return( result );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_foreign_is_a:
|
* vips_foreign_is_a:
|
||||||
* @loader: name of loader to use for test
|
* @loader: name of loader to use for test
|
||||||
@ -812,7 +758,7 @@ vips_foreign_load_temp( VipsForeignLoad *load )
|
|||||||
|
|
||||||
/* Otherwise, fall back to a memory buffer.
|
/* Otherwise, fall back to a memory buffer.
|
||||||
*/
|
*/
|
||||||
return( vips_image_new_buffer() );
|
return( vips_image_new_memory() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check two images for compatibility: their geometries need to match.
|
/* Check two images for compatibility: their geometries need to match.
|
||||||
@ -1506,22 +1452,9 @@ vips_foreign_find_save( const char *name )
|
|||||||
return( G_OBJECT_CLASS_NAME( save_class ) );
|
return( G_OBJECT_CLASS_NAME( save_class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Kept for early vips8 API compat.
|
||||||
* vips_foreign_save:
|
|
||||||
* @in: image to write
|
|
||||||
* @filename: file to write to
|
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
|
||||||
*
|
|
||||||
* Saves @in to @filename using the saver recommended by
|
|
||||||
* vips_foreign_find_save().
|
|
||||||
*
|
|
||||||
* Save options may be appended to @filename as "[name=value,...]" or given as
|
|
||||||
* a NULL-terminated list of name-value pairs at the end of the arguments.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_load().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_foreign_save( VipsImage *in, const char *name, ... )
|
vips_foreign_save( VipsImage *in, const char *name, ... )
|
||||||
{
|
{
|
||||||
@ -1568,7 +1501,7 @@ vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class,
|
|||||||
* Searches for an operation you could use to write to a buffer in @suffix
|
* Searches for an operation you could use to write to a buffer in @suffix
|
||||||
* format.
|
* format.
|
||||||
*
|
*
|
||||||
* See also: vips_foreign_save_buffer().
|
* See also: vips_image_write_to_buffer().
|
||||||
*
|
*
|
||||||
* Returns: the name of an operation on success, %NULL on error
|
* Returns: the name of an operation on success, %NULL on error
|
||||||
*/
|
*/
|
||||||
@ -1594,59 +1527,6 @@ vips_foreign_find_save_buffer( const char *name )
|
|||||||
return( G_OBJECT_CLASS_NAME( save_class ) );
|
return( G_OBJECT_CLASS_NAME( save_class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_save_buffer:
|
|
||||||
* @in: image to write
|
|
||||||
* @suffix: format to write
|
|
||||||
* @buf: return buffer start here
|
|
||||||
* @len: return buffer length here
|
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
|
||||||
*
|
|
||||||
* Saves @in to a memory buffer selected from @suffix. @suffix may also set
|
|
||||||
* save options, for example it could be ".jpg[Q=80]".
|
|
||||||
* Save options may also be given
|
|
||||||
* as a NULL-terminated list of name-value pairs.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_load_buffer().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
vips_foreign_save_buffer( VipsImage *in,
|
|
||||||
const char *name, void **buf, size_t *len,
|
|
||||||
... )
|
|
||||||
{
|
|
||||||
char suffix[VIPS_PATH_MAX];
|
|
||||||
char option_string[VIPS_PATH_MAX];
|
|
||||||
const char *operation_name;
|
|
||||||
VipsArea *area;
|
|
||||||
va_list ap;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
vips__filename_split8( name, suffix, option_string );
|
|
||||||
|
|
||||||
if( !(operation_name = vips_foreign_find_save_buffer( suffix )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
va_start( ap, len );
|
|
||||||
result = vips_call_split_option_string( operation_name, option_string,
|
|
||||||
ap, in, &area );
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
if( area ) {
|
|
||||||
if( buf ) {
|
|
||||||
*buf = area->data;
|
|
||||||
area->free_fn = NULL;
|
|
||||||
}
|
|
||||||
if( len )
|
|
||||||
*len = area->length;
|
|
||||||
|
|
||||||
vips_area_unref( area );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( result );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called from iofuncs to init all operations in this dir. Use a plugin system
|
/* Called from iofuncs to init all operations in this dir. Use a plugin system
|
||||||
* instead?
|
* instead?
|
||||||
*/
|
*/
|
||||||
|
@ -444,7 +444,7 @@ vips__openslide_read_associated( const char *filename, VipsImage *out,
|
|||||||
|
|
||||||
/* Memory buffer. Get associated directly to this, then copy to out.
|
/* Memory buffer. Get associated directly to this, then copy to out.
|
||||||
*/
|
*/
|
||||||
raw = vips_image_new_buffer();
|
raw = vips_image_new_memory();
|
||||||
vips_object_local( out, raw );
|
vips_object_local( out, raw );
|
||||||
|
|
||||||
if( !(rslide = readslide_new( filename, raw, 0, associated )) ||
|
if( !(rslide = readslide_new( filename, raw, 0, associated )) ||
|
||||||
|
@ -516,7 +516,7 @@ png2vips_image( Read *read, VipsImage *out )
|
|||||||
/* Arg awful interlaced image. We have to load to a huge mem
|
/* Arg awful interlaced image. We have to load to a huge mem
|
||||||
* buffer, then copy to out.
|
* buffer, then copy to out.
|
||||||
*/
|
*/
|
||||||
t[0] = vips_image_new_buffer();
|
t[0] = vips_image_new_memory();
|
||||||
if( png2vips_header( read, t[0] ) ||
|
if( png2vips_header( read, t[0] ) ||
|
||||||
png2vips_interlace( read, t[0] ) ||
|
png2vips_interlace( read, t[0] ) ||
|
||||||
vips_image_write( t[0], out ) )
|
vips_image_write( t[0], out ) )
|
||||||
|
@ -220,7 +220,7 @@ read_image( Read *read, VipsImage *out )
|
|||||||
vips_object_local_array( VIPS_OBJECT( out ), 3 );
|
vips_object_local_array( VIPS_OBJECT( out ), 3 );
|
||||||
webp_decoder decoder;
|
webp_decoder decoder;
|
||||||
|
|
||||||
t[0] = vips_image_new_buffer();
|
t[0] = vips_image_new_memory();
|
||||||
if( read_header( read, t[0] ) )
|
if( read_header( read, t[0] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( vips_image_write_prepare( t[0] ) )
|
if( vips_image_write_prepare( t[0] ) )
|
||||||
|
@ -96,7 +96,7 @@ vips_freqmult_build( VipsObject *object )
|
|||||||
* FIXME does this actually work now we're a class? test
|
* FIXME does this actually work now we're a class? test
|
||||||
* perhaps we need a temporary object
|
* perhaps we need a temporary object
|
||||||
*/
|
*/
|
||||||
t[4] = vips_image_new_buffer();
|
t[4] = vips_image_new_memory();
|
||||||
|
|
||||||
if( vips_fwfft( in, &t[0], NULL ) ||
|
if( vips_fwfft( in, &t[0], NULL ) ||
|
||||||
vips_multiply( t[0], freqmult->mask, &t[1], NULL ) ||
|
vips_multiply( t[0], freqmult->mask, &t[1], NULL ) ||
|
||||||
|
@ -115,7 +115,7 @@ rfwfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Convert input to a real double membuffer.
|
/* Convert input to a real double membuffer.
|
||||||
*/
|
*/
|
||||||
t[1] = vips_image_new_buffer();
|
t[1] = vips_image_new_memory();
|
||||||
if( vips_cast_double( in, &t[0], NULL ) ||
|
if( vips_cast_double( in, &t[0], NULL ) ||
|
||||||
vips_image_write( t[0], t[1] ) )
|
vips_image_write( t[0], t[1] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -145,7 +145,7 @@ rfwfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Write to out as another memory buffer.
|
/* Write to out as another memory buffer.
|
||||||
*/
|
*/
|
||||||
*out = vips_image_new_buffer();
|
*out = vips_image_new_memory();
|
||||||
if( vips_image_pipelinev( *out, VIPS_DEMAND_STYLE_ANY, in, NULL ) )
|
if( vips_image_pipelinev( *out, VIPS_DEMAND_STYLE_ANY, in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
(*out)->BandFmt = VIPS_FORMAT_DPCOMPLEX;
|
(*out)->BandFmt = VIPS_FORMAT_DPCOMPLEX;
|
||||||
@ -230,7 +230,7 @@ cfwfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Convert input to a complex double membuffer.
|
/* Convert input to a complex double membuffer.
|
||||||
*/
|
*/
|
||||||
t[1] = vips_image_new_buffer();
|
t[1] = vips_image_new_memory();
|
||||||
if( vips_cast_dpcomplex( in, &t[0], NULL ) ||
|
if( vips_cast_dpcomplex( in, &t[0], NULL ) ||
|
||||||
vips_image_write( t[0], t[1] ) )
|
vips_image_write( t[0], t[1] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -260,7 +260,7 @@ cfwfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Write to out as another memory buffer.
|
/* Write to out as another memory buffer.
|
||||||
*/
|
*/
|
||||||
*out = vips_image_new_buffer();
|
*out = vips_image_new_memory();
|
||||||
if( vips_image_pipelinev( *out, VIPS_DEMAND_STYLE_ANY, in, NULL ) )
|
if( vips_image_pipelinev( *out, VIPS_DEMAND_STYLE_ANY, in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
(*out)->BandFmt = VIPS_FORMAT_DPCOMPLEX;
|
(*out)->BandFmt = VIPS_FORMAT_DPCOMPLEX;
|
||||||
|
@ -100,7 +100,7 @@ cinvfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Convert input to a complex double membuffer.
|
/* Convert input to a complex double membuffer.
|
||||||
*/
|
*/
|
||||||
*out = vips_image_new_buffer();
|
*out = vips_image_new_memory();
|
||||||
if( vips_cast_dpcomplex( in, &t[0], NULL ) ||
|
if( vips_cast_dpcomplex( in, &t[0], NULL ) ||
|
||||||
vips_image_write( t[0], *out ) )
|
vips_image_write( t[0], *out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -149,7 +149,7 @@ rinvfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Convert input to a complex double membuffer.
|
/* Convert input to a complex double membuffer.
|
||||||
*/
|
*/
|
||||||
t[1] = vips_image_new_buffer();
|
t[1] = vips_image_new_memory();
|
||||||
if( vips_cast_dpcomplex( in, &t[0], NULL ) ||
|
if( vips_cast_dpcomplex( in, &t[0], NULL ) ||
|
||||||
vips_image_write( t[0], t[1] ) )
|
vips_image_write( t[0], t[1] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -173,7 +173,7 @@ rinvfft1( VipsObject *object, VipsImage *in, VipsImage **out )
|
|||||||
|
|
||||||
/* Make mem buffer real image for output.
|
/* Make mem buffer real image for output.
|
||||||
*/
|
*/
|
||||||
*out = vips_image_new_buffer();
|
*out = vips_image_new_memory();
|
||||||
if( vips_image_pipelinev( *out, VIPS_DEMAND_STYLE_ANY, t[1], NULL ) )
|
if( vips_image_pipelinev( *out, VIPS_DEMAND_STYLE_ANY, t[1], NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
(*out)->BandFmt = VIPS_FORMAT_DOUBLE;
|
(*out)->BandFmt = VIPS_FORMAT_DOUBLE;
|
||||||
|
@ -307,21 +307,7 @@ typedef struct _VipsForeignSaveClass {
|
|||||||
GType vips_foreign_save_get_type( void );
|
GType vips_foreign_save_get_type( void );
|
||||||
|
|
||||||
const char *vips_foreign_find_save( const char *filename );
|
const char *vips_foreign_find_save( const char *filename );
|
||||||
const char * vips_foreign_find_save_buffer( const char *suffix );
|
const char *vips_foreign_find_save_buffer( const char *suffix );
|
||||||
|
|
||||||
/* Read/write an image convenience functions.
|
|
||||||
*/
|
|
||||||
int vips_foreign_load( const char *filename, VipsImage **out, ... )
|
|
||||||
__attribute__((sentinel));
|
|
||||||
int vips_foreign_save( VipsImage *in, const char *filename, ... )
|
|
||||||
__attribute__((sentinel));
|
|
||||||
|
|
||||||
int vips_foreign_load_buffer( void *buf, size_t len, const char *option_string,
|
|
||||||
VipsImage **out, ... )
|
|
||||||
__attribute__((sentinel));
|
|
||||||
int vips_foreign_save_buffer( VipsImage *in,
|
|
||||||
const char *suffix, void **buf, size_t *len, ... )
|
|
||||||
__attribute__((sentinel));
|
|
||||||
|
|
||||||
int vips_openslideload( const char *filename, VipsImage **out, ... )
|
int vips_openslideload( const char *filename, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
@ -416,21 +416,29 @@ void vips_image_set_kill( VipsImage *image, gboolean kill );
|
|||||||
|
|
||||||
VipsImage *vips_image_new( void );
|
VipsImage *vips_image_new( void );
|
||||||
VipsImage *vips_image_new_mode( const char *filename, const char *mode );
|
VipsImage *vips_image_new_mode( const char *filename, const char *mode );
|
||||||
VipsImage *vips_image_new_buffer( void );
|
VipsImage *vips_image_new_memory( void );
|
||||||
VipsImage *vips_image_new_from_file( const char *filename, ... )
|
VipsImage *vips_image_new_from_file( const char *filename, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
VipsImage *vips_image_new_from_file_RW( const char *filename );
|
||||||
VipsImage *vips_image_new_from_file_raw( const char *filename,
|
VipsImage *vips_image_new_from_file_raw( const char *filename,
|
||||||
int xsize, int ysize, int bands, guint64 offset );
|
int xsize, int ysize, int bands, guint64 offset );
|
||||||
VipsImage *vips_image_new_from_memory( void *buffer,
|
VipsImage *vips_image_new_from_memory( void *buffer,
|
||||||
int xsize, int ysize, int bands, VipsBandFormat bandfmt );
|
int xsize, int ysize, int bands, VipsBandFormat bandfmt );
|
||||||
|
VipsImage *vips_image_new_from_buffer( void *buf, size_t len,
|
||||||
|
const char *option_string, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
VipsImage *vips_image_new_matrix( int width, int height );
|
VipsImage *vips_image_new_matrix( int width, int height );
|
||||||
VipsImage *vips_image_new_matrixv( int width, int height, ... );
|
VipsImage *vips_image_new_matrixv( int width, int height, ... );
|
||||||
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 );
|
||||||
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 );
|
||||||
int vips_image_write_to_file( VipsImage *image, const char *filename, ... )
|
int vips_image_write_to_file( VipsImage *image, const char *filename, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
int vips_image_write_to_buffer( VipsImage *in,
|
||||||
|
const char *name, void **buf, size_t *len, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
|
||||||
int vips_image_decode_predict( VipsImage *im,
|
int vips_image_decode_predict( VipsImage *im,
|
||||||
int *bands, VipsBandFormat *format );
|
int *bands, VipsBandFormat *format );
|
||||||
|
@ -315,6 +315,11 @@ IMAGE *vips__deprecated_open_write( const char *filename );
|
|||||||
|
|
||||||
int vips__input_interpolate_init( im_object *obj, char *str );
|
int vips__input_interpolate_init( im_object *obj, char *str );
|
||||||
|
|
||||||
|
int vips_foreign_load( const char *filename, VipsImage **out, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
int vips_foreign_save( VipsImage *in, const char *filename, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
@ -1538,109 +1538,6 @@ vips_image_new( void )
|
|||||||
return( image );
|
return( image );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_image_new_mode:
|
|
||||||
* @filename: file to open
|
|
||||||
* @mode: mode to open with
|
|
||||||
*
|
|
||||||
* vips_image_new_mode() examines the mode string and creates an
|
|
||||||
* appropriate #VipsImage.
|
|
||||||
*
|
|
||||||
* This function (mostly) exists to support the vips7 compatibility layer.
|
|
||||||
* vips8 programs should use vips_image_new_from_file() and friends.
|
|
||||||
*
|
|
||||||
* <itemizedlist>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"t"</emphasis>
|
|
||||||
* creates a temporary memory buffer image.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"p"</emphasis>
|
|
||||||
* creates a "glue" descriptor you can use to join operations, see also
|
|
||||||
* vips_image_new().
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"r"</emphasis>
|
|
||||||
* opens the named file for reading. If the file is not in the native
|
|
||||||
* VIPS format for your machine, vips_image_new_mode()
|
|
||||||
* automatically converts the file for you.
|
|
||||||
*
|
|
||||||
* Some formats (eg. tiled tiff) are read directly.
|
|
||||||
*
|
|
||||||
* Some formats (eg. strip tiff) do not support random access and can't
|
|
||||||
* be processed directly. Small images are decompressed to memory and
|
|
||||||
* loaded from there, large images are decompressed to a disc file and
|
|
||||||
* processed from that.
|
|
||||||
*
|
|
||||||
* If the operations you intend to perform are sequential, that is, they
|
|
||||||
* operate in a strict top-to-bottom manner, you can use sequential mode
|
|
||||||
* instead, see "rs" below,
|
|
||||||
* or you can use the lower-level
|
|
||||||
* API and control the loading process yourself. See
|
|
||||||
* #VipsForeign.
|
|
||||||
*
|
|
||||||
* See vips_image_new_temp_file() for an explanation of how VIPS selects a
|
|
||||||
* location for the temporary file.
|
|
||||||
*
|
|
||||||
* The disc threshold can be set with the "--vips-disc-threshold"
|
|
||||||
* command-line argument, or the VIPS_DISC_THRESHOLD environment variable.
|
|
||||||
* The value is a simple integer, but can take a unit postfix of "k",
|
|
||||||
* "m" or "g" to indicate kilobytes, megabytes or gigabytes.
|
|
||||||
*
|
|
||||||
* For example:
|
|
||||||
*
|
|
||||||
* |[
|
|
||||||
* vips --vips-disc-threshold 500m copy fred.tif fred.v
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* will copy via disc if "fred.tif" is more than 500 Mbytes
|
|
||||||
* uncompressed. The default threshold is 100 MB.
|
|
||||||
*
|
|
||||||
* Note that <emphasis>"r"</emphasis> mode works in at least two stages.
|
|
||||||
* It should return quickly and let you check header fields. It will
|
|
||||||
* only actually read in pixels when you first access them.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"rs"</emphasis>
|
|
||||||
* opens the named file for reading sequentially. It reads the source
|
|
||||||
* image top-to-bottom and serves up pixels to the pipeline as required.
|
|
||||||
* Provided the operations that connect to the image all demand pixels
|
|
||||||
* only top-to-bottom as well, everything is fine and you avoid the
|
|
||||||
* separate decompress stage.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"w"</emphasis>
|
|
||||||
* opens the named file for writing. It looks at the file name
|
|
||||||
* suffix to determine the type to write -- for example:
|
|
||||||
*
|
|
||||||
* |[
|
|
||||||
* vips_image_new_mode( "fred.tif", "w" )
|
|
||||||
* ]|
|
|
||||||
*
|
|
||||||
* will write in TIFF format.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"rw"</emphasis>
|
|
||||||
* opens the named file for reading and writing. This will only work for
|
|
||||||
* VIPS files in a format native to your machine. It is only for
|
|
||||||
* paintbox-type applications.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* </itemizedlist>
|
|
||||||
*
|
|
||||||
* Returns: the new #VipsImage, or %NULL on error.
|
|
||||||
*/
|
|
||||||
VipsImage *
|
VipsImage *
|
||||||
vips_image_new_mode( const char *filename, const char *mode )
|
vips_image_new_mode( const char *filename, const char *mode )
|
||||||
{
|
{
|
||||||
@ -1665,10 +1562,10 @@ vips_image_new_mode( const char *filename, const char *mode )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_new_buffer:
|
* vips_image_new_memory:
|
||||||
*
|
*
|
||||||
* vips_image_new_buffer() creates a new VipsImage which when written to will
|
* vips_image_new_memory() creates a new #VipsImage which, when written to, will
|
||||||
* create a memory buffer. It is a convenience function for
|
* create a memory image. It is a convenience function for
|
||||||
* vips_image_new_mode(vips_image_temp_name(), "t").
|
* vips_image_new_mode(vips_image_temp_name(), "t").
|
||||||
*
|
*
|
||||||
* See also: vips_image_new().
|
* See also: vips_image_new().
|
||||||
@ -1676,7 +1573,7 @@ vips_image_new_mode( const char *filename, const char *mode )
|
|||||||
* Returns: the new #VipsImage, or %NULL on error.
|
* Returns: the new #VipsImage, or %NULL on error.
|
||||||
*/
|
*/
|
||||||
VipsImage *
|
VipsImage *
|
||||||
vips_image_new_buffer( void )
|
vips_image_new_memory( void )
|
||||||
{
|
{
|
||||||
return( vips_image_new_mode( vips_image_temp_name(), "t" ) );
|
return( vips_image_new_mode( vips_image_temp_name(), "t" ) );
|
||||||
}
|
}
|
||||||
@ -1686,6 +1583,12 @@ vips_image_new_buffer( void )
|
|||||||
* @name: file to open
|
* @name: file to open
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
*
|
*
|
||||||
|
* Optional arguments:
|
||||||
|
*
|
||||||
|
* @access: hint #VipsAccess mode to loader
|
||||||
|
* @disc: load via a temporary disc file
|
||||||
|
* @...: other arguments depend on the loader
|
||||||
|
*
|
||||||
* vips_image_new_from_file() opens @name for reading. It can load files
|
* vips_image_new_from_file() opens @name for reading. It can load files
|
||||||
* in many image formats, including VIPS, TIFF, PNG, JPEG, FITS, Matlab,
|
* in many image formats, including VIPS, TIFF, PNG, JPEG, FITS, Matlab,
|
||||||
* OpenEXR, CSV, WebP, Radiance, RAW, PPM and others.
|
* OpenEXR, CSV, WebP, Radiance, RAW, PPM and others.
|
||||||
@ -1694,7 +1597,48 @@ vips_image_new_buffer( void )
|
|||||||
* a NULL-terminated list of name-value pairs at the end of the arguments.
|
* a NULL-terminated list of name-value pairs at the end of the arguments.
|
||||||
* Options given in the function call override options given in the filename.
|
* Options given in the function call override options given in the filename.
|
||||||
*
|
*
|
||||||
* See also: vips_foreign_load(), vips_image_write_to_file().
|
* vips_image_new_from_file() always returns immediately with the header
|
||||||
|
* fields filled in. No pixels are actually read until you first access them.
|
||||||
|
*
|
||||||
|
* @access lets you hint the expected access pattern for this file.
|
||||||
|
* #VIPS_ACCESS_RANDOM means you can fetch pixels randomly from the image.
|
||||||
|
* This is the default mode. #VIPS_ACCESS_SEQUENTIAL means you will read the
|
||||||
|
* whole image exactly once, top-to-bottom. In this mode, vips can avoid
|
||||||
|
* converting the whole image in one go, for a large memory saving. You are
|
||||||
|
* allowed to make small non-local references, so area operations like
|
||||||
|
* convolution will work. #VIPS_ACCESS_SEQUENTIAL_UNBUFFERED does not allow
|
||||||
|
* non-local references, so will only work for very strict top-to-bottom
|
||||||
|
* operations, but does have very low memory needs.
|
||||||
|
*
|
||||||
|
* In #VIPS_ACCESS_RANDOM mode, small images are decompressed to memory and
|
||||||
|
* then processed from there. Large images are decompressed to temporary
|
||||||
|
* random-access files on disc and then processed from there. Set @disc to
|
||||||
|
* %TRUE to force loading via disc. See vips_image_new_temp_file() for an
|
||||||
|
* explanation of how VIPS selects a location for the temporary file.
|
||||||
|
*
|
||||||
|
* The disc threshold can be set with the "--vips-disc-threshold"
|
||||||
|
* command-line argument, or the VIPS_DISC_THRESHOLD environment variable.
|
||||||
|
* The value is a simple integer, but can take a unit postfix of "k",
|
||||||
|
* "m" or "g" to indicate kilobytes, megabytes or gigabytes.
|
||||||
|
* The default threshold is 100 MB.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* VipsImage *image = vips_image_new_from_file ("fred.tif",
|
||||||
|
* "page", 12,
|
||||||
|
* NULL);
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* Will open "fred.tif", reading page 12.
|
||||||
|
*
|
||||||
|
* Use vips_foreign_find_load() or vips_foreign_is_a() to see what format a
|
||||||
|
* file is in and therefore what options are available. If you need more
|
||||||
|
* control over the loading process, you can call loaders directly, see
|
||||||
|
* vips_jpegload(), for example.
|
||||||
|
*
|
||||||
|
* See also: vips_foreign_find_load(), vips_foreign_is_a(),
|
||||||
|
* vips_image_write_to_file().
|
||||||
*
|
*
|
||||||
* Returns: the new #VipsImage, or %NULL on error.
|
* Returns: the new #VipsImage, or %NULL on error.
|
||||||
*/
|
*/
|
||||||
@ -1723,6 +1667,24 @@ vips_image_new_from_file( const char *name, ... )
|
|||||||
return( out );
|
return( out );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_image_new_from_file_RW:
|
||||||
|
* @filename: filename to open
|
||||||
|
*
|
||||||
|
* Opens the named file for reading and writing. This will only work for
|
||||||
|
* VIPS files in a format native to your machine. It is only for
|
||||||
|
* paintbox-type applications.
|
||||||
|
*
|
||||||
|
* See also: vips_draw_circle().
|
||||||
|
*
|
||||||
|
* Returns: the new #VipsImage, or %NULL on error.
|
||||||
|
*/
|
||||||
|
VipsImage *
|
||||||
|
vips_image_new_from_file_RW( const char *filename )
|
||||||
|
{
|
||||||
|
return( vips_image_new_mode( filename, "rw" ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_new_from_file_raw:
|
* vips_image_new_from_file_raw:
|
||||||
* @filename: filename to open
|
* @filename: filename to open
|
||||||
@ -1774,11 +1736,18 @@ vips_image_new_from_file_raw( const char *filename,
|
|||||||
* @bands: image bands (or bytes per pixel)
|
* @bands: image bands (or bytes per pixel)
|
||||||
* @bandfmt: image format
|
* @bandfmt: image format
|
||||||
*
|
*
|
||||||
* This function wraps an #IMAGE around a memory buffer. VIPS does not take
|
* This function wraps a #VipsImage around a memory area. The memory area
|
||||||
|
* must be a simple array, for example RGBRGBRGB, left-to-right,
|
||||||
|
* top-to-bottom. Use vips_image_new_from_buffer() to load an area of memory
|
||||||
|
* containing an image in a format.
|
||||||
|
*
|
||||||
|
* VIPS does not take
|
||||||
* responsibility for the area of memory, it's up to you to make sure it's
|
* responsibility for the area of memory, it's up to you to make sure it's
|
||||||
* freed when the image is closed. See for example #VipsObject::close.
|
* freed when the image is closed. See for example #VipsObject::close.
|
||||||
*
|
*
|
||||||
* See also: im_binfile(), im_raw2vips(), vips_image_new().
|
* Use vips_copy_morph() to set other image properties.
|
||||||
|
*
|
||||||
|
* See also: vips_image_new().
|
||||||
*
|
*
|
||||||
* Returns: the new #VipsImage, or %NULL on error.
|
* Returns: the new #VipsImage, or %NULL on error.
|
||||||
*/
|
*/
|
||||||
@ -1808,6 +1777,60 @@ vips_image_new_from_memory( void *buffer,
|
|||||||
return( image );
|
return( image );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_image_new_from_buffer:
|
||||||
|
* @buf: start of memory buffer
|
||||||
|
* @len: length of memory buffer
|
||||||
|
* @option_string: set of extra options as a string
|
||||||
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
|
*
|
||||||
|
* Loads an image from the formatted area of memory @buf, @len using the
|
||||||
|
* loader recommended by vips_foreign_find_load_buffer(). Only TIFF, PNG and
|
||||||
|
* JPEG formats are supported. To load an unformatted area of memory, use
|
||||||
|
* vips_image_new_from_memory().
|
||||||
|
*
|
||||||
|
* VIPS does not take
|
||||||
|
* responsibility for the area of memory, it's up to you to make sure it's
|
||||||
|
* freed when the image is closed. See for example #VipsObject::close.
|
||||||
|
*
|
||||||
|
* Load options may be given in @option_string as "[name=value,...]" or given as
|
||||||
|
* a NULL-terminated list of name-value pairs at the end of the arguments.
|
||||||
|
* Options given in the function call override options given in the filename.
|
||||||
|
*
|
||||||
|
* See also: vips_image_write_to_buffer().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
VipsImage *
|
||||||
|
vips_image_new_from_buffer( void *buf, size_t len,
|
||||||
|
const char *option_string, ... )
|
||||||
|
{
|
||||||
|
const char *operation_name;
|
||||||
|
VipsArea *area;
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
VipsImage *out;
|
||||||
|
|
||||||
|
if( !(operation_name = vips_foreign_find_load_buffer( buf, len )) )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
/* We don't take a copy of the data or free it.
|
||||||
|
*/
|
||||||
|
area = vips_area_new_blob( NULL, buf, len );
|
||||||
|
|
||||||
|
va_start( ap, option_string );
|
||||||
|
result = vips_call_split_option_string( operation_name,
|
||||||
|
option_string, ap, area, &out );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
vips_area_unref( area );
|
||||||
|
|
||||||
|
if( result )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
return( out );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_new_matrix:
|
* vips_image_new_matrix:
|
||||||
* @width: image width
|
* @width: image width
|
||||||
@ -2042,6 +2065,63 @@ vips_image_write_to_file( VipsImage *image, const char *name, ... )
|
|||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_image_write_to_buffer:
|
||||||
|
* @in: image to write
|
||||||
|
* @suffix: format to write
|
||||||
|
* @buf: return buffer start here
|
||||||
|
* @len: return buffer length here
|
||||||
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
|
*
|
||||||
|
* Writes @in to a memory buffer selected from @suffix. @suffix may also set
|
||||||
|
* save options, for example it could be ".jpg[Q=80]".
|
||||||
|
* Save options may also be given
|
||||||
|
* as a NULL-terminated list of name-value pairs.
|
||||||
|
*
|
||||||
|
* Currently only TIFF, JPEG and PNG formats are supported.
|
||||||
|
*
|
||||||
|
* You can call the various save operations directly if you wish, see
|
||||||
|
* vips_jpegsave_buffer(), for example.
|
||||||
|
*
|
||||||
|
* See also: vips_image_new_from_buffer().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_image_write_to_buffer( VipsImage *in,
|
||||||
|
const char *name, void **buf, size_t *len,
|
||||||
|
... )
|
||||||
|
{
|
||||||
|
char suffix[VIPS_PATH_MAX];
|
||||||
|
char option_string[VIPS_PATH_MAX];
|
||||||
|
const char *operation_name;
|
||||||
|
VipsArea *area;
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
vips__filename_split8( name, suffix, option_string );
|
||||||
|
if( !(operation_name = vips_foreign_find_save_buffer( suffix )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
va_start( ap, len );
|
||||||
|
result = vips_call_split_option_string( operation_name, option_string,
|
||||||
|
ap, in, &area );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
if( area ) {
|
||||||
|
if( buf ) {
|
||||||
|
*buf = area->data;
|
||||||
|
area->free_fn = NULL;
|
||||||
|
}
|
||||||
|
if( len )
|
||||||
|
*len = area->length;
|
||||||
|
|
||||||
|
vips_area_unref( area );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_decode:
|
* vips_image_decode:
|
||||||
* @in: image to decode
|
* @in: image to decode
|
||||||
@ -2464,7 +2544,7 @@ vips_image_wio_input( VipsImage *image )
|
|||||||
/* Change to VIPS_IMAGE_SETBUF. First, make a memory
|
/* Change to VIPS_IMAGE_SETBUF. First, make a memory
|
||||||
* buffer and copy into that.
|
* buffer and copy into that.
|
||||||
*/
|
*/
|
||||||
t1 = vips_image_new_buffer();
|
t1 = vips_image_new_memory();
|
||||||
if( vips_image_write( image, t1 ) ) {
|
if( vips_image_write( image, t1 ) ) {
|
||||||
g_object_unref( t1 );
|
g_object_unref( t1 );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
Loading…
Reference in New Issue
Block a user