ruby-vips 2.0.13 → 2.0.14

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -0
  3. data/.rubocop_todo.yml +730 -0
  4. data/.travis.yml +13 -6
  5. data/CHANGELOG.md +8 -0
  6. data/README.md +5 -8
  7. data/Rakefile +6 -0
  8. data/VERSION +1 -1
  9. data/example/annotate.rb +2 -2
  10. data/example/daltonize8.rb +14 -14
  11. data/example/example2.rb +6 -6
  12. data/example/example3.rb +5 -5
  13. data/example/example4.rb +4 -4
  14. data/example/example5.rb +2 -2
  15. data/example/inheritance_with_refcount.rb +207 -207
  16. data/example/thumb.rb +10 -10
  17. data/example/trim8.rb +2 -2
  18. data/example/watermark.rb +14 -35
  19. data/example/wobble.rb +24 -24
  20. data/install-vips.sh +1 -1
  21. data/lib/vips.rb +335 -306
  22. data/lib/vips/access.rb +9 -9
  23. data/lib/vips/align.rb +7 -7
  24. data/lib/vips/angle.rb +8 -8
  25. data/lib/vips/angle45.rb +12 -12
  26. data/lib/vips/bandformat.rb +16 -16
  27. data/lib/vips/blend_mode.rb +34 -0
  28. data/lib/vips/coding.rb +11 -11
  29. data/lib/vips/compass_direction.rb +13 -13
  30. data/lib/vips/direction.rb +7 -7
  31. data/lib/vips/extend.rb +13 -13
  32. data/lib/vips/gobject.rb +94 -94
  33. data/lib/vips/gvalue.rb +232 -232
  34. data/lib/vips/image.rb +1329 -1335
  35. data/lib/vips/interesting.rb +10 -10
  36. data/lib/vips/interpolate.rb +51 -51
  37. data/lib/vips/interpretation.rb +25 -25
  38. data/lib/vips/kernel.rb +18 -18
  39. data/lib/vips/methods.rb +463 -283
  40. data/lib/vips/object.rb +208 -208
  41. data/lib/vips/operation.rb +323 -323
  42. data/lib/vips/operationboolean.rb +10 -10
  43. data/lib/vips/operationcomplex.rb +8 -8
  44. data/lib/vips/operationcomplex2.rb +6 -6
  45. data/lib/vips/operationcomplexget.rb +7 -7
  46. data/lib/vips/operationmath.rb +14 -14
  47. data/lib/vips/operationmath2.rb +6 -6
  48. data/lib/vips/operationrelational.rb +11 -11
  49. data/lib/vips/operationround.rb +7 -7
  50. data/lib/vips/size.rb +9 -9
  51. data/lib/vips/version.rb +1 -1
  52. data/ruby-vips.gemspec +6 -2
  53. metadata +29 -6
@@ -7,237 +7,237 @@
7
7
  require 'ffi'
8
8
 
9
9
  module Vips
10
- private
11
-
12
- # debugging support
13
- attach_function :vips_object_print_all, [], :void
14
-
15
- # we must init these by hand, since they are usually made on first image
16
- # create
17
- attach_function :vips_band_format_get_type, [], :GType
18
- attach_function :vips_interpretation_get_type, [], :GType
19
- attach_function :vips_coding_get_type, [], :GType
20
-
21
- public
22
-
23
- # some handy gtypes
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
- attach_function :vips_blend_mode_get_type, [], :GType
37
- BLEND_MODE_TYPE = Vips::vips_blend_mode_get_type
38
- else
39
- BLEND_MODE_TYPE = nil
10
+ private
11
+
12
+ # debugging support
13
+ attach_function :vips_object_print_all, [], :void
14
+
15
+ # we must init these by hand, since they are usually made on first image
16
+ # create
17
+ attach_function :vips_band_format_get_type, [], :GType
18
+ attach_function :vips_interpretation_get_type, [], :GType
19
+ attach_function :vips_coding_get_type, [], :GType
20
+
21
+ public
22
+
23
+ # some handy gtypes
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
+ attach_function :vips_blend_mode_get_type, [], :GType
37
+ BLEND_MODE_TYPE = Vips::vips_blend_mode_get_type
38
+ else
39
+ BLEND_MODE_TYPE = nil
40
+ end
41
+
42
+ private
43
+
44
+ attach_function :vips_enum_from_nick, [:string, :GType, :string], :int
45
+ attach_function :vips_enum_nick, [:GType, :int], :string
46
+
47
+ attach_function :vips_value_set_ref_string,
48
+ [GObject::GValue.ptr, :string], :void
49
+ attach_function :vips_value_set_array_double,
50
+ [GObject::GValue.ptr, :pointer, :int], :void
51
+ attach_function :vips_value_set_array_int,
52
+ [GObject::GValue.ptr, :pointer, :int], :void
53
+ attach_function :vips_value_set_array_image,
54
+ [GObject::GValue.ptr, :int], :void
55
+ callback :free_fn, [:pointer], :void
56
+ attach_function :vips_value_set_blob,
57
+ [GObject::GValue.ptr, :free_fn, :pointer, :size_t], :void
58
+
59
+ class SizeStruct < FFI::Struct
60
+ layout :value, :size_t
61
+ end
62
+
63
+ class IntStruct < FFI::Struct
64
+ layout :value, :int
65
+ end
66
+
67
+ attach_function :vips_value_get_ref_string,
68
+ [GObject::GValue.ptr, SizeStruct.ptr], :string
69
+ attach_function :vips_value_get_array_double,
70
+ [GObject::GValue.ptr, IntStruct.ptr], :pointer
71
+ attach_function :vips_value_get_array_int,
72
+ [GObject::GValue.ptr, IntStruct.ptr], :pointer
73
+ attach_function :vips_value_get_array_image,
74
+ [GObject::GValue.ptr, IntStruct.ptr], :pointer
75
+ attach_function :vips_value_get_blob,
76
+ [GObject::GValue.ptr, SizeStruct.ptr], :pointer
77
+
78
+ attach_function :type_find, :vips_type_find, [:string, :string], :GType
79
+
80
+ class Object < GObject::GObject
81
+
82
+ # print all active VipsObjects, with their reference counts. Handy for
83
+ # debugging ruby-vips.
84
+ def self.print_all
85
+ GC.start
86
+ Vips::vips_object_print_all
40
87
  end
