ruby-vips 2.0.14 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
- data/.github/workflows/test.yml +80 -0
- data/.standard.yml +17 -0
- data/.yardopts +0 -1
- data/CHANGELOG.md +41 -0
- data/Gemfile +3 -1
- data/README.md +42 -41
- data/Rakefile +13 -21
- data/TODO +18 -10
- data/VERSION +1 -1
- data/example/annotate.rb +6 -6
- data/example/connection.rb +26 -0
- data/example/daltonize8.rb +16 -18
- data/example/draw_lines.rb +30 -0
- data/example/example1.rb +5 -6
- data/example/example2.rb +6 -6
- data/example/example3.rb +5 -5
- data/example/example4.rb +4 -4
- data/example/example5.rb +6 -7
- data/example/inheritance_with_refcount.rb +36 -54
- data/example/progress.rb +30 -0
- data/example/thumb.rb +8 -10
- data/example/trim8.rb +5 -5
- data/example/watermark.rb +2 -2
- data/example/wobble.rb +1 -1
- data/lib/ruby-vips.rb +1 -1
- data/lib/vips.rb +199 -93
- data/lib/vips/align.rb +0 -1
- data/lib/vips/angle.rb +0 -1
- data/lib/vips/angle45.rb +0 -1
- data/lib/vips/bandformat.rb +0 -2
- data/lib/vips/blend_mode.rb +29 -27
- data/lib/vips/coding.rb +0 -1
- data/lib/vips/compass_direction.rb +0 -1
- data/lib/vips/connection.rb +46 -0
- data/lib/vips/direction.rb +0 -1
- data/lib/vips/extend.rb +0 -1
- data/lib/vips/gobject.rb +26 -15
- data/lib/vips/gvalue.rb +61 -55
- data/lib/vips/image.rb +455 -282
- data/lib/vips/interesting.rb +0 -1
- data/lib/vips/interpolate.rb +3 -7
- data/lib/vips/interpretation.rb +0 -1
- data/lib/vips/kernel.rb +0 -1
- data/lib/vips/methods.rb +791 -124
- data/lib/vips/mutableimage.rb +173 -0
- data/lib/vips/object.rb +178 -68
- data/lib/vips/operation.rb +277 -130
- data/lib/vips/operationboolean.rb +0 -1
- data/lib/vips/operationcomplex.rb +0 -1
- data/lib/vips/operationcomplex2.rb +0 -1
- data/lib/vips/operationcomplexget.rb +0 -1
- data/lib/vips/operationmath.rb +0 -1
- data/lib/vips/operationmath2.rb +0 -1
- data/lib/vips/operationrelational.rb +0 -1
- data/lib/vips/operationround.rb +0 -1
- data/lib/vips/region.rb +73 -0
- data/lib/vips/size.rb +0 -1
- data/lib/vips/source.rb +88 -0
- data/lib/vips/sourcecustom.rb +89 -0
- data/lib/vips/target.rb +86 -0
- data/lib/vips/targetcustom.rb +77 -0
- data/lib/vips/version.rb +1 -2
- data/ruby-vips.gemspec +26 -21
- metadata +39 -51
- data/.rubocop.yml +0 -10
- data/.rubocop_todo.yml +0 -730
- data/.travis.yml +0 -62
- data/install-vips.sh +0 -26
@@ -0,0 +1,173 @@
|
|
1
|
+
# This module provides an interface to the vips image processing library
|
2
|
+
# via ruby-ffi.
|
3
|
+
#
|
4
|
+
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
|
5
|
+
# License:: MIT
|
6
|
+
|
7
|
+
require "ffi"
|
8
|
+
require "forwardable"
|
9
|
+
|
10
|
+
module Vips
|
11
|
+
# This class represents a libvips image which can be modified. See
|
12
|
+
# {Vips::Image#mutate}.
|
13
|
+
class MutableImage < Vips::Object
|
14
|
+
extend Forwardable
|
15
|
+
alias_method :parent_get_typeof, :get_typeof
|
16
|
+
def_instance_delegators :@image, :width, :height, :bands, :format,
|
17
|
+
:interpretation, :filename, :xoffset, :yoffset, :xres, :yres, :size,
|
18
|
+
:get, :get_typeof, :get_fields
|
19
|
+
|
20
|
+
# layout is exactly as {Image} (since we are also wrapping a VipsImage
|
21
|
+
# object)
|
22
|
+
module MutableImageLayout
|
23
|
+
def self.included base
|
24
|
+
base.class_eval do
|
25
|
+
layout :parent, Vips::Object::Struct
|
26
|
+
# rest opaque
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Struct < Vips::Object::Struct
|
32
|
+
include MutableImageLayout
|
33
|
+
end
|
34
|
+
|
35
|
+
class ManagedStruct < Vips::Object::ManagedStruct
|
36
|
+
include MutableImageLayout
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get the {Image} this {MutableImage} is modifying. Only use this once you
|
40
|
+
# have finished all modifications.
|
41
|
+
#
|
42
|
+
# This is for internal use only. See {Vips::Image#mutate} for the
|
43
|
+
# user-facing interface.
|
44
|
+
attr_reader :image
|
45
|
+
|
46
|
+
# Make a {MutableImage} from a regular {Image}.
|
47
|
+
#
|
48
|
+
# This is for internal use only. See {Vips::Image#mutate} for the
|
49
|
+
# user-facing interface.
|
50
|
+
def initialize(image)
|
51
|
+
# We take a copy of the regular Image to ensure we have an unshared
|
52
|
+
# (unique) object. We forward things like #width and #height to this, and
|
53
|
+
# it's the thing we return at the end of the mutate block.
|
54
|
+
copy_image = image.copy
|
55
|
+
|
56
|
+
# Use ptr since we need the raw unwrapped pointer inside the image ...
|
57
|
+
# and make the ref that gobject will unref when it finishes.
|
58
|
+
# See also the comment on set_type! before changing this.
|
59
|
+
pointer = copy_image.ptr
|
60
|
+
::GObject.g_object_ref pointer
|
61
|
+
super pointer
|
62
|
+
|
63
|
+
# and save the copy ready for when we finish mutating
|
64
|
+
@image = copy_image
|
65
|
+
end
|
66
|
+
|
67
|
+
def inspect
|
68
|
+
"#<MutableImage #{width}x#{height} #{format}, #{bands} bands, #{interpretation}>"
|
69
|
+
end
|
70
|
+
|
71
|
+
def respond_to? name, include_all = false
|
72
|
+
# To support keyword args, we need to tell Ruby that final image
|
73
|
+
# arguments cannot be hashes of keywords.
|
74
|
+
#
|
75
|
+
# https://makandracards.com/makandra/
|
76
|
+
# 36013-heads-up-ruby-implicitly-converts-a-hash-to-keyword-arguments
|
77
|
+
return false if name == :to_hash
|
78
|
+
|
79
|
+
super
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to_missing? name, include_all = false
|
83
|
+
# Respond to all vips operations by nickname.
|
84
|
+
return true if Vips.type_find("VipsOperation", name.to_s) != 0
|
85
|
+
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
89
|
+
# Invoke a vips operation with {Vips::Operation#call}, using self as
|
90
|
+
# the first input argument. {Vips::Operation#call} will only allow
|
91
|
+
# operations that modify self when passed a {MutableImage}.
|
92
|
+
#
|
93
|
+
# @param name [String] vips operation to call
|
94
|
+
# @return result of vips operation
|
95
|
+
def method_missing name, *args, **options
|
96
|
+
Vips::Operation.call name.to_s, [self, *args], options
|
97
|
+
end
|
98
|
+
|
99
|
+
# Create a metadata item on an image of the specifed type. Ruby types
|
100
|
+
# are automatically transformed into the matching glib type (eg.
|
101
|
+
# {GObject::GINT_TYPE}), if possible.
|
102
|
+
#
|
103
|
+
# For example, you can use this to set an image's ICC profile:
|
104
|
+
#
|
105
|
+
# ```ruby
|
106
|
+
# x.set_type! Vips::BLOB_TYPE, "icc-profile-data", profile
|
107
|
+
# ```
|
108
|
+
#
|
109
|
+
# where `profile` is an ICC profile held as a binary string object.
|
110
|
+
#
|
111
|
+
# @see set!
|
112
|
+
# @param gtype [Integer] GType of item
|
113
|
+
# @param name [String] Metadata field to set
|
114
|
+
# @param value [Object] Value to set
|
115
|
+
def set_type! gtype, name, value
|
116
|
+
gvalue = GObject::GValue.alloc
|
117
|
+
gvalue.init gtype
|
118
|
+
gvalue.set value
|
119
|
+
|
120
|
+
# libvips 8.9.1 had a terrible misfeature which would block metadata
|
121
|
+
# modification unless the object had a ref_count of 1. MutableImage
|
122
|
+
# will always have a ref_count of at least 2 (the parent gobject keeps a
|
123
|
+
# ref, and we keep a ref to the copy ready to return to our caller),
|
124
|
+
# so we must temporarily drop the refs to 1 around metadata changes.
|
125
|
+
#
|
126
|
+
# See https://github.com/libvips/ruby-vips/issues/291
|
127
|
+
begin
|
128
|
+
::GObject.g_object_unref ptr
|
129
|
+
Vips.vips_image_set self, name, gvalue
|
130
|
+
ensure
|
131
|
+
::GObject.g_object_ref ptr
|
132
|
+
end
|
133
|
+
|
134
|
+
gvalue.unset
|
135
|
+
end
|
136
|
+
|
137
|
+
# Set the value of a metadata item on an image. The metadata item must
|
138
|
+
# already exist. Ruby types are automatically transformed into the
|
139
|
+
# matching {GObject::GValue}, if possible.
|
140
|
+
#
|
141
|
+
# For example, you can use this to set an image's ICC profile:
|
142
|
+
#
|
143
|
+
# ```
|
144
|
+
# x.set! "icc-profile-data", profile
|
145
|
+
# ```
|
146
|
+
#
|
147
|
+
# where `profile` is an ICC profile held as a binary string object.
|
148
|
+
#
|
149
|
+
# @see set_type!
|
150
|
+
# @param name [String] Metadata field to set
|
151
|
+
# @param value [Object] Value to set
|
152
|
+
def set! name, value
|
153
|
+
set_type! get_typeof(name), name, value
|
154
|
+
end
|
155
|
+
|
156
|
+
# Remove a metadata item from an image.
|
157
|
+
#
|
158
|
+
# For example:
|
159
|
+
#
|
160
|
+
# ```
|
161
|
+
# x.remove! "icc-profile-data"
|
162
|
+
# ```
|
163
|
+
#
|
164
|
+
# @param name [String] Metadata field to remove
|
165
|
+
def remove! name
|
166
|
+
# See set_type! for an explanation. Image#remove can't throw an
|
167
|
+
# exception, so there's no need to ensure we unref.
|
168
|
+
::GObject.g_object_unref ptr
|
169
|
+
Vips.vips_image_remove self, name
|
170
|
+
::GObject.g_object_ref ptr
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
data/lib/vips/object.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
|
5
5
|
# License:: MIT
|
6
6
|
|
7
|
-
require
|
7
|
+
require "ffi"
|
8
8
|
|
9
9
|
module Vips
|
10
10
|
private
|
@@ -21,40 +21,131 @@ module Vips
|
|
21
21
|
public
|
22
22
|
|
23
23
|
# some handy gtypes
|
24
|
-
IMAGE_TYPE = GObject
|
25
|
-
ARRAY_INT_TYPE = GObject
|
26
|
-
ARRAY_DOUBLE_TYPE = GObject
|
27
|
-
ARRAY_IMAGE_TYPE = GObject
|
28
|
-
REFSTR_TYPE = GObject
|
29
|
-
BLOB_TYPE = GObject
|
30
|
-
|
31
|
-
BAND_FORMAT_TYPE = Vips
|
32
|
-
INTERPRETATION_TYPE = Vips
|
33
|
-
CODING_TYPE = Vips
|
34
|
-
|
35
|
-
if Vips
|
24
|
+
IMAGE_TYPE = GObject.g_type_from_name "VipsImage"
|
25
|
+
ARRAY_INT_TYPE = GObject.g_type_from_name "VipsArrayInt"
|
26
|
+
ARRAY_DOUBLE_TYPE = GObject.g_type_from_name "VipsArrayDouble"
|
27
|
+
ARRAY_IMAGE_TYPE = GObject.g_type_from_name "VipsArrayImage"
|
28
|
+
REFSTR_TYPE = GObject.g_type_from_name "VipsRefString"
|
29
|
+
BLOB_TYPE = GObject.g_type_from_name "VipsBlob"
|
30
|
+
|
31
|
+
BAND_FORMAT_TYPE = Vips.vips_band_format_get_type
|
32
|
+
INTERPRETATION_TYPE = Vips.vips_interpretation_get_type
|
33
|
+
CODING_TYPE = Vips.vips_coding_get_type
|
34
|
+
|
35
|
+
if Vips.at_least_libvips?(8, 6)
|
36
36
|
attach_function :vips_blend_mode_get_type, [], :GType
|
37
|
-
BLEND_MODE_TYPE = Vips
|
37
|
+
BLEND_MODE_TYPE = Vips.vips_blend_mode_get_type
|
38
38
|
else
|
39
39
|
BLEND_MODE_TYPE = nil
|
40
40
|
end
|
41
41
|
|
42
42
|
private
|
43
43
|
|
44
|
+
class Progress < FFI::Struct
|
45
|
+
layout :im, :pointer,
|
46
|
+
:run, :int,
|
47
|
+
:eta, :int,
|
48
|
+
:tpels, :int64_t,
|
49
|
+
:npels, :int64_t,
|
50
|
+
:percent, :int,
|
51
|
+
:start, :pointer
|
52
|
+
end
|
53
|
+
|
54
|
+
# Our signal marshalers.
|
55
|
+
#
|
56
|
+
# These are functions which take the handler as a param and return a
|
57
|
+
# closure with the right FFI signature for g_signal_connect for this
|
58
|
+
# specific signal.
|
59
|
+
#
|
60
|
+
# ruby-ffi makes it hard to use the g_signal_connect user data param
|
61
|
+
# to pass the function pointer through, unfortunately.
|
62
|
+
#
|
63
|
+
# We can't throw exceptions across C, so we must catch everything.
|
64
|
+
|
65
|
+
MARSHAL_PROGRESS = proc do |handler|
|
66
|
+
FFI::Function.new(:void, [:pointer, :pointer, :pointer]) do |vi, prog, cb|
|
67
|
+
begin
|
68
|
+
handler.call(Progress.new(prog))
|
69
|
+
rescue Exception => e
|
70
|
+
puts "progress: #{e}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
MARSHAL_READ = proc do |handler|
|
76
|
+
FFI::Function.new(:int64_t, [:pointer, :pointer, :int64_t]) do |i, p, len|
|
77
|
+
begin
|
78
|
+
result = handler.call(p, len)
|
79
|
+
rescue Exception => e
|
80
|
+
puts "read: #{e}"
|
81
|
+
result = 0
|
82
|
+
end
|
83
|
+
|
84
|
+
result
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
MARSHAL_SEEK = proc do |handler|
|
89
|
+
FFI::Function.new(:int64_t, [:pointer, :int64_t, :int]) do |i, off, whence|
|
90
|
+
begin
|
91
|
+
result = handler.call(off, whence)
|
92
|
+
rescue Exception => e
|
93
|
+
puts "seek: #{e}"
|
94
|
+
result = -1
|
95
|
+
end
|
96
|
+
|
97
|
+
result
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
MARSHAL_WRITE = proc do |handler|
|
102
|
+
FFI::Function.new(:int64_t, [:pointer, :pointer, :int64_t]) do |i, p, len|
|
103
|
+
begin
|
104
|
+
result = handler.call(p, len)
|
105
|
+
rescue Exception => e
|
106
|
+
puts "write: #{e}"
|
107
|
+
result = 0
|
108
|
+
end
|
109
|
+
|
110
|
+
result
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
MARSHAL_FINISH = proc do |handler|
|
115
|
+
FFI::Function.new(:void, [:pointer, :pointer]) do |i, cb|
|
116
|
+
begin
|
117
|
+
handler.call
|
118
|
+
rescue Exception => e
|
119
|
+
puts "finish: #{e}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# map signal name to marshal proc
|
125
|
+
MARSHAL_ALL = {
|
126
|
+
preeval: MARSHAL_PROGRESS,
|
127
|
+
eval: MARSHAL_PROGRESS,
|
128
|
+
posteval: MARSHAL_PROGRESS,
|
129
|
+
read: MARSHAL_READ,
|
130
|
+
seek: MARSHAL_SEEK,
|
131
|
+
write: MARSHAL_WRITE,
|
132
|
+
finish: MARSHAL_FINISH
|
133
|
+
}
|
134
|
+
|
44
135
|
attach_function :vips_enum_from_nick, [:string, :GType, :string], :int
|
45
136
|
attach_function :vips_enum_nick, [:GType, :int], :string
|
46
137
|
|
47
138
|
attach_function :vips_value_set_ref_string,
|
48
|
-
|
139
|
+
[GObject::GValue.ptr, :string], :void
|
49
140
|
attach_function :vips_value_set_array_double,
|
50
|
-
|
141
|
+
[GObject::GValue.ptr, :pointer, :int], :void
|
51
142
|
attach_function :vips_value_set_array_int,
|
52
|
-
|
143
|
+
[GObject::GValue.ptr, :pointer, :int], :void
|
53
144
|
attach_function :vips_value_set_array_image,
|
54
|
-
|
145
|
+
[GObject::GValue.ptr, :int], :void
|
55
146
|
callback :free_fn, [:pointer], :void
|
56
147
|
attach_function :vips_value_set_blob,
|
57
|
-
|
148
|
+
[GObject::GValue.ptr, :free_fn, :pointer, :size_t], :void
|
58
149
|
|
59
150
|
class SizeStruct < FFI::Struct
|
60
151
|
layout :value, :size_t
|
@@ -65,25 +156,24 @@ module Vips
|
|
65
156
|
end
|
66
157
|
|
67
158
|
attach_function :vips_value_get_ref_string,
|
68
|
-
|
159
|
+
[GObject::GValue.ptr, SizeStruct.ptr], :string
|
69
160
|
attach_function :vips_value_get_array_double,
|
70
|
-
|
161
|
+
[GObject::GValue.ptr, IntStruct.ptr], :pointer
|
71
162
|
attach_function :vips_value_get_array_int,
|
72
|
-
|
163
|
+
[GObject::GValue.ptr, IntStruct.ptr], :pointer
|
73
164
|
attach_function :vips_value_get_array_image,
|
74
|
-
|
165
|
+
[GObject::GValue.ptr, IntStruct.ptr], :pointer
|
75
166
|
attach_function :vips_value_get_blob,
|
76
|
-
|
167
|
+
[GObject::GValue.ptr, SizeStruct.ptr], :pointer
|
77
168
|
|
78
169
|
attach_function :type_find, :vips_type_find, [:string, :string], :GType
|
79
170
|
|
80
171
|
class Object < GObject::GObject
|
81
|
-
|
82
172
|
# print all active VipsObjects, with their reference counts. Handy for
|
83
173
|
# debugging ruby-vips.
|
84
174
|
def self.print_all
|
85
175
|
GC.start
|
86
|
-
Vips
|
176
|
+
Vips.vips_object_print_all
|
87
177
|
end
|
88
178
|
|
89
179
|
# the layout of the VipsObject struct
|
@@ -92,41 +182,39 @@ module Vips
|
|
92
182
|
base.class_eval do
|
93
183
|
# don't actually need most of these
|
94
184
|
layout :parent, GObject::GObject::Struct,
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
185
|
+
:constructed, :int,
|
186
|
+
:static_object, :int,
|
187
|
+
:argument_table, :pointer,
|
188
|
+
:nickname, :string,
|
189
|
+
:description, :string,
|
190
|
+
:preclose, :int,
|
191
|
+
:close, :int,
|
192
|
+
:postclose, :int,
|
193
|
+
:local_memory, :size_t
|
104
194
|
end
|
105
195
|
end
|
106
196
|
end
|
107
197
|
|
108
198
|
class Struct < GObject::GObject::Struct
|
109
199
|
include ObjectLayout
|
110
|
-
|
111
200
|
end
|
112
201
|
|
113
202
|
class ManagedStruct < GObject::GObject::ManagedStruct
|
114
203
|
include ObjectLayout
|
115
|
-
|
116
204
|
end
|
117
205
|
|
118
206
|
# return a pspec, or nil ... nil wil leave a message in the error log
|
119
207
|
# which you must clear
|
120
208
|
def get_pspec name
|
121
|
-
|
209
|
+
ppspec = GObject::GParamSpecPtr.new
|
122
210
|
argument_class = Vips::ArgumentClassPtr.new
|
123
211
|
argument_instance = Vips::ArgumentInstancePtr.new
|
124
212
|
|
125
|
-
result = Vips
|
126
|
-
|
213
|
+
result = Vips.vips_object_get_argument self, name,
|
214
|
+
ppspec, argument_class, argument_instance
|
127
215
|
return nil if result != 0
|
128
216
|
|
129
|
-
|
217
|
+
ppspec[:value]
|
130
218
|
end
|
131
219
|
|
132
220
|
# return a gtype, raise an error on not found
|
@@ -134,42 +222,67 @@ module Vips
|
|
134
222
|
pspec = get_pspec name
|
135
223
|
raise Vips::Error unless pspec
|
136
224
|
|
137
|
-
pspec[:
|
225
|
+
pspec[:value_type]
|
138
226
|
end
|
139
227
|
|
140
228
|
# return a gtype, 0 on not found
|
141
229
|
def get_typeof name
|
142
230
|
pspec = get_pspec name
|
143
231
|
unless pspec
|
144
|
-
Vips
|
232
|
+
Vips.vips_error_clear
|
145
233
|
return 0
|
146
234
|
end
|
147
235
|
|
148
|
-
pspec[:
|
236
|
+
pspec[:value_type]
|
149
237
|
end
|
150
238
|
|
151
239
|
def get name
|
152
240
|
gtype = get_typeof_error name
|
153
241
|
gvalue = GObject::GValue.alloc
|
154
242
|
gvalue.init gtype
|
155
|
-
GObject
|
243
|
+
GObject.g_object_get_property self, name, gvalue
|
156
244
|
result = gvalue.get
|
245
|
+
gvalue.unset
|
157
246
|
|
158
|
-
GLib
|
247
|
+
GLib.logger.debug("Vips::Object.get") { "#{name} == #{result}" }
|
159
248
|
|
160
|
-
|
249
|
+
result
|
161
250
|
end
|
162
251
|
|
163
252
|
def set name, value
|
164
|
-
GLib
|
253
|
+
GLib.logger.debug("Vips::Object.set") { "#{name} = #{value}" }
|
165
254
|
|
166
255
|
gtype = get_typeof_error name
|
167
256
|
gvalue = GObject::GValue.alloc
|
168
257
|
gvalue.init gtype
|
169
258
|
gvalue.set value
|
170
|
-
GObject
|
259
|
+
GObject.g_object_set_property self, name, gvalue
|
260
|
+
gvalue.unset
|
171
261
|
end
|
172
262
|
|
263
|
+
def signal_connect name, handler = nil, &block
|
264
|
+
marshal = MARSHAL_ALL[name.to_sym]
|
265
|
+
raise Vips::Error, "unsupported signal #{name}" if marshal.nil?
|
266
|
+
|
267
|
+
if block
|
268
|
+
# our block as a Proc
|
269
|
+
prc = block
|
270
|
+
elsif handler
|
271
|
+
# We assume the hander is a Proc (perhaps we should test)
|
272
|
+
prc = handler
|
273
|
+
else
|
274
|
+
raise Vips::Error, "must supply either block or handler"
|
275
|
+
end
|
276
|
+
|
277
|
+
# The marshal function will make a closure with the right type signature
|
278
|
+
# for the selected signal
|
279
|
+
callback = marshal.call(prc)
|
280
|
+
|
281
|
+
# we need to make sure this is not GCd while self is alive
|
282
|
+
@references << callback
|
283
|
+
|
284
|
+
GObject.g_signal_connect_data(self, name.to_s, callback, nil, nil, 0)
|
285
|
+
end
|
173
286
|
end
|
174
287
|
|
175
288
|
class ObjectClass < FFI::Struct
|
@@ -196,22 +309,22 @@ module Vips
|
|
196
309
|
ARGUMENT_MODIFY = 128
|
197
310
|
|
198
311
|
ARGUMENT_FLAGS = {
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
312
|
+
required: ARGUMENT_REQUIRED,
|
313
|
+
construct: ARGUMENT_CONSTRUCT,
|
314
|
+
set_once: ARGUMENT_SET_ONCE,
|
315
|
+
set_always: ARGUMENT_SET_ALWAYS,
|
316
|
+
input: ARGUMENT_INPUT,
|
317
|
+
output: ARGUMENT_OUTPUT,
|
318
|
+
deprecated: ARGUMENT_DEPRECATED,
|
319
|
+
modify: ARGUMENT_MODIFY
|
207
320
|
}
|
208
321
|
|
209
322
|
class ArgumentClass < Argument
|
210
323
|
layout :parent, Argument,
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
324
|
+
:object_class, ObjectClass.ptr,
|
325
|
+
:flags, :uint,
|
326
|
+
:priority, :int,
|
327
|
+
:offset, :ulong_long
|
215
328
|
end
|
216
329
|
|
217
330
|
class ArgumentClassPtr < FFI::Struct
|
@@ -225,10 +338,10 @@ module Vips
|
|
225
338
|
# just use :pointer, not VipsObject.ptr, to avoid casting gobject
|
226
339
|
# subclasses
|
227
340
|
attach_function :vips_object_get_argument,
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
341
|
+
[:pointer, :string,
|
342
|
+
GObject::GParamSpecPtr.ptr,
|
343
|
+
ArgumentClassPtr.ptr, ArgumentInstancePtr.ptr],
|
344
|
+
:int
|
232
345
|
|
233
346
|
attach_function :vips_object_print_all, [], :void
|
234
347
|
|
@@ -238,7 +351,4 @@ module Vips
|
|
238
351
|
attach_function :vips_type_map, [:GType, :type_map_fn, :pointer], :pointer
|
239
352
|
|
240
353
|
attach_function :vips_object_get_description, [:pointer], :string
|
241
|
-
|
242
354
|
end
|
243
|
-
|
244
|
-
|