Merge branch 'master' into dzsave-gsf
This commit is contained in:
commit
5a8c9fb4ef
15
TODO
15
TODO
@ -4,27 +4,12 @@
|
|||||||
|
|
||||||
heh fix
|
heh fix
|
||||||
|
|
||||||
- use vips_object_set_from_string() for vips_foreign_load_options() and
|
|
||||||
friends
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- use this for dzsave_buffer
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- clean up foreign.c, there seems to be some cruft
|
|
||||||
|
|
||||||
- vips_filename_suffix_match() is used by
|
- vips_filename_suffix_match() is used by
|
||||||
vips_foreign_load_new_from_foreign_sub(), but it splits on ':' ... argh!
|
vips_foreign_load_new_from_foreign_sub(), but it splits on ':' ... argh!
|
||||||
|
|
||||||
deprecate this thing and stop ':' split
|
deprecate this thing and stop ':' split
|
||||||
|
|
||||||
vips_foreign_find_save() should split on [], there's something to find the
|
|
||||||
start of the rightmost [] pair, use that
|
|
||||||
|
|
||||||
see also vips_foreign_find_save_buffer()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <vips/intl.h>
|
#include <vips/intl.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <vips/vips.h>
|
#include <vips/vips.h>
|
||||||
|
|
||||||
|
@ -466,6 +466,8 @@ vips_foreign_load_summary_class( VipsObjectClass *object_class, VipsBuf *buf )
|
|||||||
if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) ) {
|
if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) ) {
|
||||||
if( class->is_a )
|
if( class->is_a )
|
||||||
vips_buf_appends( buf, ", is_a" );
|
vips_buf_appends( buf, ", is_a" );
|
||||||
|
if( class->is_a_buffer )
|
||||||
|
vips_buf_appends( buf, ", is_a_buffer" );
|
||||||
if( class->get_flags )
|
if( class->get_flags )
|
||||||
vips_buf_appends( buf, ", get_flags" );
|
vips_buf_appends( buf, ", get_flags" );
|
||||||
if( class->get_flags_filename )
|
if( class->get_flags_filename )
|
||||||
@ -484,7 +486,7 @@ vips_foreign_load_summary_class( VipsObjectClass *object_class, VipsBuf *buf )
|
|||||||
/* Can this VipsForeign open this file?
|
/* Can this VipsForeign open this file?
|
||||||
*/
|
*/
|
||||||
static void *
|
static void *
|
||||||
vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class,
|
vips_foreign_find_load_sub( VipsForeignLoadClass *load_class,
|
||||||
const char *filename )
|
const char *filename )
|
||||||
{
|
{
|
||||||
VipsForeignClass *class = VIPS_FOREIGN_CLASS( load_class );
|
VipsForeignClass *class = VIPS_FOREIGN_CLASS( load_class );
|
||||||
@ -504,35 +506,74 @@ vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class,
|
|||||||
* vips_foreign_find_load:
|
* vips_foreign_find_load:
|
||||||
* @filename: file to find a loader for
|
* @filename: file to find a loader for
|
||||||
*
|
*
|
||||||
* Searches for an operation you could use to load @filename.
|
* Searches for an operation you could use to load @filename. Any trailing
|
||||||
|
* options on @filename are stripped and ignored.
|
||||||
*
|
*
|
||||||
* See also: vips_foreign_load().
|
* See also: vips_foreign_load().
|
||||||
*
|
*
|
||||||
* Returns: the name of an operation on success, %NULL on error
|
* Returns: the name of an operation on success, %NULL on error
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
vips_foreign_find_load( const char *filename )
|
vips_foreign_find_load( const char *name )
|
||||||
{
|
{
|
||||||
|
char filename[VIPS_PATH_MAX];
|
||||||
|
char option_string[VIPS_PATH_MAX];
|
||||||
VipsForeignLoadClass *load_class;
|
VipsForeignLoadClass *load_class;
|
||||||
|
|
||||||
|
vips__filename_split8( name, filename, option_string );
|
||||||
|
|
||||||
if( !vips_existsf( "%s", filename ) ) {
|
if( !vips_existsf( "%s", filename ) ) {
|
||||||
vips_error( "VipsForeignLoad",
|
vips_error( "VipsForeignLoad",
|
||||||
_( "file \"%s\" not found" ), filename );
|
_( "file \"%s\" not found" ), name );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
|
if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
|
||||||
"VipsForeignLoad",
|
"VipsForeignLoad",
|
||||||
(VipsSListMap2Fn) vips_foreign_load_new_from_foreign_sub,
|
(VipsSListMap2Fn) vips_foreign_find_load_sub,
|
||||||
(void *) filename, NULL )) ) {
|
(void *) filename, NULL )) ) {
|
||||||
vips_error( "VipsForeignLoad",
|
vips_error( "VipsForeignLoad",
|
||||||
_( "\"%s\" is not a known file format" ), filename );
|
_( "\"%s\" is not a known file format" ), name );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( G_OBJECT_CLASS_NAME( load_class ) );
|
return( G_OBJECT_CLASS_NAME( load_class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_foreign_load:
|
||||||
|
* @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().
|
||||||
|
*
|
||||||
|
* See also: vips_foreign_save(), vips_foreign_load_options().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_foreign_load( const char *name, VipsImage **out, ... )
|
||||||
|
{
|
||||||
|
char filename[VIPS_PATH_MAX];
|
||||||
|
char option_string[VIPS_PATH_MAX];
|
||||||
|
const char *operation_name;
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
vips__filename_split8( name, filename, option_string );
|
||||||
|
if( !(operation_name = vips_foreign_find_load( filename )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
va_start( ap, out );
|
||||||
|
result = vips_call_split_option_string( operation_name, option_string,
|
||||||
|
ap, filename, out );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
/* Can this VipsForeign open this buffer?
|
/* Can this VipsForeign open this buffer?
|
||||||
*/
|
*/
|
||||||
static void *
|
static void *
|
||||||
@ -547,10 +588,11 @@ vips_foreign_find_load_buffer_sub( VipsForeignLoadClass *load_class,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_foreign_find_load:
|
* vips_foreign_find_load_buffer:
|
||||||
* @filename: file to find a loader for
|
* @buf: start of memory buffer
|
||||||
|
* @len: length of memory buffer
|
||||||
*
|
*
|
||||||
* Searches for an operation you could use to load @filename.
|
* Searches for an operation you could use to load a memory buffer.
|
||||||
*
|
*
|
||||||
* See also: vips_foreign_load_buffer().
|
* See also: vips_foreign_load_buffer().
|
||||||
*
|
*
|
||||||
@ -574,37 +616,45 @@ vips_foreign_find_load_buffer( void *buf, size_t len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_foreign_find_load_options:
|
* vips_foreign_load_buffer:
|
||||||
* @filename: file to find a loader for
|
* @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
|
||||||
*
|
*
|
||||||
* Searches for an operation you could use to load @filename.
|
* 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.
|
||||||
*
|
*
|
||||||
* Arguments to the loader may be embedded in the filename using the usual
|
* See also: vips_foreign_save(), vips_foreign_load_options().
|
||||||
* syntax.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_load().
|
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
const char *
|
int
|
||||||
vips_foreign_find_load_options( const char *filename )
|
vips_foreign_load_buffer( void *buf, size_t len, const char *option_string,
|
||||||
|
VipsImage **out, ... )
|
||||||
{
|
{
|
||||||
VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD );
|
const char *operation_name;
|
||||||
VipsObject *object;
|
VipsArea *area;
|
||||||
const char *type_name;
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
/* This will use vips_foreign_load_new_from_string() to pick a loader,
|
if( !(operation_name = vips_foreign_find_load_buffer( buf, len )) )
|
||||||
* then set options from the tail of the filename. This is rather slow
|
return( -1 );
|
||||||
* :-(
|
|
||||||
|
/* We don't take a copy of the data or free it.
|
||||||
*/
|
*/
|
||||||
if( !(object = vips_object_new_from_string( oclass, filename )) )
|
area = vips_area_new_blob( NULL, buf, len );
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
type_name = G_OBJECT_TYPE_NAME( object );
|
va_start( ap, out );
|
||||||
|
result = vips_call_split_option_string( operation_name,
|
||||||
|
option_string, ap, area, out );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
g_object_unref( object );
|
vips_area_unref( area );
|
||||||
|
|
||||||
return( type_name );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -694,7 +744,8 @@ vips_get_disc_threshold( void )
|
|||||||
*/
|
*/
|
||||||
threshold = 100 * 1024 * 1024;
|
threshold = 100 * 1024 * 1024;
|
||||||
|
|
||||||
if( (env = g_getenv( "IM_DISC_THRESHOLD" )) )
|
if( (env = g_getenv( "VIPS_DISC_THRESHOLD" )) ||
|
||||||
|
(env = g_getenv( "IM_DISC_THRESHOLD" )) )
|
||||||
threshold = vips__parse_size( env );
|
threshold = vips__parse_size( env );
|
||||||
|
|
||||||
if( vips__disc_threshold )
|
if( vips__disc_threshold )
|
||||||
@ -1039,135 +1090,6 @@ vips_foreign_save_summary_class( VipsObjectClass *object_class, VipsBuf *buf )
|
|||||||
vips_enum_nick( VIPS_TYPE_SAVEABLE, class->saveable ) );
|
vips_enum_nick( VIPS_TYPE_SAVEABLE, class->saveable ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can we write this filename with this file?
|
|
||||||
*/
|
|
||||||
static void *
|
|
||||||
vips_foreign_find_save_sub( VipsForeignSaveClass *save_class,
|
|
||||||
const char *filename )
|
|
||||||
{
|
|
||||||
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
|
|
||||||
|
|
||||||
if( class->suffs &&
|
|
||||||
vips_filename_suffix_match( filename, class->suffs ) )
|
|
||||||
return( save_class );
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_find_save:
|
|
||||||
* @filename: name to find a saver for
|
|
||||||
*
|
|
||||||
* Searches for an operation you could use to write to @filename.
|
|
||||||
*
|
|
||||||
* @filename may not contain embedded options. See
|
|
||||||
* vips_foreign_find_save_options() if your filename may have options in.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_save().
|
|
||||||
*
|
|
||||||
* Returns: the name of an operation on success, %NULL on error
|
|
||||||
*/
|
|
||||||
const char *
|
|
||||||
vips_foreign_find_save( const char *filename )
|
|
||||||
{
|
|
||||||
VipsForeignSaveClass *save_class;
|
|
||||||
|
|
||||||
if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
|
|
||||||
"VipsForeignSave",
|
|
||||||
(VipsSListMap2Fn) vips_foreign_find_save_sub,
|
|
||||||
(void *) filename, NULL )) ) {
|
|
||||||
vips_error( "VipsForeignSave",
|
|
||||||
_( "\"%s\" is not a known file format" ), filename );
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( G_OBJECT_CLASS_NAME( save_class ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Can we write this buffer with this file type?
|
|
||||||
*/
|
|
||||||
static void *
|
|
||||||
vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class,
|
|
||||||
const char *suffix )
|
|
||||||
{
|
|
||||||
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class );
|
|
||||||
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
|
|
||||||
|
|
||||||
if( class->suffs &&
|
|
||||||
vips_ispostfix( object_class->nickname, "_buffer" ) &&
|
|
||||||
vips_filename_suffix_match( suffix, class->suffs ) )
|
|
||||||
return( save_class );
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_find_save_buffer:
|
|
||||||
* @suffix: name to find a saver for
|
|
||||||
*
|
|
||||||
* Searches for an operation you could use to write to a buffer in @suffix
|
|
||||||
* format.
|
|
||||||
*
|
|
||||||
* @filename may not contain embedded options. See
|
|
||||||
* vips_foreign_find_save_options() if your filename may have options in.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_save_buffer().
|
|
||||||
*
|
|
||||||
* Returns: the name of an operation on success, %NULL on error
|
|
||||||
*/
|
|
||||||
const char *
|
|
||||||
vips_foreign_find_save_buffer( const char *suffix )
|
|
||||||
{
|
|
||||||
VipsForeignSaveClass *save_class;
|
|
||||||
|
|
||||||
if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
|
|
||||||
"VipsForeignSave",
|
|
||||||
(VipsSListMap2Fn) vips_foreign_find_save_buffer_sub,
|
|
||||||
(void *) suffix, NULL )) ) {
|
|
||||||
vips_error( "VipsForeignSave",
|
|
||||||
_( "\"%s\" is not a known file format" ), suffix );
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( G_OBJECT_CLASS_NAME( save_class ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_find_save_options:
|
|
||||||
* @filename: name to find a saver for
|
|
||||||
*
|
|
||||||
* Searches for an operation you could use to write to @filename.
|
|
||||||
*
|
|
||||||
* @filename may contain embedded options. See
|
|
||||||
* vips_foreign_find_save() if your filename does not have options in.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_write().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
const char *
|
|
||||||
vips_foreign_find_save_options( const char *filename )
|
|
||||||
{
|
|
||||||
VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE );
|
|
||||||
VipsObject *object;
|
|
||||||
const char *type_name;
|
|
||||||
|
|
||||||
/* This will use vips_foreign_save_new_from_string() to pick a saver,
|
|
||||||
* then set options from the tail of the filename. This is rather slow
|
|
||||||
* :-(
|
|
||||||
*/
|
|
||||||
if( !(object = vips_object_new_from_string( oclass, filename )) )
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
type_name = G_OBJECT_TYPE_NAME( object );
|
|
||||||
|
|
||||||
g_object_unref( object );
|
|
||||||
|
|
||||||
return( type_name );
|
|
||||||
}
|
|
||||||
|
|
||||||
static VipsObject *
|
static VipsObject *
|
||||||
vips_foreign_save_new_from_string( const char *string )
|
vips_foreign_save_new_from_string( const char *string )
|
||||||
{
|
{
|
||||||
@ -1533,72 +1455,52 @@ vips_foreign_save_init( VipsForeignSave *object )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Can we write this filename with this file?
|
||||||
* vips_foreign_load:
|
|
||||||
* @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().
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_save(), vips_foreign_load_options().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
*/
|
||||||
int
|
static void *
|
||||||
vips_foreign_load( const char *filename, VipsImage **out, ... )
|
vips_foreign_find_save_sub( VipsForeignSaveClass *save_class,
|
||||||
|
const char *filename )
|
||||||
{
|
{
|
||||||
const char *operation;
|
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
|
||||||
va_list ap;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if( !(operation = vips_foreign_find_load( filename )) )
|
if( class->suffs &&
|
||||||
return( -1 );
|
vips_filename_suffix_match( filename, class->suffs ) )
|
||||||
|
return( save_class );
|
||||||
|
|
||||||
va_start( ap, out );
|
return( NULL );
|
||||||
result = vips_call_split( operation, ap, filename, out );
|
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
return( result );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_foreign_load_buffer:
|
* vips_foreign_find_save:
|
||||||
* @buf: start of memory buffer
|
* @filename: name to find a saver for
|
||||||
* @len: length of memory buffer
|
|
||||||
* @out: output image
|
|
||||||
* @...: %NULL-terminated list of optional named arguments
|
|
||||||
*
|
*
|
||||||
* Loads @buf, @len into @out using the loader recommended by
|
* Searches for an operation you could use to write to @filename.
|
||||||
* vips_foreign_find_load_buffer().
|
* Any trailing options on @filename are stripped and ignored.
|
||||||
*
|
*
|
||||||
* See also: vips_foreign_save(), vips_foreign_load_options().
|
* See also: vips_foreign_save().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: the name of an operation on success, %NULL on error
|
||||||
*/
|
*/
|
||||||
int
|
const char *
|
||||||
vips_foreign_load_buffer( void *buf, size_t len, VipsImage **out, ... )
|
vips_foreign_find_save( const char *name )
|
||||||
{
|
{
|
||||||
const char *operation;
|
char filename[VIPS_PATH_MAX];
|
||||||
VipsArea *area;
|
char option_string[VIPS_PATH_MAX];
|
||||||
va_list ap;
|
VipsForeignSaveClass *save_class;
|
||||||
int result;
|
|
||||||
|
|
||||||
if( !(operation = vips_foreign_find_load_buffer( buf, len )) )
|
vips__filename_split8( name, filename, option_string );
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* We don't take a copy of the data or free it.
|
if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
|
||||||
*/
|
"VipsForeignSave",
|
||||||
area = vips_area_new_blob( NULL, buf, len );
|
(VipsSListMap2Fn) vips_foreign_find_save_sub,
|
||||||
|
(void *) filename, NULL )) ) {
|
||||||
|
vips_error( "VipsForeignSave",
|
||||||
|
_( "\"%s\" is not a known file format" ), name );
|
||||||
|
|
||||||
va_start( ap, out );
|
return( NULL );
|
||||||
result = vips_call_split( operation, ap, area, out );
|
}
|
||||||
va_end( ap );
|
|
||||||
|
|
||||||
vips_area_unref( area );
|
return( G_OBJECT_CLASS_NAME( save_class ) );
|
||||||
|
|
||||||
return( result );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1616,22 +1518,77 @@ vips_foreign_load_buffer( void *buf, size_t len, VipsImage **out, ... )
|
|||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
vips_foreign_save( VipsImage *in, const char *filename, ... )
|
vips_foreign_save( VipsImage *in, const char *name, ... )
|
||||||
{
|
{
|
||||||
const char *operation;
|
char filename[VIPS_PATH_MAX];
|
||||||
|
char option_string[VIPS_PATH_MAX];
|
||||||
|
const char *operation_name;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if( !(operation = vips_foreign_find_save( filename )) )
|
vips__filename_split8( name, filename, option_string );
|
||||||
|
|
||||||
|
if( !(operation_name = vips_foreign_find_save( filename )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
va_start( ap, filename );
|
va_start( ap, name );
|
||||||
result = vips_call_split( operation, ap, in, filename );
|
result = vips_call_split_option_string( operation_name, option_string,
|
||||||
|
ap, in, filename );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Can we write this buffer with this file type?
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class,
|
||||||
|
const char *suffix )
|
||||||
|
{
|
||||||
|
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class );
|
||||||
|
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
|
||||||
|
|
||||||
|
if( class->suffs &&
|
||||||
|
vips_ispostfix( object_class->nickname, "_buffer" ) &&
|
||||||
|
vips_filename_suffix_match( suffix, class->suffs ) )
|
||||||
|
return( save_class );
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_foreign_find_save_buffer:
|
||||||
|
* @suffix: name to find a saver for
|
||||||
|
*
|
||||||
|
* Searches for an operation you could use to write to a buffer in @suffix
|
||||||
|
* format.
|
||||||
|
*
|
||||||
|
* See also: vips_foreign_save_buffer().
|
||||||
|
*
|
||||||
|
* Returns: the name of an operation on success, %NULL on error
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
vips_foreign_find_save_buffer( const char *name )
|
||||||
|
{
|
||||||
|
char suffix[VIPS_PATH_MAX];
|
||||||
|
char option_string[VIPS_PATH_MAX];
|
||||||
|
VipsForeignSaveClass *save_class;
|
||||||
|
|
||||||
|
vips__filename_split8( name, suffix, option_string );
|
||||||
|
|
||||||
|
if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
|
||||||
|
"VipsForeignSave",
|
||||||
|
(VipsSListMap2Fn) vips_foreign_find_save_buffer_sub,
|
||||||
|
(void *) suffix, NULL )) ) {
|
||||||
|
vips_error( "VipsForeignSave",
|
||||||
|
_( "\"%s\" is not a known file format" ), name );
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( G_OBJECT_CLASS_NAME( save_class ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_foreign_save_buffer:
|
* vips_foreign_save_buffer:
|
||||||
* @in: image to write
|
* @in: image to write
|
||||||
@ -1651,66 +1608,26 @@ vips_foreign_save( VipsImage *in, const char *filename, ... )
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
vips_foreign_save_buffer( VipsImage *in,
|
vips_foreign_save_buffer( VipsImage *in,
|
||||||
const char *suffix, void **buf, size_t *len,
|
const char *name, void **buf, size_t *len,
|
||||||
... )
|
... )
|
||||||
{
|
{
|
||||||
char str[VIPS_PATH_MAX];
|
char suffix[VIPS_PATH_MAX];
|
||||||
char *p;
|
char option_string[VIPS_PATH_MAX];
|
||||||
const char *operation_name;
|
const char *operation_name;
|
||||||
VipsOperation *operation;
|
|
||||||
VipsArea *area;
|
VipsArea *area;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* Take any [options] off the suffix.
|
vips__filename_split8( name, suffix, option_string );
|
||||||
*/
|
|
||||||
vips_strncpy( str, suffix, VIPS_PATH_MAX );
|
|
||||||
if( (p = (char *) vips__find_rightmost_brackets( str )) )
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
if( !(operation_name = vips_foreign_find_save_buffer( str )) )
|
if( !(operation_name = vips_foreign_find_save_buffer( suffix )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( !(operation = vips_operation_new( operation_name )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
g_object_set( operation, "in", in, NULL );
|
|
||||||
|
|
||||||
/* Now set any operation args from the options list.
|
|
||||||
*/
|
|
||||||
if( (p = (char *) vips__find_rightmost_brackets( suffix )) &&
|
|
||||||
vips_object_set_from_string( VIPS_OBJECT( operation ), p ) ) {
|
|
||||||
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
|
||||||
g_object_unref( operation );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set any from varargs.
|
|
||||||
*/
|
|
||||||
va_start( ap, len );
|
va_start( ap, len );
|
||||||
result = vips_object_set_valist( VIPS_OBJECT( operation ), ap );
|
result = vips_call_split_option_string( operation_name, option_string,
|
||||||
|
ap, in, &area );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
if( result ) {
|
|
||||||
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
|
||||||
g_object_unref( operation );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( vips_cache_operation_buildp( &operation ) ) {
|
|
||||||
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
|
||||||
g_object_unref( operation );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_get( operation, "buffer", &area, NULL );
|
|
||||||
|
|
||||||
/* Getting @buffer will have upped its count so it'll be safe.
|
|
||||||
* We can junk all other outputs,
|
|
||||||
*/
|
|
||||||
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
|
||||||
g_object_unref( operation );
|
|
||||||
|
|
||||||
if( area ) {
|
if( area ) {
|
||||||
if( buf ) {
|
if( buf ) {
|
||||||
*buf = area->data;
|
*buf = area->data;
|
||||||
@ -1722,124 +1639,7 @@ vips_foreign_save_buffer( VipsImage *in,
|
|||||||
vips_area_unref( area );
|
vips_area_unref( area );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( result );
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_load_options:
|
|
||||||
* @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().
|
|
||||||
*
|
|
||||||
* Arguments to the loader may be embedded in the filename using the usual
|
|
||||||
* syntax. They may also be given as a set of NULL-terminated optional
|
|
||||||
* arguments.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_load().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
vips_foreign_load_options( const char *filename, VipsImage **out, ... )
|
|
||||||
{
|
|
||||||
VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD );
|
|
||||||
|
|
||||||
VipsObject *object;
|
|
||||||
va_list ap;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
/* This will use vips_foreign_load_new_from_string() to pick a loader,
|
|
||||||
* then set options from the remains of the string.
|
|
||||||
*/
|
|
||||||
if( !(object = vips_object_new_from_string( oclass, filename )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* Also set options from args.
|
|
||||||
*/
|
|
||||||
va_start( ap, out );
|
|
||||||
result = vips_object_set_valist( object, ap );
|
|
||||||
va_end( ap );
|
|
||||||
if( result )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( vips_cache_operation_buildp( (VipsOperation **) &object ) ) {
|
|
||||||
/* The build may have made some output objects before
|
|
||||||
* failing.
|
|
||||||
*/
|
|
||||||
vips_object_unref_outputs( object );
|
|
||||||
g_object_unref( object );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_get( object, "out", out, NULL );
|
|
||||||
|
|
||||||
/* Getting @out will have upped its count so it'll be safe.
|
|
||||||
* We can junk all other outputs,
|
|
||||||
*/
|
|
||||||
vips_object_unref_outputs( object );
|
|
||||||
|
|
||||||
/* @out holds a ref to new_object, we can drop ours.
|
|
||||||
*/
|
|
||||||
g_object_unref( object );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vips_foreign_save_options:
|
|
||||||
* @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().
|
|
||||||
*
|
|
||||||
* Arguments to the saver may be embedded in the filename using the usual
|
|
||||||
* syntax. They may also be given as a set of NULL-terminated optional
|
|
||||||
* arguments.
|
|
||||||
*
|
|
||||||
* See also: vips_foreign_save().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
vips_foreign_save_options( VipsImage *in, const char *filename, ... )
|
|
||||||
{
|
|
||||||
VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE );
|
|
||||||
|
|
||||||
VipsObject *object;
|
|
||||||
va_list ap;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
/* This will use vips_foreign_save_new_from_string() to pick a saver,
|
|
||||||
* then set options from the tail of the filename.
|
|
||||||
*/
|
|
||||||
if( !(object = vips_object_new_from_string( oclass, filename )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
g_object_set( object, "in", in, NULL );
|
|
||||||
|
|
||||||
/* Also set options from args.
|
|
||||||
*/
|
|
||||||
va_start( ap, filename );
|
|
||||||
result = vips_object_set_valist( object, ap );
|
|
||||||
va_end( ap );
|
|
||||||
if( result )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* ... and running _build() should save it.
|
|
||||||
*/
|
|
||||||
if( vips_cache_operation_buildp( (VipsOperation **) &object ) ) {
|
|
||||||
g_object_unref( object );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref( object );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -215,7 +215,6 @@ GType vips_foreign_load_get_type( void );
|
|||||||
|
|
||||||
const char *vips_foreign_find_load( const char *filename );
|
const char *vips_foreign_find_load( const char *filename );
|
||||||
const char *vips_foreign_find_load_buffer( void *buf, size_t len );
|
const char *vips_foreign_find_load_buffer( void *buf, size_t len );
|
||||||
const char *vips_foreign_find_load_options( const char *filename );
|
|
||||||
|
|
||||||
VipsForeignFlags vips_foreign_flags( const char *loader, const char *filename );
|
VipsForeignFlags vips_foreign_flags( const char *loader, const char *filename );
|
||||||
gboolean vips_foreign_is_a( const char *loader, const char *filename );
|
gboolean vips_foreign_is_a( const char *loader, const char *filename );
|
||||||
@ -309,7 +308,6 @@ 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 );
|
||||||
const char *vips_foreign_find_save_options( const char *filename );
|
|
||||||
|
|
||||||
/* Read/write an image convenience functions.
|
/* Read/write an image convenience functions.
|
||||||
*/
|
*/
|
||||||
@ -318,12 +316,8 @@ int vips_foreign_load( const char *filename, VipsImage **out, ... )
|
|||||||
int vips_foreign_save( VipsImage *in, const char *filename, ... )
|
int vips_foreign_save( VipsImage *in, const char *filename, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
|
||||||
int vips_foreign_load_options( const char *filename, VipsImage **out, ... )
|
int vips_foreign_load_buffer( void *buf, size_t len, const char *option_string,
|
||||||
__attribute__((sentinel));
|
VipsImage **out, ... )
|
||||||
int vips_foreign_save_options( VipsImage *in, const char *filename, ... )
|
|
||||||
__attribute__((sentinel));
|
|
||||||
|
|
||||||
int vips_foreign_load_buffer( void *buf, size_t len, VipsImage **out, ... )
|
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_foreign_save_buffer( VipsImage *in,
|
int vips_foreign_save_buffer( VipsImage *in,
|
||||||
const char *suffix, void **buf, size_t *len, ... )
|
const char *suffix, void **buf, size_t *len, ... )
|
||||||
|
@ -104,6 +104,8 @@ VipsOperation *vips_operation_new( const char *name );
|
|||||||
int vips_call( const char *operation_name, ... )
|
int vips_call( const char *operation_name, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_call_split( const char *operation_name, va_list optional, ... );
|
int vips_call_split( const char *operation_name, va_list optional, ... );
|
||||||
|
int vips_call_split_option_string( const char *operation_name,
|
||||||
|
const char *option_string, va_list optional, ... );
|
||||||
|
|
||||||
void vips_call_options( GOptionGroup *group, VipsOperation *operation );
|
void vips_call_options( GOptionGroup *group, VipsOperation *operation );
|
||||||
int vips_call_argv( VipsOperation *operation, int argc, char **argv );
|
int vips_call_argv( VipsOperation *operation, int argc, char **argv );
|
||||||
|
@ -257,6 +257,8 @@ const char *vips__token_must( const char *buffer, VipsToken *token,
|
|||||||
const char *vips__token_need( const char *buffer, VipsToken need_token,
|
const char *vips__token_need( const char *buffer, VipsToken need_token,
|
||||||
char *string, int size );
|
char *string, int size );
|
||||||
const char *vips__find_rightmost_brackets( const char *p );
|
const char *vips__find_rightmost_brackets( const char *p );
|
||||||
|
void vips__filename_split8( const char *name,
|
||||||
|
char *filename, char *option_string );
|
||||||
|
|
||||||
int vips_ispoweroftwo( int p );
|
int vips_ispoweroftwo( int p );
|
||||||
int vips_amiMSBfirst( void );
|
int vips_amiMSBfirst( void );
|
||||||
|
@ -431,7 +431,7 @@ vips_info( const char *domain, const char *fmt, ... )
|
|||||||
* @ap: arguments to the format string
|
* @ap: arguments to the format string
|
||||||
*
|
*
|
||||||
* Sends a formatted warning message to stderr. If you define the
|
* Sends a formatted warning message to stderr. If you define the
|
||||||
* environment variable IM_WARNING, these message are surpressed.
|
* environment variable VIPS_WARNING, these message are surpressed.
|
||||||
*
|
*
|
||||||
* Warning messages are used to report things like overflow counts.
|
* Warning messages are used to report things like overflow counts.
|
||||||
*
|
*
|
||||||
@ -440,7 +440,8 @@ vips_info( const char *domain, const char *fmt, ... )
|
|||||||
void
|
void
|
||||||
vips_vwarn( const char *domain, const char *fmt, va_list ap )
|
vips_vwarn( const char *domain, const char *fmt, va_list ap )
|
||||||
{
|
{
|
||||||
if( !g_getenv( "IM_WARNING" ) ) {
|
if( !g_getenv( "IM_WARNING" ) &&
|
||||||
|
!g_getenv( "VIPS_WARNING" ) ) {
|
||||||
g_mutex_lock( vips__global_lock );
|
g_mutex_lock( vips__global_lock );
|
||||||
(void) fprintf( stderr, _( "%s: " ), _( "vips warning" ) );
|
(void) fprintf( stderr, _( "%s: " ), _( "vips warning" ) );
|
||||||
if( domain )
|
if( domain )
|
||||||
|
@ -670,7 +670,7 @@ vips_image_rewind( VipsObject *object )
|
|||||||
static void
|
static void
|
||||||
vips_image_save_cb( VipsImage *image, int *result )
|
vips_image_save_cb( VipsImage *image, int *result )
|
||||||
{
|
{
|
||||||
if( vips_foreign_save_options( image, image->filename, NULL ) )
|
if( vips_foreign_save( image, image->filename, NULL ) )
|
||||||
*result = -1;
|
*result = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,6 +737,7 @@ static void
|
|||||||
vips_image_add_progress( VipsImage *image )
|
vips_image_add_progress( VipsImage *image )
|
||||||
{
|
{
|
||||||
if( vips__progress ||
|
if( vips__progress ||
|
||||||
|
g_getenv( "VIPS_PROGRESS" ) ||
|
||||||
g_getenv( "IM_PROGRESS" ) ) {
|
g_getenv( "IM_PROGRESS" ) ) {
|
||||||
|
|
||||||
/* Keep the %complete we displayed last time here.
|
/* Keep the %complete we displayed last time here.
|
||||||
@ -825,14 +826,13 @@ vips_image_build( VipsObject *object )
|
|||||||
VipsImage *t;
|
VipsImage *t;
|
||||||
|
|
||||||
if( mode[1] == 's' ) {
|
if( mode[1] == 's' ) {
|
||||||
if( vips_foreign_load_options( filename, &t,
|
if( vips_foreign_load( filename, &t,
|
||||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||||
NULL ) )
|
NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( vips_foreign_load_options( filename, &t,
|
if( vips_foreign_load( filename, &t, NULL ) )
|
||||||
NULL ) )
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,7 +855,7 @@ vips_image_build( VipsObject *object )
|
|||||||
*/
|
*/
|
||||||
g_assert( g_type_from_name( "VipsForeignSaveVips" ) );
|
g_assert( g_type_from_name( "VipsForeignSaveVips" ) );
|
||||||
|
|
||||||
if( !(file_op = vips_foreign_find_save_options( filename )) )
|
if( !(file_op = vips_foreign_find_save( filename )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* If this is the vips saver, just save directly ourselves.
|
/* If this is the vips saver, just save directly ourselves.
|
||||||
@ -1579,7 +1579,7 @@ vips_image_new( void )
|
|||||||
* location for the temporary file.
|
* location for the temporary file.
|
||||||
*
|
*
|
||||||
* The disc threshold can be set with the "--vips-disc-threshold"
|
* The disc threshold can be set with the "--vips-disc-threshold"
|
||||||
* command-line argument, or the IM_DISC_THRESHOLD environment variable.
|
* command-line argument, or the VIPS_DISC_THRESHOLD environment variable.
|
||||||
* The value is a simple integer, but can take a unit postfix of "k",
|
* The value is a simple integer, but can take a unit postfix of "k",
|
||||||
* "m" or "g" to indicate kilobytes, megabytes or gigabytes.
|
* "m" or "g" to indicate kilobytes, megabytes or gigabytes.
|
||||||
*
|
*
|
||||||
|
@ -246,7 +246,8 @@ vips__init( const char *argv0 )
|
|||||||
|
|
||||||
/* Default info setting from env.
|
/* Default info setting from env.
|
||||||
*/
|
*/
|
||||||
if( g_getenv( "IM_INFO" ) )
|
if( g_getenv( "VIPS_INFO" ) ||
|
||||||
|
g_getenv( "IM_INFO" ) )
|
||||||
vips__info = 1;
|
vips__info = 1;
|
||||||
|
|
||||||
/* Register base vips types.
|
/* Register base vips types.
|
||||||
|
@ -1672,8 +1672,7 @@ vips_object_set_argument_from_string( VipsObject *object,
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the filename. vips_foreign_load_options()
|
/* Read the filename.
|
||||||
* handles embedded options.
|
|
||||||
*/
|
*/
|
||||||
if( flags & VIPS_OPERATION_SEQUENTIAL_UNBUFFERED )
|
if( flags & VIPS_OPERATION_SEQUENTIAL_UNBUFFERED )
|
||||||
access = VIPS_ACCESS_SEQUENTIAL_UNBUFFERED;
|
access = VIPS_ACCESS_SEQUENTIAL_UNBUFFERED;
|
||||||
@ -1682,7 +1681,7 @@ vips_object_set_argument_from_string( VipsObject *object,
|
|||||||
else
|
else
|
||||||
access = VIPS_ACCESS_RANDOM;
|
access = VIPS_ACCESS_RANDOM;
|
||||||
|
|
||||||
if( vips_foreign_load_options( value, &out,
|
if( vips_foreign_load( value, &out,
|
||||||
"access", access,
|
"access", access,
|
||||||
NULL ) )
|
NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -1906,10 +1905,9 @@ vips_object_get_argument_to_string( VipsObject *object,
|
|||||||
VipsImage *in;
|
VipsImage *in;
|
||||||
|
|
||||||
/* Pull out the image and write it.
|
/* Pull out the image and write it.
|
||||||
* vips_foreign_save_options() handles embedded options.
|
|
||||||
*/
|
*/
|
||||||
g_object_get( object, name, &in, NULL );
|
g_object_get( object, name, &in, NULL );
|
||||||
if( vips_foreign_save_options( in, arg, NULL ) ) {
|
if( vips_foreign_save( in, arg, NULL ) ) {
|
||||||
g_object_unref( in );
|
g_object_unref( in );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@ -2090,10 +2088,18 @@ vips_object_set_args( VipsObject *object, const char *p )
|
|||||||
string, VIPS_PATH_MAX )) )
|
string, VIPS_PATH_MAX )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
do {
|
if( !(p = vips__token_must( p, &token, string, VIPS_PATH_MAX )) )
|
||||||
if( !(p = vips__token_need( p, VIPS_TOKEN_STRING,
|
return( -1 );
|
||||||
string, VIPS_PATH_MAX )) )
|
|
||||||
|
for(;;) {
|
||||||
|
if( token == VIPS_TOKEN_RIGHT )
|
||||||
|
break;
|
||||||
|
if( token != VIPS_TOKEN_STRING ) {
|
||||||
|
vips_error( class->nickname,
|
||||||
|
_( "expected string or ), saw %s" ),
|
||||||
|
vips_enum_nick( VIPS_TYPE_TOKEN, token ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
/* We have to look for a '=', ')' or a ',' to see if string is
|
/* We have to look for a '=', ')' or a ',' to see if string is
|
||||||
* a param name or a value.
|
* a param name or a value.
|
||||||
@ -2136,14 +2142,19 @@ vips_object_set_args( VipsObject *object, const char *p )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now must be a , or a ).
|
/* Now must be a , or a ).
|
||||||
*/
|
*/
|
||||||
if( token != VIPS_TOKEN_RIGHT && token != VIPS_TOKEN_COMMA ) {
|
if( token == VIPS_TOKEN_COMMA ) {
|
||||||
|
if( !(p = vips__token_must( p, &token,
|
||||||
|
string, VIPS_PATH_MAX )) )
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
else if( token != VIPS_TOKEN_RIGHT ) {
|
||||||
vips_error( class->nickname,
|
vips_error( class->nickname,
|
||||||
"%s", _( "not , or ) after parameter" ) );
|
"%s", _( "not , or ) after parameter" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
} while( token != VIPS_TOKEN_RIGHT );
|
}
|
||||||
|
|
||||||
if( (p = vips__token_get( p, &token, string, VIPS_PATH_MAX )) ) {
|
if( (p = vips__token_get( p, &token, string, VIPS_PATH_MAX )) ) {
|
||||||
vips_error( class->nickname,
|
vips_error( class->nickname,
|
||||||
|
@ -647,6 +647,50 @@ vips_call_required_optional( VipsOperation **operation,
|
|||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_call_by_name( const char *operation_name,
|
||||||
|
const char *option_string, va_list required, va_list optional )
|
||||||
|
{
|
||||||
|
VipsOperation *operation;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
VIPS_DEBUG_MSG( "vips_call_by_name: starting for %s ...\n",
|
||||||
|
operation_name );
|
||||||
|
|
||||||
|
if( !(operation = vips_operation_new( operation_name )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
/* Set str options before vargs options, so the user can't override
|
||||||
|
* thnigs we set deliberately.
|
||||||
|
*/
|
||||||
|
if( option_string &&
|
||||||
|
vips_object_set_from_string( VIPS_OBJECT( operation ),
|
||||||
|
option_string ) ) {
|
||||||
|
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
||||||
|
g_object_unref( operation );
|
||||||
|
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
result = vips_call_required_optional( &operation, required, optional );
|
||||||
|
|
||||||
|
/* Build failed: junk args and back out.
|
||||||
|
*/
|
||||||
|
if( result ) {
|
||||||
|
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
||||||
|
g_object_unref( operation );
|
||||||
|
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The operation we have built should now have been reffed by one of
|
||||||
|
* its arguments or have finished its work. Either way, we can unref.
|
||||||
|
*/
|
||||||
|
g_object_unref( operation );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_call( const char *operation_name, ... )
|
vips_call( const char *operation_name, ... )
|
||||||
{
|
{
|
||||||
@ -655,16 +699,9 @@ vips_call( const char *operation_name, ... )
|
|||||||
va_list required;
|
va_list required;
|
||||||
va_list optional;
|
va_list optional;
|
||||||
|
|
||||||
VIPS_DEBUG_MSG( "vips_call: starting for %s ...\n", operation_name );
|
|
||||||
|
|
||||||
if( !(operation = vips_operation_new( operation_name ) ) )
|
if( !(operation = vips_operation_new( operation_name ) ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
#ifdef VIPS_DEBUG
|
|
||||||
VIPS_DEBUG_MSG( "where:\n" );
|
|
||||||
vips_object_print_dump( VIPS_OBJECT( operation ) );
|
|
||||||
#endif /*VIPS_DEBUG*/
|
|
||||||
|
|
||||||
/* We have to break the va_list into separate required and optional
|
/* We have to break the va_list into separate required and optional
|
||||||
* components.
|
* components.
|
||||||
*
|
*
|
||||||
@ -690,58 +727,43 @@ vips_call( const char *operation_name, ... )
|
|||||||
}
|
}
|
||||||
} VIPS_ARGUMENT_FOR_ALL_END
|
} VIPS_ARGUMENT_FOR_ALL_END
|
||||||
|
|
||||||
result = vips_call_required_optional( &operation, required, optional );
|
/* We just needed this operation for the arg loop.
|
||||||
|
*/
|
||||||
|
g_object_unref( operation );
|
||||||
|
|
||||||
|
result = vips_call_by_name( operation_name, NULL, required, optional );
|
||||||
|
|
||||||
va_end( required );
|
va_end( required );
|
||||||
va_end( optional );
|
va_end( optional );
|
||||||
|
|
||||||
/* Failed: junk args and back out.
|
|
||||||
*/
|
|
||||||
if( result ) {
|
|
||||||
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
|
||||||
g_object_unref( operation );
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The operation we have built should now have been reffed by one of
|
|
||||||
* its arguments or have finished its work. Either way, we can unref.
|
|
||||||
*/
|
|
||||||
g_object_unref( operation );
|
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_call_split( const char *operation_name, va_list optional, ... )
|
vips_call_split( const char *operation_name, va_list optional, ... )
|
||||||
{
|
{
|
||||||
VipsOperation *operation;
|
|
||||||
int result;
|
int result;
|
||||||
va_list required;
|
va_list required;
|
||||||
|
|
||||||
VIPS_DEBUG_MSG( "vips_call_split: starting for %s ...\n",
|
|
||||||
operation_name );
|
|
||||||
|
|
||||||
if( !(operation = vips_operation_new( operation_name )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
va_start( required, optional );
|
va_start( required, optional );
|
||||||
result = vips_call_required_optional( &operation, required, optional );
|
result = vips_call_by_name( operation_name, NULL,
|
||||||
|
required, optional );
|
||||||
va_end( required );
|
va_end( required );
|
||||||
|
|
||||||
/* Build failed: junk args and back out.
|
return( result );
|
||||||
*/
|
}
|
||||||
if( result ) {
|
|
||||||
vips_object_unref_outputs( VIPS_OBJECT( operation ) );
|
|
||||||
g_object_unref( operation );
|
|
||||||
|
|
||||||
return( -1 );
|
int
|
||||||
}
|
vips_call_split_option_string( const char *operation_name,
|
||||||
|
const char *option_string, va_list optional, ... )
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
va_list required;
|
||||||
|
|
||||||
/* The operation we have built should now have been reffed by one of
|
va_start( required, optional );
|
||||||
* its arguments or have finished its work. Either way, we can unref.
|
result = vips_call_by_name( operation_name, option_string,
|
||||||
*/
|
required, optional );
|
||||||
g_object_unref( operation );
|
va_end( required );
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
@ -82,14 +82,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Maximum number of concurrent threads we allow. No reason for the limit,
|
/* Maximum number of concurrent threads we allow. No reason for the limit,
|
||||||
* it's just there to stop mad values for IM_CONCURRENCY killing the system.
|
* it's just there to stop mad values for VIPS_CONCURRENCY killing the system.
|
||||||
*/
|
*/
|
||||||
#define MAX_THREADS (1024)
|
#define MAX_THREADS (1024)
|
||||||
|
|
||||||
/* Name of environment variable we get concurrency level from.
|
|
||||||
*/
|
|
||||||
#define IM_CONCURRENCY "IM_CONCURRENCY"
|
|
||||||
|
|
||||||
/* Default tile geometry ... can be set by init_world.
|
/* Default tile geometry ... can be set by init_world.
|
||||||
*/
|
*/
|
||||||
int vips__tile_width = VIPS__TILE_WIDTH;
|
int vips__tile_width = VIPS__TILE_WIDTH;
|
||||||
@ -218,7 +214,7 @@ vips_g_thread_new( const char *domain, GThreadFunc func, gpointer data )
|
|||||||
* #VipsThreadPool.
|
* #VipsThreadPool.
|
||||||
*
|
*
|
||||||
* The special value 0 means "default". In this case, the number of threads is
|
* The special value 0 means "default". In this case, the number of threads is
|
||||||
* set by the environmnt variable IM_CONCURRENCY, or if that is not set, the
|
* set by the environmnt variable VIPS_CONCURRENCY, or if that is not set, the
|
||||||
* number of threads availble on the hist machine.
|
* number of threads availble on the hist machine.
|
||||||
*
|
*
|
||||||
* See also: vips_concurrency_get().
|
* See also: vips_concurrency_get().
|
||||||
@ -305,9 +301,9 @@ get_num_processors( void )
|
|||||||
* "--vips-concurrency" to set this value.
|
* "--vips-concurrency" to set this value.
|
||||||
*
|
*
|
||||||
* If vips_concurrency_set() has not been called and no command-line argument
|
* If vips_concurrency_set() has not been called and no command-line argument
|
||||||
* was used, vips uses the value of the environment variable IM_CONCURRENCY,
|
* was used, vips uses the value of the environment variable VIPS_CONCURRENCY,
|
||||||
*
|
*
|
||||||
* If IM_CONCURRENCY has not been set, vips find the number of hardware
|
* If VIPS_CONCURRENCY has not been set, vips find the number of hardware
|
||||||
* threads that the host machine can run in parallel and uses that value.
|
* threads that the host machine can run in parallel and uses that value.
|
||||||
*
|
*
|
||||||
* The final value is clipped to the range 1 - 1024.
|
* The final value is clipped to the range 1 - 1024.
|
||||||
@ -327,7 +323,8 @@ vips_concurrency_get( void )
|
|||||||
*/
|
*/
|
||||||
if( vips__concurrency > 0 )
|
if( vips__concurrency > 0 )
|
||||||
nthr = vips__concurrency;
|
nthr = vips__concurrency;
|
||||||
else if( (str = g_getenv( IM_CONCURRENCY )) &&
|
else if( ((str = g_getenv( "VIPS_CONCURRENCY" )) ||
|
||||||
|
(str = g_getenv( "IM_CONCURRENCY" ))) &&
|
||||||
(x = atoi( str )) > 0 )
|
(x = atoi( str )) > 0 )
|
||||||
nthr = x;
|
nthr = x;
|
||||||
else
|
else
|
||||||
|
@ -1428,6 +1428,24 @@ vips__find_rightmost_brackets( const char *p )
|
|||||||
return( start[i] );
|
return( start[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Split a vips8-style filename + options.
|
||||||
|
*
|
||||||
|
* filename and options must be VIPS_PATH_MAX in length.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vips__filename_split8( const char *name, char *filename, char *option_string )
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
vips_strncpy( filename, name, VIPS_PATH_MAX );
|
||||||
|
if( (p = (char *) vips__find_rightmost_brackets( filename )) ) {
|
||||||
|
vips_strncpy( option_string, p, VIPS_PATH_MAX );
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vips_strncpy( option_string, "", VIPS_PATH_MAX );
|
||||||
|
}
|
||||||
|
|
||||||
/* True if an int is a power of two ... 1, 2, 4, 8, 16, 32, etc. Do with just
|
/* True if an int is a power of two ... 1, 2, 4, 8, 16, 32, etc. Do with just
|
||||||
* integer arithmetic for portability. A previous Nicos version using doubles
|
* integer arithmetic for portability. A previous Nicos version using doubles
|
||||||
* and log/log failed on x86 with rounding problems. Return 0 for not
|
* and log/log failed on x86 with rounding problems. Return 0 for not
|
||||||
|
@ -77,7 +77,8 @@ vips_vector_init( void )
|
|||||||
/* Look for the environment variable IM_NOVECTOR and use that to turn
|
/* Look for the environment variable IM_NOVECTOR and use that to turn
|
||||||
* off as well.
|
* off as well.
|
||||||
*/
|
*/
|
||||||
if( g_getenv( "IM_NOVECTOR" ) )
|
if( g_getenv( "VIPS_NOVECTOR" ) ||
|
||||||
|
g_getenv( "IM_NOVECTOR" ) )
|
||||||
vips__vector_enabled = FALSE;
|
vips__vector_enabled = FALSE;
|
||||||
#endif /*HAVE_ORC*/
|
#endif /*HAVE_ORC*/
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
#define DEBUG_VERBOSE
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -208,8 +209,14 @@ pass_compile_section( Pass *pass, Morph *morph, gboolean first_pass )
|
|||||||
ASM3( "orb", "sum", "sum", "value" );
|
ASM3( "orb", "sum", "sum", "value" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( !mask->coeff[i] )
|
if( !mask->coeff[i] ) {
|
||||||
ASM3( "andnb", "sum", "sum", "value" );
|
/* You'd think we could use andnb, but it
|
||||||
|
* fails on some machines with some orc
|
||||||
|
* versions :(
|
||||||
|
*/
|
||||||
|
ASM3( "xorb", "value", "value", one );
|
||||||
|
ASM3( "andb", "sum", "sum", "value" );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ASM3( "andb", "sum", "sum", "value" );
|
ASM3( "andb", "sum", "sum", "value" );
|
||||||
}
|
}
|
||||||
@ -454,10 +461,10 @@ dilate_gen( REGION *or, void *vseq, void *a, void *b )
|
|||||||
if( im_prepare( ir, &s ) )
|
if( im_prepare( ir, &s ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "dilate_gen: preparing %dx%d@%dx%d pixels\n",
|
printf( "dilate_gen: preparing %dx%d@%dx%d pixels\n",
|
||||||
s.width, s.height, s.left, s.top );
|
s.width, s.height, s.left, s.top );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
/* Scan mask, building offsets we check when processing. Only do this
|
/* Scan mask, building offsets we check when processing. Only do this
|
||||||
* if the bpl has changed since the previous im_prepare().
|
* if the bpl has changed since the previous im_prepare().
|
||||||
@ -566,10 +573,10 @@ erode_gen( REGION *or, void *vseq, void *a, void *b )
|
|||||||
if( im_prepare( ir, &s ) )
|
if( im_prepare( ir, &s ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "erode_gen: preparing %dx%d@%dx%d pixels\n",
|
printf( "erode_gen: preparing %dx%d@%dx%d pixels\n",
|
||||||
s.width, s.height, s.left, s.top );
|
s.width, s.height, s.left, s.top );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
/* Scan mask, building offsets we check when processing. Only do this
|
/* Scan mask, building offsets we check when processing. Only do this
|
||||||
* if the bpl has changed since the previous im_prepare().
|
* if the bpl has changed since the previous im_prepare().
|
||||||
@ -665,10 +672,10 @@ morph_vector_gen( REGION *or, void *vseq, void *a, void *b )
|
|||||||
if( im_prepare( ir, &s ) )
|
if( im_prepare( ir, &s ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "morph_vector_gen: preparing %dx%d@%dx%d pixels\n",
|
printf( "morph_vector_gen: preparing %dx%d@%dx%d pixels\n",
|
||||||
s.width, s.height, s.left, s.top );
|
s.width, s.height, s.left, s.top );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
for( j = 0; j < morph->n_pass; j++ )
|
for( j = 0; j < morph->n_pass; j++ )
|
||||||
vips_executor_set_program( &executor[j],
|
vips_executor_set_program( &executor[j],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user