41
88
 
42
- private
43
-
44
- attach_function :vips_enum_from_nick, [:string, :GType, :string], :int
45
- attach_function :vips_enum_nick, [:GType, :int], :string
46
-
47
- attach_function :vips_value_set_ref_string,
48
- [GObject::GValue.ptr, :string], :void
49
- attach_function :vips_value_set_array_double,
50
- [GObject::GValue.ptr, :pointer, :int], :void
51
- attach_function :vips_value_set_array_int,
52
- [GObject::GValue.ptr, :pointer, :int], :void
53
- attach_function :vips_value_set_array_image,
54
- [GObject::GValue.ptr, :int], :void
55
- callback :free_fn, [:pointer], :void
56
- attach_function :vips_value_set_blob,
57
- [GObject::GValue.ptr, :free_fn, :pointer, :size_t], :void
58
-
59
- class SizeStruct < FFI::Struct
60
- layout :value, :size_t
61
- end
62
-
63
- class IntStruct < FFI::Struct
64
- layout :value, :int
65
- end
66
-
67
- attach_function :vips_value_get_ref_string,
68
- [GObject::GValue.ptr, SizeStruct.ptr], :string
69
- attach_function :vips_value_get_array_double,
70
- [GObject::GValue.ptr, IntStruct.ptr], :pointer
71
- attach_function :vips_value_get_array_int,
72
- [GObject::GValue.ptr, IntStruct.ptr], :pointer
73
- attach_function :vips_value_get_array_image,
74
- [GObject::GValue.ptr, IntStruct.ptr], :pointer
75
- attach_function :vips_value_get_blob,
76
- [GObject::GValue.ptr, SizeStruct.ptr], :pointer
77
-
78
- attach_function :type_find, :vips_type_find, [:string, :string], :GType
79
-
80
- class Object < GObject::GObject
81
-
82
- # print all active VipsObjects, with their reference counts. Handy for
83
- # debugging ruby-vips.
84
- def self.print_all
85
- GC.start
86
- Vips::vips_object_print_all
87
- end
88
-
89
- # the layout of the VipsObject struct
90
- module ObjectLayout
91
- def self.included base
92
- base.class_eval do
93
- # don't actually need most of these
94
- layout :parent, GObject::GObject::Struct,
95
- :constructed, :int,
96
- :static_object, :int,
97
- :argument_table, :pointer,
98
- :nickname, :string,
99
- :description, :string,
100
- :preclose, :int,
101
- :close, :int,
102
- :postclose, :int,
103
- :local_memory, :size_t
104
- end
105
- end
106
- end
107
-
108
- class Struct < GObject::GObject::Struct
109
- include ObjectLayout
110
-
111
- end
112
-
113
- class ManagedStruct < GObject::GObject::ManagedStruct
114
- include ObjectLayout
115
-
116
- end
117
-
118
- # return a pspec, or nil ... nil wil leave a message in the error log
119
- # which you must clear
120
- def get_pspec name
121
- pspec = GObject::GParamSpecPtr.new
122
- argument_class = Vips::ArgumentClassPtr.new
123
- argument_instance = Vips::ArgumentInstancePtr.new
124
-
125
- result = Vips::vips_object_get_argument self, name,
126
- pspec, argument_class, argument_instance
127
- return nil if result != 0
128
-
129
- pspec
130
- end
131
-
132
- # return a gtype, raise an error on not found
133
- def get_typeof_error name
134
- pspec = get_pspec name
135
- raise Vips::Error unless pspec
136
-
137
- pspec[:value][:value_type]
138
- end
139
-
140
- # return a gtype, 0 on not found
141
- def get_typeof name
142
- pspec = get_pspec name
143
- unless pspec
144
- Vips::vips_error_clear
145
- return 0
146
- end
147
-
148
- pspec[:value][:value_type]
89
+ # the layout of the VipsObject struct
90
+ module ObjectLayout
91
+ def self.included base
92
+ base.class_eval do
93
+ # don't actually need most of these
94
+ layout :parent, GObject::GObject::Struct,
95
+ :constructed, :int,
96
+ :static_object, :int,
97
+ :argument_table, :pointer,
98
+ :nickname, :string,
99
+ :description, :string,
100
+ :preclose, :int,
101
+ :close, :int,
102
+ :postclose, :int,
103
+ :local_memory, :size_t
149
104
  end
