Skip to content

Commit 4bef010

Browse files
committed
improve gflags argument handling
1 parent 726357f commit 4bef010

File tree

5 files changed

+68
-8
lines changed

5 files changed

+68
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## master
44

55
* improve NULL pointer handling [dloebl]
6+
* improve GFlags argument handling [jcupitt]
67

78
## Version 2.2.4 (2025-06-05)
89

lib/vips/gvalue.rb

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class GValue < FFI::ManagedStruct
2525
:data, [:ulong_long, 2]
2626

2727
# convert an enum value (str/symb/int) into an int ready for libvips
28-
def self.from_nick(gtype, value)
28+
def self.enum_from_nick(gtype, value)
2929
value = value.to_s if value.is_a? Symbol
3030

3131
if value.is_a? String
@@ -40,6 +40,34 @@ def self.from_nick(gtype, value)
4040
value
4141
end
4242

43+
# convert an flags value (array[str/symb/int] | str/symb/int) into an
44+
# int ready for libvips
45+
def self.flags_from_nick(gtype, value)
46+
if value.is_a? String
47+
# libvips will parse strings like "sub|up" etc.
48+
name = value.tr("_", "-")
49+
value = Vips.vips_flags_from_nick "ruby-vips", gtype, name
50+
else
51+
value = [value] if !value.is_a? Array
52+
53+
# convert each item to a set of bits, OR them together
54+
result = 0
55+
value.map do |item|
56+
item = item.to_s if item.is_a? Symbol
57+
if item.is_a? String
58+
name = item.tr("_", "-")
59+
item = Vips.vips_flags_from_nick "ruby-vips", gtype, name
60+
end
61+
62+
result |= item
63+
end
64+
65+
value = result
66+
end
67+
68+
value
69+
end
70+
4371
# convert an int enum back into a symbol
4472
def self.to_nick(gtype, enum_value)
4573
enum_name = Vips.vips_enum_nick gtype, enum_value
@@ -148,10 +176,11 @@ def set value
148176
else
149177
case fundamental
150178
when GFLAGS_TYPE
151-
::GObject.g_value_set_flags self, value
179+
flags_value = GValue.flags_from_nick(self[:gtype], value)
180+
::GObject.g_value_set_flags self, flags_value
152181

153182
when GENUM_TYPE
154-
enum_value = GValue.from_nick(self[:gtype], value)
183+
enum_value = GValue.enum_from_nick(self[:gtype], value)
155184
::GObject.g_value_set_enum self, enum_value
156185

157186
when GOBJECT_TYPE

lib/vips/image.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,12 @@ def self.smap x, &block
114114
end
115115

116116
def self.complex? format
117-
format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
117+
format_number = GObject::GValue.enum_from_nick BAND_FORMAT_TYPE, format
118118
Vips.vips_band_format_iscomplex(format_number) != 0
119119
end
120120

121121
def self.float? format
122-
format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
122+
format_number = GObject::GValue.enum_from_nick BAND_FORMAT_TYPE, format
123123
Vips.vips_band_format_isfloat(format_number) != 0
124124
end
125125

@@ -380,7 +380,7 @@ def self.new_from_memory data, width, height, bands, format
380380
size = data.bytesize
381381
end
382382

383-
format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
383+
format_number = GObject::GValue.enum_from_nick BAND_FORMAT_TYPE, format
384384
vi = Vips.vips_image_new_from_memory data, size,
385385
width, height, bands, format_number
386386
raise Vips::Error if vi.null?
@@ -405,7 +405,7 @@ def self.new_from_memory data, width, height, bands, format
405405
# @param format [Symbol] band format
406406
# @return [Image] the loaded image
407407
def self.new_from_memory_copy data, width, height, bands, format
408-
format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
408+
format_number = GObject::GValue.enum_from_nick BAND_FORMAT_TYPE, format
409409

410410
if data.is_a?(FFI::Pointer)
411411
if data.size == UNKNOWN_POINTER_SIZE
@@ -1319,7 +1319,7 @@ def composite overlay, mode, **opts
13191319
end
13201320

13211321
mode = mode.map do |x|
1322-
GObject::GValue.from_nick Vips::BLEND_MODE_TYPE, x
1322+
GObject::GValue.enum_from_nick Vips::BLEND_MODE_TYPE, x
13231323
end
13241324

13251325
Vips::Image.composite([self] + overlay, mode, **opts)

lib/vips/object.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class Progress < FFI::Struct
125125

126126
attach_function :vips_enum_from_nick, [:string, :GType, :string], :int
127127
attach_function :vips_enum_nick, [:GType, :int], :string
128+
attach_function :vips_flags_from_nick, [:string, :GType, :string], :int
128129

129130
attach_function :vips_value_set_ref_string,
130131
[GObject::GValue.ptr, :string], :void

spec/vips_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,35 @@
166166
expect(rot.bands).to eq(1)
167167
end
168168

169+
it "can handle symbol flag arguments" do
170+
black = Vips::Operation.call "black", [200, 200]
171+
bytes = Vips::Operation.call "pngsave_buffer", [black], keep: :icc
172+
173+
expect(bytes.length).to be > 100
174+
end
175+
176+
it "can handle int flag arguments" do
177+
black = Vips::Operation.call "black", [200, 200]
178+
bytes = Vips::Operation.call "pngsave_buffer", [black], keep: 1 << 3
179+
180+
expect(bytes.length).to be > 100
181+
end
182+
183+
it "can handle string flag arguments" do
184+
black = Vips::Operation.call "black", [200, 200]
185+
bytes = Vips::Operation.call "pngsave_buffer", [black], keep: "icc"
186+
187+
expect(bytes.length).to be > 100
188+
end
189+
190+
it "can handle array flag arguments" do
191+
black = Vips::Operation.call "black", [200, 200]
192+
bytes = Vips::Operation.call "pngsave_buffer", [black],
193+
keep: [:icc, :xmp]
194+
195+
expect(bytes.length).to be > 100
196+
end
197+
169198
it "can return optional output args" do
170199
point = Vips::Operation.call "black", [1, 1]
171200
test = Vips::Operation.call "embed", [point, 20, 10, 100, 100],

0 commit comments

Comments
 (0)