set options in filenames in vips8 Python

now supports "fred.jpg[Q=90]" in Vips.Image.new_from_file() etc.
This commit is contained in:
John Cupitt 2014-08-31 21:16:39 +01:00
parent a370e5003e
commit 3b43bd76f3
4 changed files with 81 additions and 35 deletions

33
TODO
View File

@ -16,35 +16,16 @@
- GBoxed
can we write generic array index?
from gi.repository import Vips
vips_area_index_array( VipsArea *area, int i, GValue *value )
a = Vips.ArrayDouble.new([1,2,3])
a.get()
ie. get element i from array out as a GValue? do we need a
switch for all possible types?
a = Vips.ArrayInt.new([1,2,3])
a.get()
from gi.repository import GLib
from gi.repository import GObject
gint_type = GObject.GType.from_name('gint')
a = GObject.Value(gint_type)
a.set_value(12)
a.get_value()
12
a.unset()
>>> a
<Value (invalid) None>
a.init(gint_type)
a = GObject.Value(None)
>>> a
<Value (invalid) None>
b = Vips.ArrayDouble.new([1,2,3])
b.area.index_array(1)
segv
a = Vips.ArrayImage.new([c, d, e])
a.get()

View File

@ -406,6 +406,9 @@ void vips_image_minimise_all( VipsImage *image );
void vips_image_set_progress( VipsImage *image, gboolean progress );
char *vips_filename_get_filename( const char *vips_filename );
char *vips_filename_get_options( const char *vips_filename );
VipsImage *vips_image_new( void );
VipsImage *vips_image_new_memory( void );
VipsImage *vips_image_new_from_file( const char *name, ... )

View File

@ -1736,6 +1736,54 @@ vips_image_new_memory( void )
return( vips_image_new_mode( vips_image_temp_name(), "t" ) );
}
/**
* vips_filename_get_filename:
* @vips_filename: a filename including a set of options
*
* Given a vips filename like "fred.jpg[Q=90]", return a new string of
* just the filename part, "fred.jpg" in this case.
*
* Useful for language bindings.
*
* See also: vips_filename_get_options().
*
* Returns: transfer full: just the filename component.
*/
char *
vips_filename_get_filename( const char *vips_filename )
{
char filename[VIPS_PATH_MAX];
char options[VIPS_PATH_MAX];
vips__filename_split8( vips_filename, filename, options );
return( g_strdup( filename ) );
}
/**
* vips_filename_get_options:
* @vips_filename: a filename including a set of options
*
* Given a vips filename like "fred.jpg[Q=90]", return a new string of
* just the options part, "[Q=90]" in this case.
*
* Useful for language bindings.
*
* See also: vips_filename_get_filename().
*
* Returns: transfer full: just the options component.
*/
char *
vips_filename_get_options( const char *vips_filename )
{
char filename[VIPS_PATH_MAX];
char options[VIPS_PATH_MAX];
vips__filename_split8( vips_filename, filename, options );
return( g_strdup( options ) );
}
/**
* vips_image_new_from_file:
* @name: file to open

View File

@ -40,15 +40,25 @@ class Argument:
self.priority = op.get_argument_priority(self.name)
self.isset = op.argument_isset(self.name)
def _call_base(name, self, required, optional):
logging.debug('_call_base name=%s, self=%s, required=%s optional=%s' %
(name, self, required, optional))
def _call_base(name, required, optional, self = None, option_string = None):
logging.debug('_call_base name=%s, required=%s optional=%s' %
(name, required, optional))
if self:
logging.debug('_call_base self=%s' % self)
if option_string:
logging.debug('_call_base option_string = %s' % option_string)
try:
op = Vips.Operation.new(name)
except TypeError, e:
raise Error('No such operator.')
# set str options first so the user can't override things we set
# deliberately and beak stuff
if option_string:
if op.set_from_string(option_string) != 0:
raise Error('Bad arguments.')
# find all the args for this op, sort into priority order
args = [Argument(op, x) for x in op.props]
args.sort(lambda a, b: a.priority - b.priority)
@ -137,20 +147,22 @@ def _call_base(name, self, required, optional):
# general user entrypoint
def call(name, *args, **kwargs):
return _call_base(name, None, args, kwargs)
return _call_base(name, args, kwargs)
# here from getattr ... try to run the attr as a method
def _call_instance(self, name, args, kwargs):
return _call_base(name, self, args, kwargs)
return _call_base(name, args, kwargs, self)
# this is a class method
def vips_image_new_from_file(cls, filename, **kwargs):
def vips_image_new_from_file(cls, vips_filename, **kwargs):
filename = Vips.filename_get_filename(vips_filename)
option_string = Vips.filename_get_options(vips_filename)
loader = Vips.Foreign.find_load(filename)
if loader == None:
raise Error('No known loader for "%s".' % filename)
logging.debug('Image.new_from_file: loader = %s' % loader)
return _call_base(loader, None, [filename], kwargs)
return _call_base(loader, [filename], kwargs, None, option_string)
def vips_image_getattr(self, name):
logging.debug('Image.__getattr__ %s' % name)
@ -161,13 +173,15 @@ def vips_image_getattr(self, name):
return lambda *args, **kwargs: _call_instance(self, name, args, kwargs)
def vips_image_write_to_file(self, filename, **kwargs):
def vips_image_write_to_file(self, vips_filename, **kwargs):
filename = Vips.filename_get_filename(vips_filename)
option_string = Vips.filename_get_options(vips_filename)
saver = Vips.Foreign.find_save(filename)
if saver == None:
raise Error('No known saver for "%s".' % filename)
logging.debug('Image.write_to_file: saver = %s' % saver)
_call_base(saver, self, [filename], kwargs)
_call_base(saver, [filename], kwargs, self, option_string)
# paste our methods into Vips.Image