105
+ end
106
+ end
150
107
 
151
- def get name
152
- gtype = get_typeof_error name
153
- gvalue = GObject::GValue.alloc
154
- gvalue.init gtype
155
- GObject::g_object_get_property self, name, gvalue
156
- result = gvalue.get
108
+ class Struct < GObject::GObject::Struct
109
+ include ObjectLayout
157
110
 
158
- GLib::logger.debug("Vips::Object.get") {"#{name} == #{result}"}
111
+ end
159
112
 
160
- return result
161
- end
113
+ class ManagedStruct < GObject::GObject::ManagedStruct
114
+ include ObjectLayout
162
115
 
163
- def set name, value
164
- GLib::logger.debug("Vips::Object.set") {"#{name} = #{value}"}
116
+ end
165
117
 
166
- gtype = get_typeof_error name
167
- gvalue = GObject::GValue.alloc
168
- gvalue.init gtype
169
- gvalue.set value
170
- GObject::g_object_set_property self, name, gvalue
171
- end
118
+ # return a pspec, or nil ... nil wil leave a message in the error log
119
+ # which you must clear
120
+ def get_pspec name
121
+ pspec = GObject::GParamSpecPtr.new
122
+ argument_class = Vips::ArgumentClassPtr.new
123
+ argument_instance = Vips::ArgumentInstancePtr.new
172
124
 
173
- end
125
+ result = Vips::vips_object_get_argument self, name,
126
+ pspec, argument_class, argument_instance
127
+ return nil if result != 0
174
128
 
175
- class ObjectClass < FFI::Struct
176
- # opaque
129
+ pspec
177
130
  end
178
131
 
179
- class Argument < FFI::Struct
180
- layout :pspec, GObject::GParamSpec.ptr
181
- end
132
+ # return a gtype, raise an error on not found
133
+ def get_typeof_error name
134
+ pspec = get_pspec name
135
+ raise Vips::Error unless pspec
182
136
 
183
- class ArgumentInstance < Argument
184
- layout :parent, Argument
185
- # rest opaque
137
+ pspec[:value][:value_type]
186
138
  end
187
139
 
188
- # enum VipsArgumentFlags
189
- ARGUMENT_REQUIRED = 1
190
- ARGUMENT_CONSTRUCT = 2
191
- ARGUMENT_SET_ONCE = 4
192
- ARGUMENT_SET_ALWAYS = 8
193
- ARGUMENT_INPUT = 16
194
- ARGUMENT_OUTPUT = 32
195
- ARGUMENT_DEPRECATED = 64
196
- ARGUMENT_MODIFY = 128
197
-
198
- ARGUMENT_FLAGS = {
199
- :required => ARGUMENT_REQUIRED,
200
- :construct => ARGUMENT_CONSTRUCT,
201
- :set_once => ARGUMENT_SET_ONCE,
202
- :set_always => ARGUMENT_SET_ALWAYS,
203
- :input => ARGUMENT_INPUT,
204
- :output => ARGUMENT_OUTPUT,
205
- :deprecated => ARGUMENT_DEPRECATED,
206
- :modify => ARGUMENT_MODIFY
207
- }
208
-
209
- class ArgumentClass < Argument
210
- layout :parent, Argument,
211
- :object_class, ObjectClass.ptr,
212
- :flags, :uint,
213
- :priority, :int,
214
- :offset, :ulong_long
215
- end
140
+ # return a gtype, 0 on not found
141
+ def get_typeof name
142
+ pspec = get_pspec name
143
+ unless pspec
144
+ Vips::vips_error_clear
145
+ return 0
146
+ end
216
147
 
