vips 8.8.0.3 → 8.10.5
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/.travis.yml +5 -2
- data/README.md +3 -1
- data/example/connection.rb +17 -0
- data/example/daltonize8.rb +13 -15
- data/example/example1.rb +1 -2
- data/example/example4.rb +2 -2
- data/example/example5.rb +4 -5
- data/example/inheritance_with_refcount.rb +2 -19
- data/example/progress.rb +30 -0
- data/example/thumb.rb +2 -4
- data/example/trim8.rb +4 -4
- data/ext/Rakefile +2 -2
- data/lib/vips.rb +101 -35
- 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 +0 -2
- 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 +8 -4
- data/lib/vips/gvalue.rb +15 -9
- data/lib/vips/image.rb +269 -204
- data/lib/vips/interesting.rb +0 -1
- data/lib/vips/interpolate.rb +0 -5
- data/lib/vips/interpretation.rb +0 -1
- data/lib/vips/kernel.rb +0 -1
- data/lib/vips/methods.rb +150 -59
- data/lib/vips/object.rb +126 -18
- data/lib/vips/operation.rb +169 -101
- 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 +89 -0
- data/lib/vips/sourcecustom.rb +90 -0
- data/lib/vips/target.rb +87 -0
- data/lib/vips/targetcustom.rb +78 -0
- data/lib/vips/version.rb +1 -1
- metadata +14 -7
- data/CHANGELOG.md +0 -266
data/lib/vips/object.rb
CHANGED
@@ -41,6 +41,97 @@ module Vips
|
|
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.new do |handler|
|
66
|
+
FFI::Function.new(:void, [:pointer, :pointer, :pointer]) do |vi, prog, cb|
|
67
|
+
begin
|
68
|
+
handler.(Progress.new(prog))
|
69
|
+
rescue Exception => e
|
70
|
+
puts "progress: #{e}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
MARSHAL_READ = Proc.new do |handler|
|
76
|
+
FFI::Function.new(:int64_t, [:pointer, :pointer, :int64_t]) do |i, p, len|
|
77
|
+
begin
|
78
|
+
result = handler.(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.new do |handler|
|
89
|
+
FFI::Function.new(:int64_t, [:pointer, :int64_t, :int]) do |i, off, whence|
|
90
|
+
begin
|
91
|
+
result = handler.(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.new do |handler|
|
102
|
+
FFI::Function.new(:int64_t, [:pointer, :pointer, :int64_t]) do |i, p, len|
|
103
|
+
begin
|
104
|
+
result = handler.(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.new do |handler|
|
115
|
+
FFI::Function.new(:void, [:pointer, :pointer]) do |i, cb|
|
116
|
+
begin
|
117
|
+
handler.()
|
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
|
|
@@ -78,7 +169,6 @@ module Vips
|
|
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
|
@@ -107,26 +197,24 @@ module Vips
|
|
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
213
|
result = Vips::vips_object_get_argument self, name,
|
126
|
-
|
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,7 +222,7 @@ 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
|
@@ -145,7 +233,7 @@ module Vips
|
|
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
|
@@ -154,20 +242,40 @@ module Vips
|
|
154
242
|
gvalue.init gtype
|
155
243
|
GObject::g_object_get_property self, name, gvalue
|
156
244
|
result = gvalue.get
|
245
|
+
gvalue.unset
|
157
246
|
|
158
|
-
GLib::logger.debug("Vips::Object.get") {"#{name} == #{result}"}
|
247
|
+
GLib::logger.debug("Vips::Object.get") { "#{name} == #{result}" }
|
159
248
|
|
160
249
|
return result
|
161
250
|
end
|
162
251
|
|
163
252
|
def set name, value
|
164
|
-
GLib::logger.debug("Vips::Object.set") {"#{name} = #{value}"}
|
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
259
|
GObject::g_object_set_property self, name, gvalue
|
260
|
+
gvalue.unset
|
261
|
+
end
|
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
|
+
unless handler ||= block
|
268
|
+
raise Vips::Error, "must supply either block or handler"
|
269
|
+
end
|
270
|
+
|
271
|
+
# The marshal function will make a closure with the right type signature
|
272
|
+
# for the selected signal
|
273
|
+
callback = marshal.(handler)
|
274
|
+
|
275
|
+
# we need to make sure this is not GCd while self is alive
|
276
|
+
@references << callback
|
277
|
+
|
278
|
+
GObject::g_signal_connect_data(self, name.to_s, callback, nil, nil, 0)
|
171
279
|
end
|
172
280
|
|
173
281
|
end
|
@@ -196,14 +304,14 @@ module Vips
|
|
196
304
|
ARGUMENT_MODIFY = 128
|
197
305
|
|
198
306
|
ARGUMENT_FLAGS = {
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
307
|
+
required: ARGUMENT_REQUIRED,
|
308
|
+
construct: ARGUMENT_CONSTRUCT,
|
309
|
+
set_once: ARGUMENT_SET_ONCE,
|
310
|
+
set_always: ARGUMENT_SET_ALWAYS,
|
311
|
+
input: ARGUMENT_INPUT,
|
312
|
+
output: ARGUMENT_OUTPUT,
|
313
|
+
deprecated: ARGUMENT_DEPRECATED,
|
314
|
+
modify: ARGUMENT_MODIFY
|
207
315
|
}
|
208
316
|
|
209
317
|
class ArgumentClass < Argument
|
data/lib/vips/operation.rb
CHANGED
@@ -11,7 +11,13 @@ module Vips
|
|
11
11
|
|
12
12
|
attach_function :vips_operation_new, [:string], :pointer
|
13
13
|
|
14
|
-
|
14
|
+
# We may well block during this (eg. if it's avg, or perhaps jpegsave), and
|
15
|
+
# libvips might trigger some signals which ruby has handles for.
|
16
|
+
#
|
17
|
+
# We need FFI to drop the GIL lock during this call and reacquire it when
|
18
|
+
# the call ends, or we'll deadlock.
|
19
|
+
attach_function :vips_cache_operation_build, [:pointer], :pointer,
|
20
|
+
blocking: true
|
15
21
|
attach_function :vips_object_unref_outputs, [:pointer], :void
|
16
22
|
|
17
23
|
callback :argument_map_fn, [:pointer,
|
@@ -28,15 +34,126 @@ module Vips
|
|
28
34
|
OPERATION_DEPRECATED = 8
|
29
35
|
|
30
36
|
OPERATION_FLAGS = {
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
sequential: OPERATION_SEQUENTIAL,
|
38
|
+
nocache: OPERATION_NOCACHE,
|
39
|
+
deprecated: OPERATION_DEPRECATED
|
34
40
|
}
|
35
41
|
|
36
42
|
attach_function :vips_operation_get_flags, [:pointer], :int
|
37
43
|
|
38
|
-
|
44
|
+
# Introspect a vips operation and return a large structure containing
|
45
|
+
# everything we know about it. This is used for doc generation as well as
|
46
|
+
# call.
|
47
|
+
class Introspect
|
48
|
+
attr_reader :name, :description, :flags, :args, :required_input,
|
49
|
+
:optional_input, :required_output, :optional_output, :member_x,
|
50
|
+
:method_args
|
51
|
+
|
52
|
+
@@introspect_cache = {}
|
53
|
+
|
54
|
+
def initialize name
|
55
|
+
@op = Operation.new name
|
56
|
+
@args = []
|
57
|
+
@required_input = []
|
58
|
+
@optional_input = {}
|
59
|
+
@required_output = []
|
60
|
+
@optional_output = {}
|
61
|
+
|
62
|
+
# find all the arguments the operator can take
|
63
|
+
@op.argument_map do |pspec, argument_class, _argument_instance|
|
64
|
+
flags = argument_class[:flags]
|
65
|
+
if (flags & ARGUMENT_CONSTRUCT) != 0
|
66
|
+
# names can include - as punctuation, but we always use _ in
|
67
|
+
# Ruby
|
68
|
+
arg_name = pspec[:name].tr("-", "_")
|
69
|
+
args << {
|
70
|
+
:arg_name => arg_name,
|
71
|
+
:flags => flags,
|
72
|
+
:gtype => pspec[:value_type]
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
@args.each do |details|
|
78
|
+
arg_name = details[:arg_name]
|
79
|
+
flags = details[:flags]
|
80
|
+
|
81
|
+
if (flags & ARGUMENT_INPUT) != 0
|
82
|
+
if (flags & ARGUMENT_REQUIRED) != 0 &&
|
83
|
+
(flags & ARGUMENT_DEPRECATED) == 0
|
84
|
+
@required_input << details
|
85
|
+
else
|
86
|
+
# we allow deprecated optional args
|
87
|
+
@optional_input[arg_name] = details
|
88
|
+
end
|
89
|
+
|
90
|
+
# MODIFY INPUT args count as OUTPUT as well
|
91
|
+
if (flags & ARGUMENT_MODIFY) != 0
|
92
|
+
if (flags & ARGUMENT_REQUIRED) != 0 &&
|
93
|
+
(flags & ARGUMENT_DEPRECATED) == 0
|
94
|
+
@required_output << details
|
95
|
+
else
|
96
|
+
@optional_output[arg_name] = details
|
97
|
+
end
|
98
|
+
end
|
99
|
+
elsif (flags & ARGUMENT_OUTPUT) != 0
|
100
|
+
if (flags & ARGUMENT_REQUIRED) != 0 &&
|
101
|
+
(flags & ARGUMENT_DEPRECATED) == 0
|
102
|
+
@required_output << details
|
103
|
+
else
|
104
|
+
# again, allow deprecated optional args
|
105
|
+
@optional_output[arg_name] = details
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Yard comment generation needs a little more introspection. We add this
|
112
|
+
# extra metadata in a separate method to keep the main path as fast as
|
113
|
+
# we can.
|
114
|
+
def add_yard_introspection name
|
115
|
+
@name = name
|
116
|
+
@description = Vips::vips_object_get_description @op
|
117
|
+
@flags = Vips::vips_operation_get_flags @op
|
118
|
+
@member_x = nil
|
119
|
+
@method_args = []
|
120
|
+
|
121
|
+
@args.each do |details|
|
122
|
+
arg_name = details[:arg_name]
|
123
|
+
flags = details[:flags]
|
124
|
+
gtype = details[:gtype]
|
125
|
+
|
126
|
+
details[:yard_name] = arg_name == "in" ? "im" : arg_name
|
127
|
+
pspec = @op.get_pspec arg_name
|
128
|
+
details[:blurb] = GObject::g_param_spec_get_blurb pspec
|
129
|
+
|
130
|
+
if (flags & ARGUMENT_INPUT) != 0 &&
|
131
|
+
(flags & ARGUMENT_REQUIRED) != 0 &&
|
132
|
+
(flags & ARGUMENT_DEPRECATED) == 0
|
133
|
+
# the first required input image is the thing we will be a method
|
134
|
+
# of
|
135
|
+
if @member_x == nil && gtype == IMAGE_TYPE
|
136
|
+
@member_x = details
|
137
|
+
else
|
138
|
+
@method_args << details
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.get name
|
145
|
+
@@introspect_cache[name] ||= Introspect.new name
|
146
|
+
end
|
39
147
|
|
148
|
+
def self.get_yard name
|
149
|
+
introspect = Introspect.get name
|
150
|
+
introspect.add_yard_introspection name
|
151
|
+
introspect
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
class Operation < Object
|
40
157
|
# the layout of the VipsOperation struct
|
41
158
|
module OperationLayout
|
42
159
|
def self.included base
|
@@ -49,12 +166,10 @@ module Vips
|
|
49
166
|
|
50
167
|
class Struct < Object::Struct
|
51
168
|
include OperationLayout
|
52
|
-
|
53
169
|
end
|
54
170
|
|
55
171
|
class ManagedStruct < Object::ManagedStruct
|
56
172
|
include OperationLayout
|
57
|
-
|
58
173
|
end
|
59
174
|
|
60
175
|
def initialize value
|
@@ -62,7 +177,7 @@ module Vips
|
|
62
177
|
# things like _build
|
63
178
|
if value.is_a? String
|
64
179
|
value = Vips::vips_operation_new value
|
65
|
-
raise Vips::Error if value
|
180
|
+
raise Vips::Error if value.null?
|
66
181
|
end
|
67
182
|
|
68
183
|
super value
|
@@ -70,7 +185,8 @@ module Vips
|
|
70
185
|
|
71
186
|
def build
|
72
187
|
op = Vips::vips_cache_operation_build self
|
73
|
-
if op
|
188
|
+
if op.null?
|
189
|
+
Vips::vips_object_unref_outputs self
|
74
190
|
raise Vips::Error
|
75
191
|
end
|
76
192
|
|
@@ -78,42 +194,23 @@ module Vips
|
|
78
194
|
end
|
79
195
|
|
80
196
|
def argument_map &block
|
81
|
-
fn = Proc.new do |
|
197
|
+
fn = Proc.new do |_op, pspec, argument_class, argument_instance, _a, _b|
|
82
198
|
block.call pspec, argument_class, argument_instance
|
83
199
|
end
|
84
200
|
|
85
201
|
Vips::vips_argument_map self, fn, nil, nil
|
86
202
|
end
|
87
203
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
argument_map do |pspec, argument_class, argument_instance|
|
97
|
-
flags = argument_class[:flags]
|
98
|
-
if (flags & ARGUMENT_CONSTRUCT) != 0
|
99
|
-
# names can include - as punctuation, but we always use _ in
|
100
|
-
# Ruby
|
101
|
-
name = pspec[:name].tr("-", "_")
|
102
|
-
|
103
|
-
args << [name, flags]
|
204
|
+
# Search an object for the first element to match a predicate. Search
|
205
|
+
# inside subarrays and sub-hashes. Equlvalent to x.flatten.find{}.
|
206
|
+
def self.flat_find object, &block
|
207
|
+
if object.respond_to? :each
|
208
|
+
object.each do |x|
|
209
|
+
result = flat_find x, &block
|
210
|
+
return result if result != nil
|
104
211
|
end
|
105
|
-
|
106
|
-
|
107
|
-
return args
|
108
|
-
end
|
109
|
-
|
110
|
-
# search array for the first element to match a predicate ...
|
111
|
-
# search inside subarrays and sub-hashes
|
112
|
-
def self.find_inside object, &block
|
113
|
-
return object if block.call object
|
114
|
-
|
115
|
-
if object.is_a? Enumerable
|
116
|
-
object.find {|value| block.call value, block}
|
212
|
+
else
|
213
|
+
return object if yield object
|
117
214
|
end
|
118
215
|
|
119
216
|
return nil
|
@@ -125,8 +222,8 @@ module Vips
|
|
125
222
|
|
126
223
|
# 2D array values become tiny 2D images
|
127
224
|
# if there's nothing to match to, we also make a 2D image
|
128
|
-
if (value.is_a?(Array) && value[0].is_a?(Array)) ||
|
129
|
-
|
225
|
+
if (value.is_a?(Array) && value[0].is_a?(Array)) ||
|
226
|
+
match_image == nil
|
130
227
|
return Image.new_from_array value
|
131
228
|
else
|
132
229
|
# we have a 1D array ... use that as a pixel constant and
|
@@ -137,9 +234,7 @@ module Vips
|
|
137
234
|
|
138
235
|
# set an operation argument, expanding constants and copying images as
|
139
236
|
# required
|
140
|
-
def set name, value, match_image
|
141
|
-
gtype = get_typeof name
|
142
|
-
|
237
|
+
def set name, value, match_image, flags, gtype
|
143
238
|
if gtype == IMAGE_TYPE
|
144
239
|
value = Operation::imageize match_image, value
|
145
240
|
|
@@ -148,7 +243,7 @@ module Vips
|
|
148
243
|
value = value.copy.copy_memory
|
149
244
|
end
|
150
245
|
elsif gtype == ARRAY_IMAGE_TYPE
|
151
|
-
value = value.map {|x| Operation::imageize match_image, x}
|
246
|
+
value = value.map { |x| Operation::imageize match_image, x }
|
152
247
|
end
|
153
248
|
|
154
249
|
super name, value
|
@@ -226,66 +321,39 @@ module Vips
|
|
226
321
|
def self.call name, supplied, optional = {}, option_string = ""
|
227
322
|
GLib::logger.debug("Vips::VipsOperation.call") {
|
228
323
|
"name = #{name}, supplied = #{supplied}, " +
|
229
|
-
|
324
|
+
"optional = #{optional}, option_string = #{option_string}"
|
230
325
|
}
|
231
326
|
|
232
|
-
|
327
|
+
introspect = Introspect.get name
|
328
|
+
required_input = introspect.required_input
|
329
|
+
required_output = introspect.required_output
|
330
|
+
optional_input = introspect.optional_input
|
331
|
+
optional_output = introspect.optional_output
|
233
332
|
|
234
|
-
# find and classify all the arguments the operator can take
|
235
|
-
args = op.get_construct_args
|
236
|
-
required_input = []
|
237
|
-
optional_input = {}
|
238
|
-
required_output = []
|
239
|
-
optional_output = {}
|
240
|
-
args.each do |name, flags|
|
241
|
-
next if (flags & ARGUMENT_DEPRECATED) != 0
|
242
|
-
|
243
|
-
if (flags & ARGUMENT_INPUT) != 0
|
244
|
-
if (flags & ARGUMENT_REQUIRED) != 0
|
245
|
-
required_input << [name, flags]
|
246
|
-
else
|
247
|
-
optional_input[name] = flags
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
# MODIFY INPUT args count as OUTPUT as well
|
252
|
-
if (flags & ARGUMENT_OUTPUT) != 0 ||
|
253
|
-
((flags & ARGUMENT_INPUT) != 0 &&
|
254
|
-
(flags & ARGUMENT_MODIFY) != 0)
|
255
|
-
if (flags & ARGUMENT_REQUIRED) != 0
|
256
|
-
required_output << [name, flags]
|
257
|
-
else
|
258
|
-
optional_output[name] = flags
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
end
|
263
|
-
|
264
|
-
# so we should have been supplied with n_required_input values, or
|
265
|
-
# n_required_input + 1 if there's a hash of options at the end
|
266
333
|
unless supplied.is_a? Array
|
267
334
|
raise Vips::Error, "unable to call #{name}: " +
|
268
|
-
|
335
|
+
"argument array is not an array"
|
269
336
|
end
|
270
337
|
unless optional.is_a? Hash
|
271
338
|
raise Vips::Error, "unable to call #{name}: " +
|
272
|
-
|
339
|
+
"optional arguments are not a hash"
|
273
340
|
end
|
341
|
+
|
274
342
|
if supplied.length != required_input.length
|
275
343
|
raise Vips::Error, "unable to call #{name}: " +
|
276
|
-
|
277
|
-
|
344
|
+
"you supplied #{supplied.length} arguments, " +
|
345
|
+
"but operation needs " + "#{required_input.length}."
|
278
346
|
end
|
279
347
|
|
280
|
-
#
|
348
|
+
# all supplied_optional keys should be in optional_input or
|
281
349
|
# optional_output
|
282
|
-
optional.each do |key,
|
350
|
+
optional.each do |key, _value|
|
283
351
|
arg_name = key.to_s
|
284
352
|
|
285
353
|
unless optional_input.has_key?(arg_name) ||
|
286
354
|
optional_output.has_key?(arg_name)
|
287
355
|
raise Vips::Error, "unable to call #{name}: " +
|
288
|
-
|
356
|
+
"unknown option #{arg_name}"
|
289
357
|
end
|
290
358
|
end
|
291
359
|
|
@@ -294,9 +362,9 @@ module Vips
|
|
294
362
|
#
|
295
363
|
# look inside array and hash arguments, since we may be passing an
|
296
364
|
# array of images
|
297
|
-
match_image =
|
298
|
-
|
299
|
-
|
365
|
+
match_image = flat_find(supplied) { |value| value.is_a? Image }
|
366
|
+
|
367
|
+
op = Operation.new name
|
300
368
|
|
301
369
|
# set any string args first so they can't be overridden
|
302
370
|
if option_string != nil
|
@@ -307,11 +375,13 @@ module Vips
|
|
307
375
|
|
308
376
|
# set all required inputs
|
309
377
|
required_input.each_index do |i|
|
310
|
-
|
311
|
-
|
378
|
+
details = required_input[i]
|
379
|
+
arg_name = details[:arg_name]
|
380
|
+
flags = details[:flags]
|
381
|
+
gtype = details[:gtype]
|
312
382
|
value = supplied[i]
|
313
383
|
|
314
|
-
op.set arg_name, value, match_image, flags
|
384
|
+
op.set arg_name, value, match_image, flags, gtype
|
315
385
|
end
|
316
386
|
|
317
387
|
# set all optional inputs
|
@@ -321,9 +391,11 @@ module Vips
|
|
321
391
|
arg_name = key.to_s
|
322
392
|
|
323
393
|
if optional_input.has_key? arg_name
|
324
|
-
|
394
|
+
details = optional_input[arg_name]
|
395
|
+
flags = details[:flags]
|
396
|
+
gtype = details[:gtype]
|
325
397
|
|
326
|
-
op.set arg_name, value, match_image, flags
|
398
|
+
op.set arg_name, value, match_image, flags, gtype
|
327
399
|
end
|
328
400
|
end
|
329
401
|
|
@@ -331,18 +403,16 @@ module Vips
|
|
331
403
|
|
332
404
|
# get all required results
|
333
405
|
result = []
|
334
|
-
required_output.each do |
|
335
|
-
result << op.get(arg_name)
|
406
|
+
required_output.each do |details|
|
407
|
+
result << op.get(details[:arg_name])
|
336
408
|
end
|
337
409
|
|
338
410
|
# fetch all optional ones
|
339
411
|
optional_results = {}
|
340
|
-
optional.each do |key,
|
412
|
+
optional.each do |key, _value|
|
341
413
|
arg_name = key.to_s
|
342
414
|
|
343
415
|
if optional_output.has_key? arg_name
|
344
|
-
flags = optional_output[arg_name]
|
345
|
-
|
346
416
|
optional_results[arg_name] = op.get arg_name
|
347
417
|
end
|
348
418
|
end
|
@@ -355,13 +425,11 @@ module Vips
|
|
355
425
|
result = nil
|
356
426
|
end
|
357
427
|
|
358
|
-
GLib::logger.debug("Vips::Operation.call") {"result = #{result}"}
|
428
|
+
GLib::logger.debug("Vips::Operation.call") { "result = #{result}" }
|
359
429
|
|
360
430
|
Vips::vips_object_unref_outputs op
|
361
431
|
|
362
432
|
return result
|
363
433
|
end
|
364
|
-
|
365
434
|
end
|
366
|
-
|
367
435
|
end
|