Exemplo n.º 1
0
def type_find(basename, nickname):
    """Get the GType for a name.

    Looks up the GType for a nickname. Types below basename in the type
    hierarchy are searched.
    """
    return vips_lib.vips_type_find(_to_bytes(basename), _to_bytes(nickname))
Exemplo n.º 2
0
    def get_typeof(self, name):
        """Get the GType of an item of metadata.

        Fetch the GType of a piece of metadata, or 0 if the named item does not
        exist. See :class:`GValue`.

        Args:
            name (str): The name of the piece of metadata to get the type of.

        Returns:
            The ``GType``, or 0.

        Raises:
            None

        """

        # on libvips before 8.5, property types must be fetched separately,
        # since built-in enums were reported as ints
        if not at_least_libvips(8, 5):
            gtype = super(Image, self).get_typeof(name)
            if gtype != 0:
                return gtype

        return vips_lib.vips_image_get_typeof(self.pointer, _to_bytes(name))
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    def new_temp_file(format):
        """Make a new temporary image.

        Returns an image backed by a temporary file. When written to with
        :func:`Image.write`, a temporary file will be created on disc in the
        specified format. When the image is closed, the file will be deleted
        automatically.

        The file is created in the temporary directory. This is set with
        the environment variable ``TMPDIR``. If this is not set, then on
        Unix systems, vips will default to ``/tmp``. On Windows, vips uses
        ``GetTempPath()`` to find the temporary directory.

        vips uses ``g_mkstemp()`` to make the temporary filename. They
        generally look something like ``"vips-12-EJKJFGH.v"``.

        Args:
            format (str): The format for the temp file, for example
                ``"%s.v"`` for a vips format file. The ``%s`` is
                substituted by the file path.

        Returns:
            A new :class:`Image`.

        Raises:
            :class:`.Error`

        """

        vi = vips_lib.vips_image_new_temp_file(_to_bytes(format))
        if vi == ffi.NULL:
            raise Error('unable to make temp file')

        return pyvips.Image(vi)
Exemplo n.º 5
0
    def get(self, name):
        """Get an item of metadata.

        Fetches an item of metadata as a Python value. For example::

            orientation = image.get('orientation')

        would fetch the image orientation.

        Args:
            name (str): The name of the piece of metadata to get.

        Returns:
            The metadata item as a Python value.

        Raises:
            :class:`.Error`

        """

        # with old libvips, we must fetch properties (as opposed to
        # metadata) via VipsObject
        if not at_least_libvips(8, 5):
            gtype = super(Image, self).get_typeof(name)
            if gtype != 0:
                return super(Image, self).get(name)

        gv = GValue()
        result = vips_lib.vips_image_get(self.pointer, _to_bytes(name),
                                         gv.pointer)
        if result != 0:
            raise Error('unable to get {0}'.format(name))

        return gv.get()
Exemplo n.º 6
0
    def new_from_file(vips_filename, **kwargs):
        """Load an image from a file.

        This method can load images in any format supported by vips. The
        filename can include load options, for example::

            image = pyvips.Image.new_from_file('fred.jpg[shrink=2]')

        You can also supply options as keyword arguments, for example::

            image = pyvips.Image.new_from_file('fred.jpg', shrink=2)

        The full set of options available depend upon the load operation that
        will be executed. Try something like::

            $ vips jpegload

        at the command-line to see a summary of the available options for the
        JPEG loader.

        Loading is fast: only enough of the image is loaded to be able to fill
        out the header. Pixels will only be decompressed when they are needed.

        Args:
            vips_filename (str): The disc file to load the image from, with
                optional appended arguments.

        All loaders support at least the following options:

        Keyword args:
            memory (bool): If set True, load the image via memory rather than
                via a temporary disc file. See :meth:`.new_temp_file` for
                notes on where temporary files are created. Small images are
                loaded via memory by default, use ``VIPS_DISC_THRESHOLD`` to
                set the definition of small.
            access (Access): Hint the expected access pattern for the image.
            fail (bool): If set True, the loader will fail with an error on
                the first serious error in the file. By default, libvips
                will attempt to read everything it can from a damanged image.

        Returns:
            A new :class:`.Image`.

        Raises:
            :class:`.Error`

        """
        vips_filename = _to_bytes(vips_filename)
        filename = vips_lib.vips_filename_get_filename(vips_filename)
        options = vips_lib.vips_filename_get_options(vips_filename)
        name = vips_lib.vips_foreign_find_load(filename)
        if name == ffi.NULL:
            raise Error('unable to load from file {0}'.format(vips_filename))

        return pyvips.Operation.call(_to_string(ffi.string(name)),
                                     _to_string(ffi.string(filename)),
                                     string_options=_to_string(
                                         ffi.string(options)
                                     ), **kwargs)