217
- class ArgumentClassPtr < FFI::Struct
218
- layout :value, ArgumentClass.ptr
148
+ pspec[:value][:value_type]
219
149
  end
220
150
 
221
- class ArgumentInstancePtr < FFI::Struct
222
- layout :value, ArgumentInstance.ptr
223
- end
151
+ def get name
152
+ gtype = get_typeof_error name
153
+ gvalue = GObject::GValue.alloc
154
+ gvalue.init gtype
155
+ GObject::g_object_get_property self, name, gvalue
156
+ result = gvalue.get
224
157
 
225
- # just use :pointer, not VipsObject.ptr, to avoid casting gobject
226
- # subclasses
227
- attach_function :vips_object_get_argument,
228
- [:pointer, :string,
229
- GObject::GParamSpecPtr.ptr,
230
- ArgumentClassPtr.ptr, ArgumentInstancePtr.ptr],
231
- :int
158
+ GLib::logger.debug("Vips::Object.get") {"#{name} == #{result}"}
232
159
 
233
- attach_function :vips_object_print_all, [], :void
160
+ return result
161
+ end
234
162
 
235
- attach_function :vips_object_set_from_string, [:pointer, :string], :int
163
+ def set name, value
164
+ GLib::logger.debug("Vips::Object.set") {"#{name} = #{value}"}
236
165
 
237
- callback :type_map_fn, [:GType, :pointer], :pointer
238
- attach_function :vips_type_map, [:GType, :type_map_fn, :pointer], :pointer
166
+ gtype = get_typeof_error name
167
+ gvalue = GObject::GValue.alloc
168
+ gvalue.init gtype
169
+ gvalue.set value
170
+ GObject::g_object_set_property self, name, gvalue
171
+ end
239
172
 
240
- attach_function :vips_object_get_description, [:pointer], :string
173
+ end
174
+
175
+ class ObjectClass < FFI::Struct
176
+ # opaque
177
+ end
178
+
179
+ class Argument < FFI::Struct
180
+ layout :pspec, GObject::GParamSpec.ptr
181
+ end
182
+
183
+ class ArgumentInstance < Argument
184
+ layout :parent, Argument
185
+ # rest opaque
186
+ end
187
+
188
+ # enum VipsArgumentFlags
189
+ ARGUMENT_REQUIRED = 1
190
+ ARGUMENT_CONSTRUCT = 2
191
+ ARGUMENT_SET_ONCE = 4
192
+ ARGUMENT_SET_ALWAYS = 8
193
+ ARGUMENT_INPUT = 16
194
+ ARGUMENT_OUTPUT = 32
195
+ ARGUMENT_DEPRECATED = 64
196
+ ARGUMENT_MODIFY = 128
197
+
198
+ ARGUMENT_FLAGS = {
199
+ :required => ARGUMENT_REQUIRED,
200
+ :construct => ARGUMENT_CONSTRUCT,
201
+ :set_once => ARGUMENT_SET_ONCE,
202
+ :set_always => ARGUMENT_SET_ALWAYS,
203
+ :input => ARGUMENT_INPUT,
204
+ :output => ARGUMENT_OUTPUT,
205
+ :deprecated => ARGUMENT_DEPRECATED,
206
+ :modify => ARGUMENT_MODIFY
207
+ }
208
+
209
+ class ArgumentClass < Argument
210
+ layout :parent, Argument,
211
+ :object_class, ObjectClass.ptr,
212
+ :flags, :uint,
213
+ :priority, :int,
214
+ :offset, :ulong_long
215
+ end
216
+
217
+ class ArgumentClassPtr < FFI::Struct
218
+ layout :value, ArgumentClass.ptr
219
+ end
220
+
221
+ class ArgumentInstancePtr < FFI::Struct
222
+ layout :value, ArgumentInstance.ptr
223
+ end
224
+
225
+ # just use :pointer, not VipsObject.ptr, to avoid casting gobject
226
+ # subclasses
227
+ attach_function :vips_object_get_argument,
228
+ [:pointer, :string,
229
+ GObject::GParamSpecPtr.ptr,
230
+ ArgumentClassPtr.ptr, ArgumentInstancePtr.ptr],
231
+ :int
232
+
233
+ attach_function :vips_object_print_all, [], :void
234
+
235
+ attach_function :vips_object_set_from_string, [:pointer, :string], :int
236
+
237
+ callback :type_map_fn, [:GType, :pointer], :pointer
238
+ attach_function :vips_type_map, [:GType, :type_map_fn, :pointer], :pointer
239
+
240
+ attach_function :vips_object_get_description, [:pointer], :string
241
241
 
242
242
  end
243
243
 
@@ -7,361 +7,361 @@
7
7
  require 'ffi'
8
8
 
9
9
  module Vips
