ruby-vips 2.0.17 → 2.1.0
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 +13 -0
- data/Gemfile +3 -1
- data/README.md +4 -4
- data/Rakefile +13 -21
- data/TODO +3 -6
- data/VERSION +1 -1
- data/example/annotate.rb +6 -6
- data/example/connection.rb +18 -9
- data/example/daltonize8.rb +6 -6
- data/example/draw_lines.rb +30 -0
- data/example/example1.rb +4 -4
- data/example/example2.rb +6 -6
- data/example/example3.rb +5 -5
- data/example/example4.rb +2 -2
- data/example/example5.rb +4 -4
- data/example/inheritance_with_refcount.rb +35 -36
- data/example/progress.rb +3 -3
- data/example/thumb.rb +6 -6
- data/example/trim8.rb +1 -1
- data/example/watermark.rb +2 -2
- data/example/wobble.rb +1 -1
- data/lib/ruby-vips.rb +1 -1
- data/lib/vips.rb +121 -75
- data/lib/vips/blend_mode.rb +29 -25
- data/lib/vips/connection.rb +4 -4
- data/lib/vips/gobject.rb +18 -11
- data/lib/vips/gvalue.rb +54 -54
- data/lib/vips/image.rb +232 -155
- data/lib/vips/interpolate.rb +3 -2
- data/lib/vips/methods.rb +165 -15
- data/lib/vips/mutableimage.rb +154 -0
- data/lib/vips/object.rb +84 -85
- data/lib/vips/operation.rb +161 -82
- data/lib/vips/region.rb +6 -6
- data/lib/vips/source.rb +11 -12
- data/lib/vips/sourcecustom.rb +7 -8
- data/lib/vips/target.rb +12 -13
- data/lib/vips/targetcustom.rb +9 -10
- data/lib/vips/version.rb +1 -1
- data/ruby-vips.gemspec +26 -22
- metadata +28 -48
- data/.rubocop.yml +0 -22
- data/.rubocop_todo.yml +0 -473
- data/.travis.yml +0 -57
- data/install-vips.sh +0 -26
data/lib/vips/blend_mode.rb
CHANGED
@@ -1,31 +1,35 @@
|
|
1
1
|
module Vips
|
2
2
|
# Blend mode to use when compositing images. See {Image#composite}.
|
3
3
|
#
|
4
|
-
# `:clear`
|
5
|
-
# `:source`
|
6
|
-
# `:over`
|
7
|
-
#
|
8
|
-
# `:
|
9
|
-
#
|
10
|
-
# `:
|
11
|
-
# `:
|
12
|
-
#
|
13
|
-
# `:
|
14
|
-
#
|
15
|
-
# `:
|
16
|
-
# `:
|
17
|
-
# `:
|
18
|
-
# `:
|
19
|
-
# `:
|
20
|
-
# `:
|
21
|
-
# `:
|
22
|
-
# `:
|
23
|
-
# `:
|
24
|
-
# `:
|
25
|
-
# `:
|
26
|
-
# `:
|
27
|
-
# `:
|
28
|
-
# `:
|
4
|
+
# * `:clear` where the second object is drawn, the first is removed
|
5
|
+
# * `:source` the second object is drawn as if nothing were below
|
6
|
+
# * `:over` the image shows what you would expect if you held two
|
7
|
+
# semi-transparent slides on top of each other
|
8
|
+
# * `:in` the first object is removed completely, the second is only
|
9
|
+
# drawn where the first was
|
10
|
+
# * `:out` the second is drawn only where the first isn't
|
11
|
+
# * `:atop` this leaves the first object mostly intact, but mixes both
|
12
|
+
# objects in the overlapping area
|
13
|
+
# * `:dest` leaves the first object untouched, the second is discarded
|
14
|
+
# completely
|
15
|
+
# * `:dest_over` like `:over`, but swaps the arguments
|
16
|
+
# * `:dest_in` like `:in`, but swaps the arguments
|
17
|
+
# * `:dest_out` like `:out`, but swaps the arguments
|
18
|
+
# * `:dest_atop` like `:atop`, but swaps the arguments
|
19
|
+
# * `:xor` something like a difference operator
|
20
|
+
# * `:add` a bit like adding the two images
|
21
|
+
# * `:saturate` a bit like the darker of the two
|
22
|
+
# * `:multiply` at least as dark as the darker of the two inputs
|
23
|
+
# * `:screen` at least as light as the lighter of the inputs
|
24
|
+
# * `:overlay` multiplies or screens colors, depending on the lightness
|
25
|
+
# * `:darken` the darker of each component
|
26
|
+
# * `:lighten` the lighter of each component
|
27
|
+
# * `:colour_dodge` brighten first by a factor second
|
28
|
+
# * `:colour_burn` darken first by a factor of second
|
29
|
+
# * `:hard_light` multiply or screen, depending on lightness
|
30
|
+
# * `:soft_light` darken or lighten, depending on lightness
|
31
|
+
# * `:difference` difference of the two
|
32
|
+
# * `:exclusion` somewhat like `:difference`, but lower-contrast
|
29
33
|
|
30
34
|
class BlendMode < Symbol
|
31
35
|
end
|
data/lib/vips/connection.rb
CHANGED
@@ -4,10 +4,10 @@
|
|
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
|
-
if Vips
|
10
|
+
if Vips.at_least_libvips?(8, 9)
|
11
11
|
attach_function :vips_connection_filename, [:pointer], :string
|
12
12
|
attach_function :vips_connection_nick, [:pointer], :string
|
13
13
|
end
|
@@ -34,13 +34,13 @@ module Vips
|
|
34
34
|
|
35
35
|
# Get any filename associated with a connection, or nil.
|
36
36
|
def filename
|
37
|
-
Vips
|
37
|
+
Vips.vips_connection_filename self
|
38
38
|
end
|
39
39
|
|
40
40
|
# Get a nickname (short description) of a connection that could be shown to
|
41
41
|
# the user.
|
42
42
|
def nick
|
43
|
-
Vips
|
43
|
+
Vips.vips_connection_nick self
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
data/lib/vips/gobject.rb
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
|
5
5
|
# License:: MIT
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require "ffi"
|
8
|
+
require "forwardable"
|
9
9
|
|
10
10
|
module GObject
|
11
11
|
# we have a number of things we need to inherit in different ways:
|
@@ -37,13 +37,15 @@ module GObject
|
|
37
37
|
def_instance_delegators :@struct, :[], :to_ptr
|
38
38
|
def_single_delegators :ffi_struct, :ptr
|
39
39
|
|
40
|
+
attr_reader :references
|
41
|
+
|
40
42
|
# the layout of the GObject struct
|
41
43
|
module GObjectLayout
|
42
44
|
def self.included base
|
43
45
|
base.class_eval do
|
44
46
|
layout :g_type_instance, :pointer,
|
45
|
-
|
46
|
-
|
47
|
+
:ref_count, :uint,
|
48
|
+
:qdata, :pointer
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
@@ -56,7 +58,7 @@ module GObject
|
|
56
58
|
# GLib::logger.debug("GObject::GObject::ManagedStruct.release") {
|
57
59
|
# "unreffing #{ptr}"
|
58
60
|
# }
|
59
|
-
::GObject
|
61
|
+
::GObject.g_object_unref ptr
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
@@ -72,6 +74,7 @@ module GObject
|
|
72
74
|
# need the unref
|
73
75
|
def initialize ptr
|
74
76
|
# GLib::logger.debug("GObject::GObject.initialize") {"ptr = #{ptr}"}
|
77
|
+
@ptr = ptr
|
75
78
|
@struct = ffi_managed_struct.new ptr
|
76
79
|
|
77
80
|
# sometimes we need to keep refs across C calls ... hide them here
|
@@ -83,9 +86,13 @@ module GObject
|
|
83
86
|
self.class.ffi_struct
|
84
87
|
end
|
85
88
|
|
89
|
+
# get the pointer we were built from ... #to_ptr gets the pointer after we
|
90
|
+
# have wrapped it up with an auto unref
|
91
|
+
attr_reader :ptr
|
92
|
+
|
86
93
|
class << self
|
87
94
|
def ffi_struct
|
88
|
-
|
95
|
+
const_get :Struct
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
@@ -96,7 +103,7 @@ module GObject
|
|
96
103
|
|
97
104
|
class << self
|
98
105
|
def ffi_managed_struct
|
99
|
-
|
106
|
+
const_get :ManagedStruct
|
100
107
|
end
|
101
108
|
end
|
102
109
|
end
|
@@ -104,10 +111,10 @@ module GObject
|
|
104
111
|
class GParamSpec < FFI::Struct
|
105
112
|
# the first few public fields
|
106
113
|
layout :g_type_instance, :pointer,
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
114
|
+
:name, :string,
|
115
|
+
:flags, :uint,
|
116
|
+
:value_type, :GType,
|
117
|
+
:owner_type, :GType
|
111
118
|
end
|
112
119
|
|
113
120
|
class GParamSpecPtr < FFI::Struct
|
data/lib/vips/gvalue.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
|
4
4
|
# License:: MIT
|
5
5
|
|
6
|
-
require
|
6
|
+
require "ffi"
|
7
7
|
|
8
8
|
module GObject
|
9
9
|
# Represent a GValue. Example use:
|
@@ -22,7 +22,7 @@ module GObject
|
|
22
22
|
|
23
23
|
class GValue < FFI::ManagedStruct
|
24
24
|
layout :gtype, :GType,
|
25
|
-
|
25
|
+
:data, [:ulong_long, 2]
|
26
26
|
|
27
27
|
# convert an enum value (str/symb/int) into an int ready for libvips
|
28
28
|
def self.from_nick(gtype, value)
|
@@ -31,7 +31,7 @@ module GObject
|
|
31
31
|
if value.is_a? String
|
32
32
|
# libvips expects "-" as a separator in enum names, but "_" is more
|
33
33
|
# convenient for ruby, eg. :b_w
|
34
|
-
value = Vips
|
34
|
+
value = Vips.vips_enum_from_nick "ruby-vips", gtype, value.tr("_", "-")
|
35
35
|
if value == -1
|
36
36
|
raise Vips::Error
|
37
37
|
end
|
@@ -42,8 +42,8 @@ module GObject
|
|
42
42
|
|
43
43
|
# convert an int enum back into a symbol
|
44
44
|
def self.to_nick(gtype, enum_value)
|
45
|
-
enum_name = Vips
|
46
|
-
if enum_name
|
45
|
+
enum_name = Vips.vips_enum_nick gtype, enum_value
|
46
|
+
if enum_name.nil?
|
47
47
|
raise Vips::Error
|
48
48
|
end
|
49
49
|
|
@@ -52,7 +52,7 @@ module GObject
|
|
52
52
|
|
53
53
|
def self.release ptr
|
54
54
|
# GLib::logger.debug("GObject::GValue::release") {"ptr = #{ptr}"}
|
55
|
-
::GObject
|
55
|
+
::GObject.g_value_unset ptr
|
56
56
|
end
|
57
57
|
|
58
58
|
# Allocate memory for a GValue and return a class wrapper. Memory will
|
@@ -70,14 +70,14 @@ module GObject
|
|
70
70
|
pointer = FFI::Pointer.new GValue, memory
|
71
71
|
|
72
72
|
# ... and wrap in a GValue
|
73
|
-
|
73
|
+
GValue.new pointer
|
74
74
|
end
|
75
75
|
|
76
76
|
# Set the type of thing a gvalue can hold.
|
77
77
|
#
|
78
78
|
# @param gtype [GType] the type of thing this GValue can hold.
|
79
79
|
def init gtype
|
80
|
-
::GObject
|
80
|
+
::GObject.g_value_init self, gtype
|
81
81
|
end
|
82
82
|
|
83
83
|
# Set the value of a GValue. The value is converted to the type of the
|
@@ -90,76 +90,76 @@ module GObject
|
|
90
90
|
# }
|
91
91
|
|
92
92
|
gtype = self[:gtype]
|
93
|
-
fundamental = ::GObject
|
93
|
+
fundamental = ::GObject.g_type_fundamental gtype
|
94
94
|
|
95
95
|
case gtype
|
96
96
|
when GBOOL_TYPE
|
97
|
-
::GObject
|
97
|
+
::GObject.g_value_set_boolean self, (value ? 1 : 0)
|
98
98
|
|
99
99
|
when GINT_TYPE
|
100
|
-
::GObject
|
100
|
+
::GObject.g_value_set_int self, value
|
101
101
|
|
102
102
|
when GUINT64_TYPE
|
103
|
-
::GObject
|
103
|
+
::GObject.g_value_set_uint64 self, value
|
104
104
|
|
105
105
|
when GDOUBLE_TYPE
|
106
|
-
::GObject
|
106
|
+
::GObject.g_value_set_double self, value
|
107
107
|
|
108
108
|
when GSTR_TYPE
|
109
|
-
::GObject
|
109
|
+
::GObject.g_value_set_string self, value
|
110
110
|
|
111
111
|
when Vips::REFSTR_TYPE
|
112
|
-
::Vips
|
112
|
+
::Vips.vips_value_set_ref_string self, value
|
113
113
|
|
114
114
|
when Vips::ARRAY_INT_TYPE
|
115
115
|
value = [value] unless value.is_a? Array
|
116
116
|
|
117
|
-
Vips
|
118
|
-
ptr = Vips
|
117
|
+
Vips.vips_value_set_array_int self, nil, value.length
|
118
|
+
ptr = Vips.vips_value_get_array_int self, nil
|
119
119
|
ptr.write_array_of_int32 value
|
120
120
|
|
121
121
|
when Vips::ARRAY_DOUBLE_TYPE
|
122
122
|
value = [value] unless value.is_a? Array
|
123
123
|
|
124
124
|
# this will allocate an array in the gvalue
|
125
|
-
Vips
|
125
|
+
Vips.vips_value_set_array_double self, nil, value.length
|
126
126
|
|
127
127
|
# pull the array out and fill it
|
128
|
-
ptr = Vips
|
128
|
+
ptr = Vips.vips_value_get_array_double self, nil
|
129
129
|
|
130
130
|
ptr.write_array_of_double value
|
131
131
|
|
132
132
|
when Vips::ARRAY_IMAGE_TYPE
|
133
133
|
value = [value] unless value.is_a? Array
|
134
134
|
|
135
|
-
Vips
|
136
|
-
ptr = Vips
|
135
|
+
Vips.vips_value_set_array_image self, value.length
|
136
|
+
ptr = Vips.vips_value_get_array_image self, nil
|
137
137
|
ptr.write_array_of_pointer value
|
138
138
|
|
139
139
|
# the gvalue needs a ref on each of the images
|
140
|
-
value.each { |image| ::GObject
|
140
|
+
value.each { |image| ::GObject.g_object_ref image }
|
141
141
|
|
142
142
|
when Vips::BLOB_TYPE
|
143
143
|
len = value.bytesize
|
144
|
-
ptr = GLib
|
145
|
-
Vips
|
144
|
+
ptr = GLib.g_malloc len
|
145
|
+
Vips.vips_value_set_blob self, GLib::G_FREE, ptr, len
|
146
146
|
ptr.write_bytes value
|
147
147
|
|
148
148
|
else
|
149
149
|
case fundamental
|
150
150
|
when GFLAGS_TYPE
|
151
|
-
::GObject
|
151
|
+
::GObject.g_value_set_flags self, value
|
152
152
|
|
153
153
|
when GENUM_TYPE
|
154
154
|
enum_value = GValue.from_nick(self[:gtype], value)
|
155
|
-
::GObject
|
155
|
+
::GObject.g_value_set_enum self, enum_value
|
156
156
|
|
157
157
|
when GOBJECT_TYPE
|
158
|
-
::GObject
|
158
|
+
::GObject.g_value_set_object self, value
|
159
159
|
|
160
160
|
else
|
161
|
-
raise Vips::Error, "unimplemented gtype for set: "
|
162
|
-
|
161
|
+
raise Vips::Error, "unimplemented gtype for set: " \
|
162
|
+
"#{::GObject.g_type_name gtype} (#{gtype})"
|
163
163
|
end
|
164
164
|
end
|
165
165
|
end
|
@@ -170,72 +170,72 @@ module GObject
|
|
170
170
|
# @return [Any] the value held by the GValue
|
171
171
|
def get
|
172
172
|
gtype = self[:gtype]
|
173
|
-
fundamental = ::GObject
|
173
|
+
fundamental = ::GObject.g_type_fundamental gtype
|
174
174
|
result = nil
|
175
175
|
|
176
176
|
case gtype
|
177
177
|
when GBOOL_TYPE
|
178
|
-
result = ::GObject
|
178
|
+
result = ::GObject.g_value_get_boolean(self) != 0
|
179
179
|
|
180
180
|
when GINT_TYPE
|
181
|
-
result = ::GObject
|
181
|
+
result = ::GObject.g_value_get_int self
|
182
182
|
|
183
183
|
when GUINT64_TYPE
|
184
|
-
result = ::GObject
|
184
|
+
result = ::GObject.g_value_get_uint64 self
|
185
185
|
|
186
186
|
when GDOUBLE_TYPE
|
187
|
-
result = ::GObject
|
187
|
+
result = ::GObject.g_value_get_double self
|
188
188
|
|
189
189
|
when GSTR_TYPE
|
190
|
-
result = ::GObject
|
190
|
+
result = ::GObject.g_value_get_string self
|
191
191
|
|
192
192
|
when Vips::REFSTR_TYPE
|
193
193
|
len = Vips::SizeStruct.new
|
194
|
-
result = ::Vips
|
194
|
+
result = ::Vips.vips_value_get_ref_string self, len
|
195
195
|
|
196
196
|
when Vips::ARRAY_INT_TYPE
|
197
197
|
len = Vips::IntStruct.new
|
198
|
-
array = Vips
|
198
|
+
array = Vips.vips_value_get_array_int self, len
|
199
199
|
result = array.get_array_of_int32 0, len[:value]
|
200
200
|
|
201
201
|
when Vips::ARRAY_DOUBLE_TYPE
|
202
202
|
len = Vips::IntStruct.new
|
203
|
-
array = Vips
|
203
|
+
array = Vips.vips_value_get_array_double self, len
|
204
204
|
result = array.get_array_of_double 0, len[:value]
|
205
205
|
|
206
206
|
when Vips::ARRAY_IMAGE_TYPE
|
207
207
|
len = Vips::IntStruct.new
|
208
|
-
array = Vips
|
208
|
+
array = Vips.vips_value_get_array_image self, len
|
209
209
|
result = array.get_array_of_pointer 0, len[:value]
|
210
210
|
result.map! do |pointer|
|
211
|
-
::GObject
|
211
|
+
::GObject.g_object_ref pointer
|
212
212
|
Vips::Image.new pointer
|
213
213
|
end
|
214
214
|
|
215
215
|
when Vips::BLOB_TYPE
|
216
216
|
len = Vips::SizeStruct.new
|
217
|
-
array = Vips
|
217
|
+
array = Vips.vips_value_get_blob self, len
|
218
218
|
result = array.get_bytes 0, len[:value]
|
219
219
|
|
220
220
|
else
|
221
221
|
case fundamental
|
222
222
|
when GFLAGS_TYPE
|
223
|
-
result = ::GObject
|
223
|
+
result = ::GObject.g_value_get_flags self
|
224
224
|
|
225
225
|
when GENUM_TYPE
|
226
|
-
enum_value = ::GObject
|
226
|
+
enum_value = ::GObject.g_value_get_enum(self)
|
227
227
|
result = GValue.to_nick self[:gtype], enum_value
|
228
228
|
|
229
229
|
when GOBJECT_TYPE
|
230
|
-
obj = ::GObject
|
230
|
+
obj = ::GObject.g_value_get_object self
|
231
231
|
# g_value_get_object() does not add a ref ... we need to add
|
232
232
|
# one to match the unref in gobject release
|
233
|
-
::GObject
|
233
|
+
::GObject.g_object_ref obj
|
234
234
|
result = Vips::Image.new obj
|
235
235
|
|
236
236
|
else
|
237
|
-
raise Vips::Error, "unimplemented gtype for get: "
|
238
|
-
|
237
|
+
raise Vips::Error, "unimplemented gtype for get: " \
|
238
|
+
"#{::GObject.g_type_name gtype} (#{gtype})"
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
@@ -243,15 +243,15 @@ module GObject
|
|
243
243
|
# "result = #{result.inspect[0..50]}"
|
244
244
|
# }
|
245
245
|
|
246
|
-
|
246
|
+
result
|
247
247
|
end
|
248
248
|
|
249
|
-
# Clear the thing held by a GValue.
|
249
|
+
# Clear the thing held by a GValue.
|
250
250
|
#
|
251
|
-
# This happens automatically when a GValue is GCed, but this method can be
|
251
|
+
# This happens automatically when a GValue is GCed, but this method can be
|
252
252
|
# handy if you need to drop a reference explicitly for some reason.
|
253
|
-
def unset
|
254
|
-
::GObject
|
253
|
+
def unset
|
254
|
+
::GObject.g_value_unset self
|
255
255
|
end
|
256
256
|
end
|
257
257
|
|
@@ -281,7 +281,7 @@ module GObject
|
|
281
281
|
|
282
282
|
# use :pointer rather than GObject.ptr to avoid casting later
|
283
283
|
attach_function :g_object_set_property,
|
284
|
-
|
284
|
+
[:pointer, :string, GValue.ptr], :void
|
285
285
|
attach_function :g_object_get_property,
|
286
|
-
|
286
|
+
[:pointer, :string, GValue.ptr], :void
|
287
287
|
end
|