Exemplo n.º 7
0
    def write_to_file(self, vips_filename, **kwargs):
        """Write an image to a file on disc.

        This method can save images in any format supported by vips. The format
        is selected from the filename suffix. The filename can include embedded
        save options, see :func:`Image.new_from_file`.

        For example::

            image.write_to_file('fred.jpg[Q=95]')

        You can also supply options as keyword arguments, for example::

            image.write_to_file('fred.jpg', Q=95)

        The full set of options available depend upon the load operation that
        will be executed. Try something like::

            $ vips jpegsave

        at the command-line to see a summary of the available options for the
        JPEG saver.

        Args:
            vips_filename (str): The disc file to save the image to, with
                optional appended arguments.

        Other arguments depend upon the save operation.

        Returns:
            None

        Raises:
            :class:`.Error`

        """
        vips_filename = _to_bytes(vips_filename)
        pointer = vips_lib.vips_filename_get_filename(vips_filename)
        filename = _to_string_copy(pointer)

        pointer = vips_lib.vips_filename_get_options(vips_filename)
        options = _to_string_copy(pointer)

        pointer = vips_lib.vips_foreign_find_save(vips_filename)
        if pointer == ffi.NULL:
            raise Error('unable to write to file {0}'.format(vips_filename))
        name = _to_string(pointer)

        return pyvips.Operation.call(name,
                                     self,
                                     filename,
                                     string_options=options,
                                     **kwargs)
Exemplo n.º 8
0
    def write_to_target(self, target, format_string, **kwargs):
        """Write an image to a target.

        This method will write the image to the target in the format
        specified in the suffix in the format string. This can include
        embedded save options, see :func:`Image.write_to_file`.

        For example::

            image.write_to_target(target, '.jpg[Q=95]')

        You can also supply options as keyword arguments, for example::

            image.write_to_target(target, '.jpg', Q=95)

        The full set of options available depend upon the save operation that
        will be executed. Try something like::

            $ vips jpegsave_target

        at the command-line to see a summary of the available options for the
        JPEG saver.

        Args:
            target (Target): The target to write the image to
            format_string (str): The suffix, plus any string-form arguments.

        Other arguments depend upon the save operation.

        Returns:
            None

        Raises:
            :class:`.Error`

        """
        format_string = _to_bytes(format_string)

        pointer = vips_lib.vips_filename_get_options(format_string)
        options = _to_string_copy(pointer)

        pointer = vips_lib.vips_foreign_find_save_target(format_string)
        if pointer == ffi.NULL:
            raise Error('unable to write to target')
        name = _to_string(pointer)

        return pyvips.Operation.call(name,
                                     self,
                                     target,
                                     string_options=options,
                                     **kwargs)
Exemplo n.º 9
0
    def set_string(self, string_options):
        """Set a series of properties using a string.

        For example::

            'fred=12, tile'
            '[fred=12]'

        """

        cstr = _to_bytes(string_options)
        result = vips_lib.vips_object_set_from_string(self.vobject, cstr)

        return result == 0