10
- private
11
-
12
- attach_function :vips_operation_new, [:string], :pointer
13
-
14
- attach_function :vips_cache_operation_build, [:pointer], :pointer
15
- attach_function :vips_object_unref_outputs, [:pointer], :void
16
-
17
- callback :argument_map_fn, [:pointer,
18
- GObject::GParamSpec.ptr,
19
- ArgumentClass.ptr,
20
- ArgumentInstance.ptr,
21
- :pointer, :pointer], :pointer
22
- attach_function :vips_argument_map, [:pointer,
23
- :argument_map_fn,
24
- :pointer, :pointer], :pointer
25
-
26
- OPERATION_SEQUENTIAL = 1
27
- OPERATION_NOCACHE = 4
28
- OPERATION_DEPRECATED = 8
29
-
30
- OPERATION_FLAGS = {
31
- :sequential => OPERATION_SEQUENTIAL,
32
- :nocache => OPERATION_NOCACHE,
33
- :deprecated => OPERATION_DEPRECATED
34
- }
35
-
36
- attach_function :vips_operation_get_flags, [:pointer], :int
37
-
38
- class Operation < Object
39
-
40
- # the layout of the VipsOperation struct
41
- module OperationLayout
42
- def self.included base
43
- base.class_eval do
44
- layout :parent, Object::Struct
45
- # rest opaque
46
- end
47
- end
10
+ private
11
+
12
+ attach_function :vips_operation_new, [:string], :pointer
13
+
14
+ attach_function :vips_cache_operation_build, [:pointer], :pointer
15
+ attach_function :vips_object_unref_outputs, [:pointer], :void
16
+
17
+ callback :argument_map_fn, [:pointer,
18
+ GObject::GParamSpec.ptr,
19
+ ArgumentClass.ptr,
20
+ ArgumentInstance.ptr,
21
+ :pointer, :pointer], :pointer
22
+ attach_function :vips_argument_map, [:pointer,
23
+ :argument_map_fn,
24
+ :pointer, :pointer], :pointer
25
+
26
+ OPERATION_SEQUENTIAL = 1
27
+ OPERATION_NOCACHE = 4
28
+ OPERATION_DEPRECATED = 8
29
+
30
+ OPERATION_FLAGS = {
31
+ :sequential => OPERATION_SEQUENTIAL,
32
+ :nocache => OPERATION_NOCACHE,
33
+ :deprecated => OPERATION_DEPRECATED
34
+ }
35
+
36
+ attach_function :vips_operation_get_flags, [:pointer], :int
37
+
38
+ class Operation < Object
39
+
40
+ # the layout of the VipsOperation struct
41
+ module OperationLayout
42
+ def self.included base
43
+ base.class_eval do
44
+ layout :parent, Object::Struct
45
+ # rest opaque
48
46
  end
47
+ end
48
+ end
49
49
 
50
- class Struct < Object::Struct
51
- include OperationLayout
50
+ class Struct < Object::Struct
51
+ include OperationLayout
52
52
 
53
- end
53
+ end
54
54
 
55
- class ManagedStruct < Object::ManagedStruct
56
- include OperationLayout
55
+ class ManagedStruct < Object::ManagedStruct
56
+ include OperationLayout
57
57
 
58
- end
58
+ end
59
59
 
60
- def initialize value
61
- # allow init with a pointer so we can wrap the return values from
62
- # things like _build
63
- if value.is_a? String
64
- value = Vips::vips_operation_new value
65
- raise Vips::Error if value == nil
66
- end
60
+ def initialize value
61
+ # allow init with a pointer so we can wrap the return values from
62
+ # things like _build
63
+ if value.is_a? String
64
+ value = Vips::vips_operation_new value
65
+ raise Vips::Error if value == nil
66
+ end
67
67
 
68
- super value
69
- end
68
+ super value
69
+ end
70
70
 
71
- def build
72
- op = Vips::vips_cache_operation_build self
73
- if op == nil
74
- raise Vips::Error
75
- end
71
+ def build
72
+ op = Vips::vips_cache_operation_build self
73
+ if op == nil
74
+ raise Vips::Error
75
+ end
76
76
 
77
- return Operation.new op
78
- end
77
+ return Operation.new op
78
+ end
79
79
 
80
- def argument_map &block
81
- fn = Proc.new do |op, pspec, argument_class, argument_instance, a, b|
82
- block.call pspec, argument_class, argument_instance
83
- end
80
+ def argument_map &block
81
+ fn = Proc.new do |op, pspec, argument_class, argument_instance, a, b|
82
+ block.call pspec, argument_class, argument_instance
83
+ end
84
84
 
85
- Vips::vips_argument_map self, fn, nil, nil
86
- end
85
+ Vips::vips_argument_map self, fn, nil, nil
86
+ end
87
+
88
+ def get_flags
89
+ Vips::vips_operation_get_flags self
90
+ end
91
+
92
+ # not quick! try to call this infrequently
93
+ def get_construct_args
94
+ args = []
87
95
 
