Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
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)))
Ejemplo n.º 4
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)))