Exemplo n.º 10
0
    def write_to_buffer(self, format_string, **kwargs):
        """Write an image to memory.

        This method can save images in any format supported by vips. The format
        is selected from the suffix in the format string. This can include
        embedded save options, see :func:`Image.write_to_file`.

        For example::

            data = image.write_to_buffer('.jpg[Q=95]')

        You can also supply options as keyword arguments, for example::

            data = image.write_to_buffer('.jpg', Q=95)

        The full set of options available depend upon the load operation that
        will be executed. Try something like::

            $ vips jpegsave_buffer

        at the command-line to see a summary of the available options for the
        JPEG saver.

        Args:
            format_string (str): The suffix, plus any string-form arguments.

        Other arguments depend upon the save operation.

        Returns:
            A byte string.

        Raises:
            :class:`.Error`

        """
        format_string = _to_bytes(format_string)

        pointer = vips_lib.vips_filename_get_options(format_string)
        options = _to_string_copy(pointer)

        pointer = vips_lib.vips_foreign_find_save_buffer(format_string)
        if pointer == ffi.NULL:
            raise Error('unable to write to buffer')
        name = _to_string(pointer)

        return pyvips.Operation.call(name,
                                     self,
                                     string_options=options,
                                     **kwargs)
Exemplo n.º 11
0
    def to_enum(gtype, value):
        """Turn a string into an enum value ready to be passed into libvips.

        """

        if isinstance(value, basestring if _is_PY2 else str):
            enum_value = vips_lib.vips_enum_from_nick(b'pyvips', gtype,
                                                      _to_bytes(value))
            if enum_value < 0:
                raise Error('no value {0} in gtype {1} ({2})'.format(
                    value, type_name(gtype), gtype))
        else:
            enum_value = value

        return enum_value
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
    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 **')
        result = vips_lib.vips_object_get_argument(self.vobject,
                                                   _to_bytes(name), pspec,
                                                   argument_class,
                                                   argument_instance)

        if result != 0:
            return None

        return pspec[0]
Exemplo n.º 14
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)
Exemplo n.º 15
0
    def remove(self, name):
        """Remove an item of metadata.

        The named metadata item is removed.

        Args:
            name (str): The name of the piece of metadata to remove.

        Returns:
            None

        Raises:
            None

        """

        return vips_lib.vips_image_remove(self.pointer, _to_bytes(name)) != 0
Exemplo n.º 16
0
    def new_to_file(filename):
        """Make a new target to write to a file.

        Make a new target that will write to the named file. For example::

            target = pyvips.Target.new_to_file("myfile.jpg")

        You can pass this target to (for example) :meth:`write_to_target`.

        """

        # logger.debug('VipsTarget.new_to_file: filename = %s', filename)

        pointer = vips_lib.vips_target_new_to_file(_to_bytes(filename))
        if pointer == ffi.NULL:
            raise Error("can't create output target from filename {0}".format(
                filename))

        return Target(pointer)
Exemplo n.º 17
0
    def new_from_file(filename):
        """Make a new source from a filename.

        Make a new source that is attached to the named file. For example::

            source = pyvips.Source.new_from_file("myfile.jpg")

        You can pass this source to (for example) :meth:`new_from_source`.

        """

        # logger.debug('VipsSource.new_from_file: filename = %s',
        #              filename)

        pointer = vips_lib.vips_source_new_from_file(_to_bytes(filename))
        if pointer == ffi.NULL:
            raise Error("can't create source from filename {0}"
                        .format(filename))

        return Source(pointer)