88
- def get_flags
89
- Vips::vips_operation_get_flags self
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]
90
104
  end
105
+ end
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
91
114
 
92
- # not quick! try to call this infrequently
93
- def get_construct_args
94
- args = []
115
+ if object.is_a? Enumerable
116
+ object.find {|value| block.call value, block}
117
+ end
95
118
 
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("-", "_")
119
+ return nil
120
+ end
121
+
122
+ # expand a constant into an image
123
+ def self.imageize match_image, value
124
+ return value if value.is_a? Image
125
+
126
+ # 2D array values become tiny 2D images
127
+ # 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
+ match_image == nil
130
+ return Image.new_from_array value
131
+ else
132
+ # we have a 1D array ... use that as a pixel constant and
133
+ # expand to match match_image
134
+ return match_image.new_from_image value
135
+ end
136
+ end
102
137
 
103
- args << [name, flags]
104
- end
105
- end
138
+ # set an operation argument, expanding constants and copying images as
139
+ # required
140
+ def set name, value, match_image = nil, flags = 0
141
+ gtype = get_typeof name
106
142
 
107
- return args
143
+ if gtype == IMAGE_TYPE
144
+ value = Operation::imageize match_image, value
145
+
146
+ if (flags & ARGUMENT_MODIFY) != 0
147
+ # make sure we have a unique copy
148
+ value = value.copy.copy_memory
108
149
  end
150
+ elsif gtype == ARRAY_IMAGE_TYPE
151
+ value = value.map {|x| Operation::imageize match_image, x}
152
+ end
109
153
 
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
154
+ super name, value
155
+ end
114
156
 
115
- if object.is_a? Enumerable
116
- object.find {|value| block.call value, block}
117
- end
157
+ public
158
+
159
+ # This is the public entry point for the vips binding. {call} will run
160
+ # any vips operation, for example:
161
+ #
162
+ # ```ruby
163
+ # out = Vips::Operation.call "black", [100, 100], {:bands => 12}
164
+ # ```
165
+ #
166
+ # will call the C function
167
+ #
168
+ # ```C
169
+ # vips_black( &out, 100, 100, "bands", 12, NULL );
170
+ # ```
171
+ #
172
+ # There are {Image#method_missing} hooks which will run {call} for you
173
+ # on {Image} for undefined instance or class methods. So you can also
174
+ # write:
175
+ #
176
+ # ```ruby
177
+ # out = Vips::Image.black 100, 100, bands: 12
178
+ # ```
179
+ #
180
+ # Or perhaps:
181
+ #
182
+ # ```ruby
183
+ # x = Vips::Image.black 100, 100
184
+ # y = x.invert
185
+ # ```
186
+ #
187
+ # to run the `vips_invert()` operator.
188
+ #
189
+ # There are also a set of operator overloads and some convenience
190
+ # functions, see {Image}.
191
+ #
192
+ # If the operator needs a vector constant, {call} will turn a scalar
193
+ # into a
194
+ # vector for you. So for `x.linear a, b`, which calculates
195
+ # `x * a + b` where `a` and `b` are vector constants, you can write:
196
+ #
197
+ # ```ruby
198
+ # x = Vips::Image.black 100, 100, bands: 3
199
+ # y = x.linear 1, 2
200
+ # y = x.linear [1], 4
201
+ # y = x.linear [1, 2, 3], 4
202
+ # ```
203
+ #
204
+ # or any other combination. The operator overloads use this facility to
205
+ # support all the variations on:
206
+ #
207
+ # ```ruby
208
+ # x = Vips::Image.black 100, 100, bands: 3
209
+ # y = x * 2
210
+ # y = x + [1,2,3]
211
+ # y = x % [1]
212
+ # ```
213
+ #
214
+ # Similarly, wherever an image is required, you can use a constant. The
215
+ # constant will be expanded to an image matching the first input image
216
+ # argument. For example, you can write:
217
+ #
218
+ # ```
219
+ # x = Vips::Image.black 100, 100, bands: 3
220
+ # y = x.bandjoin 255
221
+ # ```
222
+ #
223
+ # to add an extra band to the image where each pixel in the new band has
224
+ # the constant value 255.
225
+
226
+ def self.call name, supplied, optional = {}, option_string = ""
227
+ GLib::logger.debug("Vips::VipsOperation.call") {
228
+ "name = #{name}, supplied = #{supplied}, " +
229
+ "optional = #{optional}, option_string = #{option_string}"
230
+ }
231
+
232
+ op = Operation.new name
233
+
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
118
250
 
119
- return nil
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
120
260
  end
121
261
 
