def signal_connect(self, name, callback): """Connect to a signal on this object. The callback will be triggered every time this signal is issued on this instance. It will be passed the image ('self' here), and a single `void *` pointer from libvips. The value of the pointer, if any, depends on the signal -- for example, ::eval passes a pointer to a `VipsProgress` struct. """ if name not in _marshalers: raise Error('unsupported signal "{0}"'.format(name)) go = ffi.cast('GObject *', self.pointer) handle = ffi.new_handle(callback) # we need to keep refs to the ffi handle and the callback to prevent # them being GCed # the callback might be a bound method (a closure) rather than a simple # function, so it can vanish self._handles.append(handle) self._handles.append(callback) gobject_lib.g_signal_connect_data(go, _to_bytes(name), _marshalers[name], handle, ffi.NULL, 0)
def __init__(self): """Make a new custom source. You can pass this source to (for example) :meth:`new_from_source`. """ source = ffi.cast('VipsSource*', vips_lib.vips_source_custom_new()) super(SourceCustom, self).__init__(source)
def __init__(self): """Make a new target you can customise. You can pass this target to (for example) :meth:`write_to_target`. """ target = ffi.cast('VipsTarget*', vips_lib.vips_target_custom_new()) super(TargetCustom, self).__init__(target)
def nick(self): """Make a human-readable name for a connection suitable for error messages. """ so = ffi.cast('VipsConnection *', self.pointer) pointer = vips_lib.vips_connection_nick(so) if pointer == ffi.NULL: return None else: return _to_string(pointer)
def filename(self): """Get the filename associated with a connection. Return None if there is no associated file. """ so = ffi.cast('VipsConnection *', self.pointer) pointer = vips_lib.vips_connection_filename(so) if pointer == ffi.NULL: return None else: return _to_string(pointer)
def values_for_enum(gtype): """Get all values for a enum (gtype).""" g_type_class = gobject_lib.g_type_class_ref(gtype) g_enum_class = ffi.cast('GEnumClass *', g_type_class) values = [] # -1 since we always have a "last" member. for i in range(0, g_enum_class.n_values - 1): value = _to_string(g_enum_class.values[i].value_nick) values.append(value) return values
def set_string(self, string_options): """Set a series of properties using a string. For example:: 'fred=12, tile' '[fred=12]' """ vo = ffi.cast('VipsObject *', self.pointer) cstr = _to_bytes(string_options) result = vips_lib.vips_object_set_from_string(vo, cstr) return result == 0
def set(self, name, value): """Set a GObject property. The value is converted to the property type, if possible. """ logger.debug('VipsObject.set: name = %s, value = %s', name, value) gtype = self.get_typeof(name) gv = pyvips.GValue() gv.set_type(gtype) gv.set(value) go = ffi.cast('GObject *', self.pointer) gobject_lib.g_object_set_property(go, _to_bytes(name), gv.pointer)
def _get_pspec(self, name): # logger.debug('VipsObject.get_typeof: self = %s, name = %s', # str(self), name) pspec = ffi.new('GParamSpec **') argument_class = ffi.new('VipsArgumentClass **') argument_instance = ffi.new('VipsArgumentInstance **') vo = ffi.cast('VipsObject *', self.pointer) result = vips_lib.vips_object_get_argument(vo, _to_bytes(name), pspec, argument_class, argument_instance) if result != 0: return None return pspec[0]
def get(self, name): """Get a GObject property. The value of the property is converted to a Python value. """ logger.debug('VipsObject.get: name = %s', name) pspec = self._get_pspec(name) if pspec is None: raise Error('Property not found.') gtype = pspec.value_type gv = pyvips.GValue() gv.set_type(gtype) go = ffi.cast('GObject *', self.pointer) gobject_lib.g_object_get_property(go, _to_bytes(name), gv.pointer) return gv.get()
def __init__(self, pointer): # logger.debug('Operation.__init__: pointer = %s', pointer) super(Operation, self).__init__(pointer) self.object = ffi.cast('VipsObject*', pointer)
def get(self): """Get the contents of a GValue. The contents of the GValue are read out as a Python type. """ # logger.debug('GValue.get: self = %s', self) gtype = self.gvalue.g_type fundamental = gobject_lib.g_type_fundamental(gtype) result = None if gtype == GValue.gbool_type: result = bool(gobject_lib.g_value_get_boolean(self.gvalue)) elif gtype == GValue.gint_type: result = gobject_lib.g_value_get_int(self.gvalue) elif gtype == GValue.gdouble_type: result = gobject_lib.g_value_get_double(self.gvalue) elif fundamental == GValue.genum_type: return GValue.from_enum(gtype, gobject_lib.g_value_get_enum(self.gvalue)) elif fundamental == GValue.gflags_type: result = gobject_lib.g_value_get_flags(self.gvalue) elif gtype == GValue.gstr_type: pointer = gobject_lib.g_value_get_string(self.gvalue) if pointer != ffi.NULL: result = _to_string(pointer) elif gtype == GValue.refstr_type: psize = ffi.new('size_t *') pointer = vips_lib.vips_value_get_ref_string(self.gvalue, psize) # psize[0] will be number of bytes in string, but just assume it's # NULL-terminated result = _to_string(pointer) elif gtype == GValue.image_type: # g_value_get_object() will not add a ref ... that is # held by the gvalue go = gobject_lib.g_value_get_object(self.gvalue) vi = ffi.cast('VipsImage *', go) # we want a ref that will last with the life of the vimage: # this ref is matched by the unref that's attached to finalize # by Image() gobject_lib.g_object_ref(go) result = pyvips.Image(vi) elif gtype == GValue.array_int_type: pint = ffi.new('int *') array = vips_lib.vips_value_get_array_int(self.gvalue, pint) result = [] for i in range(0, pint[0]): result.append(array[i]) elif gtype == GValue.array_double_type: pint = ffi.new('int *') array = vips_lib.vips_value_get_array_double(self.gvalue, pint) result = [] for i in range(0, pint[0]): result.append(array[i]) elif gtype == GValue.array_image_type: pint = ffi.new('int *') array = vips_lib.vips_value_get_array_image(self.gvalue, pint) result = [] for i in range(0, pint[0]): vi = array[i] gobject_lib.g_object_ref(vi) image = pyvips.Image(vi) result.append(image) elif gtype == GValue.blob_type: psize = ffi.new('size_t *') array = vips_lib.vips_value_get_blob(self.gvalue, psize) buf = ffi.cast('char*', array) result = ffi.unpack(buf, psize[0]) else: raise Error('unsupported gtype for get {0}'.format( type_name(gtype))) return result
def __init__(self, pointer): # logger.debug('VipsObject.__init__: pointer = %s', pointer) super(VipsObject, self).__init__(pointer) self.vobject = ffi.cast('VipsObject*', pointer)
def _marshal_image_progress(vi, pointer, handle): gobject_lib.g_object_ref(vi) image = pyvips.Image(vi) callback = ffi.from_handle(handle) progress = ffi.cast('VipsProgress*', pointer) callback(image, progress)
# the python marshalers for gobject signal handling # - we keep a ref to each callback to stop them being GCd # - I tried to make this less copy-paste, but failed -- check again if pyvips.API_mode: @ffi.def_extern() def _marshal_image_progress(vi, pointer, handle): gobject_lib.g_object_ref(vi) image = pyvips.Image(vi) callback = ffi.from_handle(handle) progress = ffi.cast('VipsProgress*', pointer) callback(image, progress) _marshal_image_progress_cb = \ ffi.cast('GCallback', gobject_lib._marshal_image_progress) else: @ffi.callback('void(VipsImage*, void*, void*)') def _marshal_image_progress(vi, pointer, handle): gobject_lib.g_object_ref(vi) image = pyvips.Image(vi) callback = ffi.from_handle(handle) progress = ffi.cast('VipsProgress*', pointer) callback(image, progress) _marshal_image_progress_cb = \ ffi.cast('GCallback', _marshal_image_progress) _marshalers = { 'preeval': _marshal_image_progress_cb, 'eval': _marshal_image_progress_cb,
def get_description(self): """Get the description of a GObject.""" vo = ffi.cast('VipsObject *', self.pointer) return _to_string(ffi.string(vips_lib.vips_object_get_description(vo)))