Exemplo n.º 18
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()
Exemplo n.º 19
0
    def new(name):
        """Make a new interpolator by name.

        Make a new interpolator from the libvips class nickname. For example::

            inter = pyvips.Interpolator.new('bicubic')

        You can get a list of all supported interpolators from the command-line
        with::

            $ vips -l interpolate

        See for example :meth:`.affine`.

        """

        # logger.debug('VipsInterpolate.new: name = %s', name)

        vi = vips_lib.vips_interpolate_new(_to_bytes(name))
        if vi == ffi.NULL:
            raise Error('no such interpolator {0}'.format(name))

        return Interpolate(vi)
Exemplo n.º 20
0
    def set_type(self, gtype, name, value):
        """Set the type and value of an item of metadata.

        Sets the type and value of an item of metadata. Any old item of the
        same name is removed. See :class:`GValue` for types.

        Args:
            gtype (int): The GType of the metadata item to create.
            name (str): The name of the piece of metadata to create.
            value (mixed): The value to set as a Python value. It is
                converted to the ``gtype``, if possible.

        Returns:
            None

        Raises:
            None

        """

        gv = GValue()
        gv.set_type(gtype)
        gv.set(value)
        vips_lib.vips_image_set(self.pointer, _to_bytes(name), gv.pointer)
Exemplo n.º 21
0
    def set(self, value):
        """Set a GValue.

        The value is converted to the type of the GValue, if possible, and
        assigned.

        """

        # logger.debug('GValue.set: value = %s', value)

        gtype = self.gvalue.gtype
        fundamental = gobject_lib.g_type_fundamental(gtype)

        if gtype == GValue.gbool_type:
            gobject_lib.g_value_set_boolean(self.gvalue, value)
        elif gtype == GValue.gint_type:
            gobject_lib.g_value_set_int(self.gvalue, int(value))
        elif gtype == GValue.gdouble_type:
            gobject_lib.g_value_set_double(self.gvalue, value)
        elif fundamental == GValue.genum_type:
            gobject_lib.g_value_set_enum(self.gvalue,
                                         GValue.to_enum(gtype, value))
        elif fundamental == GValue.gflags_type:
            gobject_lib.g_value_set_flags(self.gvalue, value)
        elif gtype == GValue.gstr_type or gtype == GValue.refstr_type:
            gobject_lib.g_value_set_string(self.gvalue, _to_bytes(value))
        elif fundamental == GValue.gobject_type:
            gobject_lib.g_value_set_object(self.gvalue, value.pointer)
        elif gtype == GValue.array_int_type:
            if isinstance(value, numbers.Number):
                value = [value]

            array = ffi.new('int[]', value)
            vips_lib.vips_value_set_array_int(self.gvalue, array, len(value))
        elif gtype == GValue.array_double_type:
            if isinstance(value, numbers.Number):
                value = [value]

            array = ffi.new('double[]', value)
            vips_lib.vips_value_set_array_double(self.gvalue, array,
                                                 len(value))
        elif gtype == GValue.array_image_type:
            if isinstance(value, pyvips.Image):
                value = [value]

            vips_lib.vips_value_set_array_image(self.gvalue, len(value))
            array = vips_lib.vips_value_get_array_image(self.gvalue, ffi.NULL)
            for i, image in enumerate(value):
                gobject_lib.g_object_ref(image.pointer)
                array[i] = image.pointer
        elif gtype == GValue.blob_type:
            # we need to set the blob to a copy of the string that vips_lib
            # can own
            memory = glib_lib.g_malloc(len(value))
            ffi.memmove(memory, value, len(value))

            vips_lib.vips_value_set_blob(self.gvalue, glib_lib.g_free, memory,
                                         len(value))
        else:
            raise Error(
                'unsupported gtype for set {0}, fundamental {1}'.format(
                    type_name(gtype), type_name(fundamental)))
Exemplo n.º 22
0
def path_mode7(filename):
    return _to_string(ffi.string(vips_lib.vips_path_mode7(
        _to_bytes(filename))))
Exemplo n.º 23
0
def type_from_name(name):
    """Return the GType for a name."""

    return gobject_lib.g_type_from_name(_to_bytes(name))