122
- # expand a constant into an image
123
- def self.imageize match_image, value
124
- return value if value.is_a? Image
125
-
126
- # 2D array values become tiny 2D images
127
- # 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
- match_image == nil
130
- return Image.new_from_array value
131
- else
132
- # we have a 1D array ... use that as a pixel constant and
133
- # expand to match match_image
134
- return match_image.new_from_image value
135
- end
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
+ unless supplied.is_a? Array
267
+ raise Vips::Error, "unable to call #{name}: " +
268
+ "argument array is not an array"
269
+ end
270
+ unless optional.is_a? Hash
271
+ raise Vips::Error, "unable to call #{name}: " +
272
+ "optional arguments are not a hash"
273
+ end
274
+ if supplied.length != required_input.length
275
+ raise Vips::Error, "unable to call #{name}: " +
276
+ "you supplied #{supplied.length} arguments, " +
277
+ "but operation needs #{required_input.length}."
278
+ end
279
+
280
+ # very that all supplied_optional keys are in optional_input or
281
+ # optional_output
282
+ optional.each do |key, value|
283
+ arg_name = key.to_s
284
+
285
+ unless optional_input.has_key?(arg_name) ||
286
+ optional_output.has_key?(arg_name)
287
+ raise Vips::Error, "unable to call #{name}: " +
288
+ "unknown option #{arg_name}"
289
+ end
290
+ end
291
+
292
+ # the first image arg is the thing we expand constants to match ...
293
+ # we need to find it
294
+ #
295
+ # look inside array and hash arguments, since we may be passing an
296
+ # array of images
297
+ match_image = find_inside(supplied) do |value|
298
+ value.is_a? Image
299
+ end
300
+
301
+ # set any string args first so they can't be overridden
302
+ if option_string != nil
303
+ if Vips::vips_object_set_from_string(op, option_string) != 0
304
+ raise Vips::Error
136
305
  end
306
+ end
307
+
308
+ # set all required inputs
309
+ required_input.each_index do |i|
310
+ arg_name = required_input[i][0]
311
+ flags = required_input[i][1]
312
+ value = supplied[i]
313
+
314
+ op.set arg_name, value, match_image, flags
315
+ end
137
316
 
138
- # set an operation argument, expanding constants and copying images as
139
- # required
140
- def set name, value, match_image = nil, flags = 0
141
- gtype = get_typeof name
317
+ # set all optional inputs
318
+ optional.each do |key, value|
319
+ next if value.nil?
142
320
 
143
- if gtype == IMAGE_TYPE
144
- value = Operation::imageize match_image, value
321
+ arg_name = key.to_s
145
322
 
146
- if (flags & ARGUMENT_MODIFY) != 0
147
- # make sure we have a unique copy
148
- value = value.copy.copy_memory
149
- end
150
- elsif gtype == ARRAY_IMAGE_TYPE
151
- value = value.map {|x| Operation::imageize match_image, x}
152
- end
323
+ if optional_input.has_key? arg_name
324
+ flags = optional_input[arg_name]
153
325
 
154
- super name, value
326
+ op.set arg_name, value, match_image, flags
155
327
  end
328
+ end
156
329
 