Exemplo n.º 24
0
    def set(self, value):
        """Set a GValue.

        The value is converted to the type of the GValue, if possible, and
        assigned.

        """

        # logger.debug('GValue.set: value = %s', value)

        gtype = self.gvalue.g_type
        fundamental = gobject_lib.g_type_fundamental(gtype)

        if gtype == GValue.gbool_type:
            gobject_lib.g_value_set_boolean(self.gvalue, value)
        elif gtype == GValue.gint_type:
            gobject_lib.g_value_set_int(self.gvalue, int(value))
        elif gtype == GValue.gdouble_type:
            gobject_lib.g_value_set_double(self.gvalue, value)
        elif fundamental == GValue.genum_type:
            gobject_lib.g_value_set_enum(self.gvalue,
                                         GValue.to_enum(gtype, value))
        elif fundamental == GValue.gflags_type:
            gobject_lib.g_value_set_flags(self.gvalue, value)
        elif gtype == GValue.gstr_type:
            gobject_lib.g_value_set_string(self.gvalue, _to_bytes(value))
        elif gtype == GValue.refstr_type:
            vips_lib.vips_value_set_ref_string(self.gvalue, _to_bytes(value))
        elif fundamental == GValue.gobject_type:
            gobject_lib.g_value_set_object(self.gvalue, value.pointer)
        elif gtype == GValue.array_int_type:
            if isinstance(value, numbers.Number):
                value = [value]

            array = ffi.new('int[]', value)
            vips_lib.vips_value_set_array_int(self.gvalue, array, len(value))
        elif gtype == GValue.array_double_type:
            if isinstance(value, numbers.Number):
                value = [value]

            array = ffi.new('double[]', value)
            vips_lib.vips_value_set_array_double(self.gvalue, array,
                                                 len(value))
        elif gtype == GValue.array_image_type:
            if isinstance(value, pyvips.Image):
                value = [value]

            vips_lib.vips_value_set_array_image(self.gvalue, len(value))
            array = vips_lib.vips_value_get_array_image(self.gvalue, ffi.NULL)
            for i, image in enumerate(value):
                gobject_lib.g_object_ref(image.pointer)
                array[i] = image.pointer
        elif gtype == GValue.blob_type:
            # we need to set the blob to a copy of the string that vips_lib
            # can own
            memory = glib_lib.g_malloc(len(value))
            ffi.memmove(memory, value, len(value))

            # this is horrible!
            #
            # * in API mode, we must have 8.6+ and use set_blob_free to
            #   attach the metadata to avoid leaks
            # * pre-8.6, we just pass a NULL free pointer and live with the
            #   leak
            #
            # this is because in API mode you can't pass a builtin (what
            # vips_lib.g_free() becomes) as a parameter to ffi.callback(), and
            # vips_value_set_blob() needs a callback for arg 2
            #
            # additionally, you can't make a py def which calls g_free() and
            # then use the py def in the callback, since libvips will trigger
            # these functions during cleanup, and py will have shut down by
            # then and you'll get a segv

            if at_least_libvips(8, 6):
                vips_lib.vips_value_set_blob_free(self.gvalue, memory,
                                                  len(value))
            else:
                if pyvips.API_mode:
                    vips_lib.vips_value_set_blob(self.gvalue, ffi.NULL, memory,
                                                 len(value))
                else:
                    vips_lib.vips_value_set_blob(self.gvalue, glib_lib.g_free,
                                                 memory, len(value))
        else:
            raise Error(
                'unsupported gtype for set {0}, fundamental {1}'.format(
                    type_name(gtype), type_name(fundamental)))
Exemplo n.º 25
0
 def new_from_name(operation_name):
     vop = vips_lib.vips_operation_new(_to_bytes(operation_name))
     if vop == ffi.NULL:
         raise Error('no such operation {0}'.format(operation_name))
     return Operation(vop)