157
- public
158
-
159
- # This is the public entry point for the vips binding. {call} will run
160
- # any vips operation, for example:
161
- #
162
- # ```ruby
163
- # out = Vips::Operation.call "black", [100, 100], {:bands => 12}
164
- # ```
165
- #
166
- # will call the C function
167
- #
168
- # ```C
169
- # vips_black( &out, 100, 100, "bands", 12, NULL );
170
- # ```
171
- #
172
- # There are {Image#method_missing} hooks which will run {call} for you
173
- # on {Image} for undefined instance or class methods. So you can also
174
- # write:
175
- #
176
- # ```ruby
177
- # out = Vips::Image.black 100, 100, bands: 12
178
- # ```
179
- #
180
- # Or perhaps:
181
- #
182
- # ```ruby
183
- # x = Vips::Image.black 100, 100
184
- # y = x.invert
185
- # ```
186
- #
187
- # to run the `vips_invert()` operator.
188
- #
189
- # There are also a set of operator overloads and some convenience
190
- # functions, see {Image}.
191
- #
192
- # If the operator needs a vector constant, {call} will turn a scalar
193
- # into a
194
- # vector for you. So for `x.linear a, b`, which calculates
195
- # `x * a + b` where `a` and `b` are vector constants, you can write:
196
- #
197
- # ```ruby
198
- # x = Vips::Image.black 100, 100, bands: 3
199
- # y = x.linear 1, 2
200
- # y = x.linear [1], 4
201
- # y = x.linear [1, 2, 3], 4
202
- # ```
203
- #
204
- # or any other combination. The operator overloads use this facility to
205
- # support all the variations on:
206
- #
207
- # ```ruby
208
- # x = Vips::Image.black 100, 100, bands: 3
209
- # y = x * 2
210
- # y = x + [1,2,3]
211
- # y = x % [1]
212
- # ```
213
- #
214
- # Similarly, wherever an image is required, you can use a constant. The
215
- # constant will be expanded to an image matching the first input image
216
- # argument. For example, you can write:
217
- #
218
- # ```
219
- # x = Vips::Image.black 100, 100, bands: 3
220
- # y = x.bandjoin 255
221
- # ```
222
- #
223
- # to add an extra band to the image where each pixel in the new band has
224
- # the constant value 255.
225
-
226
- def self.call name, supplied, optional = {}, option_string = ""
227
- GLib::logger.debug("Vips::VipsOperation.call") {
228
- "name = #{name}, supplied = #{supplied}, " +
229
- "optional = #{optional}, option_string = #{option_string}"
230
- }
231
-
232
- op = Operation.new name
233
-
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
- unless supplied.is_a? Array
267
- raise Vips::Error, "unable to call #{name}: " +
268
- "argument array is not an array"
269
- end
270
- unless optional.is_a? Hash
271
- raise Vips::Error, "unable to call #{name}: " +
272
- "optional arguments are not a hash"
273
- end
274
- if supplied.length != required_input.length
275
- raise Vips::Error, "unable to call #{name}: " +
276
- "you supplied #{supplied.length} arguments, " +
277
- "but operation needs #{required_input.length}."
278
- end
279
-
280
- # very that all supplied_optional keys are in optional_input or
281
- # optional_output
282
- optional.each do |key, value|
283
- arg_name = key.to_s
284
-
285
- unless optional_input.has_key?(arg_name) ||
286
- optional_output.has_key?(arg_name)
287
- raise Vips::Error, "unable to call #{name}: " +
288
- "unknown option #{arg_name}"
289
- end
290
- end
291
-
292
- # the first image arg is the thing we expand constants to match ...
293
- # we need to find it
294
- #
295
- # look inside array and hash arguments, since we may be passing an
296
- # array of images
297
- match_image = find_inside(supplied) do |value|
298
- value.is_a? Image
299
- end
300
-
301
- # set any string args first so they can't be overridden
302
- if option_string != nil
303
- if Vips::vips_object_set_from_string(op, option_string) != 0
304
- raise Vips::Error
305
- end
306
- end
307
-
308
- # set all required inputs
309
- required_input.each_index do |i|
310
- arg_name = required_input[i][0]
311
- flags = required_input[i][1]
312
- value = supplied[i]
313
-
314
- op.set arg_name, value, match_image, flags
315
- end
316
-
317
- # set all optional inputs
318
- optional.each do |key, value|
319
- next if value.nil?
320
-
321
- arg_name = key.to_s
322
-
323
- if optional_input.has_key? arg_name
324
- flags = optional_input[arg_name]
325
-
326
- op.set arg_name, value, match_image, flags
327
- end
328
- end
329
-
330
- op = op.build
331
-
332
- # get all required results
333
- result = []
334
- required_output.each do |arg_name, flags|
335
- result << op.get(arg_name)
336
- end
337
-
338
- # fetch all optional ones
339
- optional_results = {}
340
- optional.each do |key, value|
341
- arg_name = key.to_s
342
-
343
- if optional_output.has_key? arg_name
344
- flags = optional_output[arg_name]
345
-
346
- optional_results[arg_name] = op.get arg_name
347
- end
348
- end
349
-
350
- result << optional_results if optional_results != {}
351
-
352
- if result.length == 1
353
- result = result.first
354
- elsif result.length == 0
355
- result = nil
356
- end
357
-
358
- GLib::logger.debug("Vips::Operation.call") {"result = #{result}"}
359
-
360
- Vips::vips_object_unref_outputs op
361
-
362
- return result
330
+ op = op.build
331
+
332
+ # get all required results
333
+ result = []
334
+ required_output.each do |arg_name, flags|
335
+ result << op.get(arg_name)
336
+ end
337
+
338
+ # fetch all optional ones
339
+ optional_results = {}
340
+ optional.each do |key, value|
341
+ arg_name = key.to_s
342
+
343
+ if optional_output.has_key? arg_name
344
+ flags = optional_output[arg_name]
345
+
346
+ optional_results[arg_name] = op.get arg_name
363
347
  end
348
+ end
349
+
350
+ result << optional_results if optional_results != {}
364
351
 
352
+ if result.length == 1
353
+ result = result.first
354
+ elsif result.length == 0
355
+ result = nil
356
+ end
357
+
358
+ GLib::logger.debug("Vips::Operation.call") {"result = #{result}"}
359
+
360
+ Vips::vips_object_unref_outputs op
361
+
362
+ return result
365
363
  end
366
364
 
365
+ end
366
+
367
367
  end