ruby-vips 2.0.14 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/example/progress.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require "vips"
|
4
|
+
|
5
|
+
image = Vips::Image.black 1, 100000
|
6
|
+
image.set_progress true
|
7
|
+
|
8
|
+
def progress_to_s(name, progress)
|
9
|
+
puts "#{name}:"
|
10
|
+
puts " progress.run = #{progress[:run]}"
|
11
|
+
puts " progress.eta = #{progress[:eta]}"
|
12
|
+
puts " progress.tpels = #{progress[:tpels]}"
|
13
|
+
puts " progress.npels = #{progress[:npels]}"
|
14
|
+
puts " progress.percent = #{progress[:percent]}"
|
15
|
+
end
|
16
|
+
|
17
|
+
image.signal_connect :preeval do |progress|
|
18
|
+
progress_to_s("preeval", progress)
|
19
|
+
end
|
20
|
+
|
21
|
+
image.signal_connect :eval do |progress|
|
22
|
+
progress_to_s("eval", progress)
|
23
|
+
image.set_kill(true) if progress[:percent] > 50
|
24
|
+
end
|
25
|
+
|
26
|
+
image.signal_connect :posteval do |progress|
|
27
|
+
progress_to_s("posteval", progress)
|
28
|
+
end
|
29
|
+
|
30
|
+
image.avg
|
data/example/thumb.rb
CHANGED
@@ -1,31 +1,29 @@
|
|
1
|
-
#!/usr/bin/
|
1
|
+
#!/usr/bin/ruby
|
2
2
|
|
3
3
|
# batch-process a lot of files
|
4
4
|
#
|
5
5
|
# this should run in constant memory -- if it doesn't, something has broken
|
6
6
|
|
7
|
-
require
|
7
|
+
require "vips"
|
8
8
|
|
9
9
|
# benchmark thumbnail via a memory buffer
|
10
10
|
def via_memory(filename, thumbnail_width)
|
11
11
|
data = IO.binread(filename)
|
12
12
|
|
13
|
-
thumb = Vips::Image.thumbnail_buffer data, thumbnail_width, crop:
|
13
|
+
thumb = Vips::Image.thumbnail_buffer data, thumbnail_width, crop: "centre"
|
14
14
|
|
15
|
-
thumb.write_to_buffer
|
15
|
+
thumb.write_to_buffer ".jpg"
|
16
16
|
end
|
17
17
|
|
18
18
|
# benchmark thumbnail via files
|
19
19
|
def via_files(filename, thumbnail_width)
|
20
|
-
thumb = Vips::Image.thumbnail filename, thumbnail_width, crop:
|
20
|
+
thumb = Vips::Image.thumbnail filename, thumbnail_width, crop: "centre"
|
21
21
|
|
22
|
-
thumb.write_to_buffer
|
22
|
+
thumb.write_to_buffer ".jpg"
|
23
23
|
end
|
24
24
|
|
25
25
|
ARGV.each do |filename|
|
26
26
|
puts "processing #{filename} ..."
|
27
|
-
|
28
|
-
#
|
27
|
+
_thumb = via_memory(filename, 500)
|
28
|
+
# _thumb = via_files(filename, 500)
|
29
29
|
end
|
30
|
-
|
31
|
-
|
data/example/trim8.rb
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
# non-zero row or column is the object edge. We make the mask image with an
|
8
8
|
# amount-different-from-background image plus a threshold.
|
9
9
|
|
10
|
-
require
|
10
|
+
require "vips"
|
11
11
|
|
12
12
|
im = Vips::Image.new_from_file ARGV[0]
|
13
13
|
|
@@ -23,16 +23,16 @@ mask = (im.median - background).abs > 10
|
|
23
23
|
# direction
|
24
24
|
columns, rows = mask.project
|
25
25
|
|
26
|
-
|
26
|
+
_first_column, first_row = columns.profile
|
27
27
|
left = first_row.min
|
28
28
|
|
29
|
-
|
29
|
+
_first_column, first_row = columns.fliphor.profile
|
30
30
|
right = columns.width - first_row.min
|
31
31
|
|
32
|
-
first_column,
|
32
|
+
first_column, _first_row = rows.profile
|
33
33
|
top = first_column.min
|
34
34
|
|
35
|
-
first_column,
|
35
|
+
first_column, _first_row = rows.flipver.profile
|
36
36
|
bottom = rows.height - first_column.min
|
37
37
|
|
38
38
|
# and now crop the original image
|
data/example/watermark.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
-
require
|
3
|
+
require "vips"
|
4
4
|
|
5
5
|
im = Vips::Image.new_from_file ARGV[0], access: :sequential
|
6
6
|
|
7
7
|
# make the text mask
|
8
|
-
text = Vips::Image.text ARGV[2], width: 200, dpi: 200, font:
|
8
|
+
text = Vips::Image.text ARGV[2], width: 200, dpi: 200, font: "sans bold"
|
9
9
|
text = text.rotate(-45)
|
10
10
|
# make the text transparent
|
11
11
|
text = (text * 0.3).cast(:uchar)
|
data/example/wobble.rb
CHANGED
data/lib/ruby-vips.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require "vips"
|
data/lib/vips.rb
CHANGED
@@ -4,28 +4,45 @@
|
|
4
4
|
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
|
5
5
|
# License:: MIT
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require "ffi"
|
8
|
+
require "logger"
|
9
9
|
|
10
10
|
# This module uses FFI to make a simple layer over the glib and gobject
|
11
11
|
# libraries.
|
12
12
|
|
13
|
+
# Generate a library name for ffi.
|
14
|
+
#
|
15
|
+
# Platform notes:
|
16
|
+
# linux:
|
17
|
+
# Some distros allow "libvips.so", but only if the -dev headers have been
|
18
|
+
# installed. To work everywhere, you must include the ABI number.
|
19
|
+
# Confusingly, the file extension is not at the end. ffi adds the "lib"
|
20
|
+
# prefix.
|
21
|
+
# mac:
|
22
|
+
# As linux, but the extension is at the end and is added by ffi.
|
23
|
+
# windows:
|
24
|
+
# The ABI number must be included, but with a hyphen. ffi does not add a
|
25
|
+
# "lib" prefix or a ".dll" suffix.
|
26
|
+
def library_name(name, abi_number)
|
27
|
+
if FFI::Platform.windows?
|
28
|
+
"lib#{name}-#{abi_number}.dll"
|
29
|
+
elsif FFI::Platform.mac?
|
30
|
+
"#{name}.#{abi_number}"
|
31
|
+
else
|
32
|
+
"#{name}.so.#{abi_number}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
13
36
|
module GLib
|
14
37
|
class << self
|
15
38
|
attr_accessor :logger
|
16
39
|
end
|
17
|
-
@logger = Logger.new(
|
40
|
+
@logger = Logger.new($stdout)
|
18
41
|
@logger.level = Logger::WARN
|
19
42
|
|
20
43
|
extend FFI::Library
|
21
44
|
|
22
|
-
|
23
|
-
glib_libname = 'libglib-2.0-0.dll'
|
24
|
-
else
|
25
|
-
glib_libname = 'glib-2.0'
|
26
|
-
end
|
27
|
-
|
28
|
-
ffi_lib glib_libname
|
45
|
+
ffi_lib library_name("glib-2.0", 0)
|
29
46
|
|
30
47
|
attach_function :g_malloc, [:size_t], :pointer
|
31
48
|
|
@@ -35,29 +52,29 @@ module GLib
|
|
35
52
|
|
36
53
|
callback :g_log_func, [:string, :int, :string, :pointer], :void
|
37
54
|
attach_function :g_log_set_handler,
|
38
|
-
|
55
|
+
[:string, :int, :g_log_func, :pointer], :int
|
39
56
|
attach_function :g_log_remove_handler, [:string, :int], :void
|
40
57
|
|
41
58
|
# log flags
|
42
|
-
LOG_FLAG_RECURSION
|
43
|
-
LOG_FLAG_FATAL
|
59
|
+
LOG_FLAG_RECURSION = 1 << 0
|
60
|
+
LOG_FLAG_FATAL = 1 << 1
|
44
61
|
|
45
62
|
# GLib log levels
|
46
|
-
LOG_LEVEL_ERROR
|
47
|
-
LOG_LEVEL_CRITICAL
|
48
|
-
LOG_LEVEL_WARNING
|
49
|
-
LOG_LEVEL_MESSAGE
|
50
|
-
LOG_LEVEL_INFO
|
51
|
-
LOG_LEVEL_DEBUG
|
63
|
+
LOG_LEVEL_ERROR = 1 << 2 # always fatal
|
64
|
+
LOG_LEVEL_CRITICAL = 1 << 3
|
65
|
+
LOG_LEVEL_WARNING = 1 << 4
|
66
|
+
LOG_LEVEL_MESSAGE = 1 << 5
|
67
|
+
LOG_LEVEL_INFO = 1 << 6
|
68
|
+
LOG_LEVEL_DEBUG = 1 << 7
|
52
69
|
|
53
70
|
# map glib levels to Logger::Severity
|
54
71
|
GLIB_TO_SEVERITY = {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
72
|
+
LOG_LEVEL_ERROR => Logger::ERROR,
|
73
|
+
LOG_LEVEL_CRITICAL => Logger::FATAL,
|
74
|
+
LOG_LEVEL_WARNING => Logger::WARN,
|
75
|
+
LOG_LEVEL_MESSAGE => Logger::UNKNOWN,
|
76
|
+
LOG_LEVEL_INFO => Logger::INFO,
|
77
|
+
LOG_LEVEL_DEBUG => Logger::DEBUG
|
61
78
|
}
|
62
79
|
GLIB_TO_SEVERITY.default = Logger::UNKNOWN
|
63
80
|
|
@@ -66,9 +83,9 @@ module GLib
|
|
66
83
|
@glib_log_handler_id = 0
|
67
84
|
|
68
85
|
# module-level, so it's not GCd away
|
69
|
-
LOG_HANDLER =
|
86
|
+
LOG_HANDLER = proc { |domain, level, message, _user_data|
|
70
87
|
@logger.log(GLIB_TO_SEVERITY[level], message, domain)
|
71
|
-
|
88
|
+
}
|
72
89
|
|
73
90
|
def self.remove_log_handler
|
74
91
|
if @glib_log_handler_id != 0 && @glib_log_domain
|
@@ -78,7 +95,7 @@ module GLib
|
|
78
95
|
end
|
79
96
|
|
80
97
|
def self.set_log_domain domain
|
81
|
-
GLib
|
98
|
+
GLib.remove_log_handler
|
82
99
|
|
83
100
|
@glib_log_domain = domain
|
84
101
|
|
@@ -108,24 +125,16 @@ module GLib
|
|
108
125
|
# on shutdown and we don't want LOG_HANDLER to be invoked
|
109
126
|
# after Ruby has gone
|
110
127
|
at_exit {
|
111
|
-
GLib
|
128
|
+
GLib.remove_log_handler
|
112
129
|
}
|
113
130
|
end
|
114
|
-
|
115
131
|
end
|
116
|
-
|
117
132
|
end
|
118
133
|
|
119
134
|
module GObject
|
120
135
|
extend FFI::Library
|
121
136
|
|
122
|
-
|
123
|
-
gobject_libname = 'libgobject-2.0-0.dll'
|
124
|
-
else
|
125
|
-
gobject_libname = 'gobject-2.0'
|
126
|
-
end
|
127
|
-
|
128
|
-
ffi_lib gobject_libname
|
137
|
+
ffi_lib library_name("gobject-2.0", 0)
|
129
138
|
|
130
139
|
# we can't just use ulong, windows has different int sizing rules
|
131
140
|
if FFI::Platform::ADDRESS_SIZE == 64
|
@@ -151,14 +160,13 @@ module GObject
|
|
151
160
|
GFLAGS_TYPE = g_type_from_name "GFlags"
|
152
161
|
GSTR_TYPE = g_type_from_name "gchararray"
|
153
162
|
GOBJECT_TYPE = g_type_from_name "GObject"
|
154
|
-
|
155
163
|
end
|
156
164
|
|
157
|
-
require
|
158
|
-
require
|
165
|
+
require "vips/gobject"
|
166
|
+
require "vips/gvalue"
|
159
167
|
|
160
168
|
# This module provides a binding for the [libvips image processing
|
161
|
-
# library](https://
|
169
|
+
# library](https://libvips.github.io/libvips/).
|
162
170
|
#
|
163
171
|
# # Example
|
164
172
|
#
|
@@ -200,9 +208,10 @@ require 'vips/gvalue'
|
|
200
208
|
# for full details
|
201
209
|
# on the various modes available.
|
202
210
|
#
|
203
|
-
# You can also load formatted images from
|
204
|
-
#
|
205
|
-
# from
|
211
|
+
# You can also load formatted images from memory buffers, create images that
|
212
|
+
# wrap C-style memory arrays, or make images from constants. Use {Source}
|
213
|
+
# and {Image.new_from_source} to load images from any data source, for
|
214
|
+
# example URIs.
|
206
215
|
#
|
207
216
|
# The next line:
|
208
217
|
#
|
@@ -245,6 +254,9 @@ require 'vips/gvalue'
|
|
245
254
|
# suffix. You can also write formatted images to memory buffers, or dump
|
246
255
|
# image data to a raw memory array.
|
247
256
|
#
|
257
|
+
# Use {Target} and {Image#write_to_target} to write formatted images to
|
258
|
+
# any data sink, for example URIs.
|
259
|
+
#
|
248
260
|
# # How it works
|
249
261
|
#
|
250
262
|
# The binding uses [ruby-ffi](https://github.com/ffi/ffi) to open the libvips
|
@@ -385,7 +397,7 @@ require 'vips/gvalue'
|
|
385
397
|
#
|
386
398
|
# https://developer.gnome.org/glib/stable/glib-Message-Logging.html
|
387
399
|
#
|
388
|
-
# You can disable
|
400
|
+
# You can disable warnings by defining the `VIPS_WARNING` environment variable.
|
389
401
|
# You can enable info output by defining `VIPS_INFO`.
|
390
402
|
#
|
391
403
|
# # Exceptions
|
@@ -395,36 +407,132 @@ require 'vips/gvalue'
|
|
395
407
|
#
|
396
408
|
# # Automatic YARD documentation
|
397
409
|
#
|
398
|
-
# The bulk of these API docs are generated automatically by
|
399
|
-
#
|
400
|
-
#
|
401
|
-
# that that operation expects.
|
410
|
+
# The bulk of these API docs are generated automatically by {Yard#generate}.
|
411
|
+
# It examines libvips and writes a summary of each operation and the arguments
|
412
|
+
# and options that that operation expects.
|
402
413
|
#
|
403
|
-
# Use the [C API
|
404
|
-
# docs](https://jcupitt.github.io/libvips/API/current)
|
414
|
+
# Use the [C API # docs](https://libvips.github.io/libvips/API/current)
|
405
415
|
# for more detail.
|
406
416
|
#
|
407
417
|
# # Enums
|
408
418
|
#
|
409
419
|
# The libvips enums, such as `VipsBandFormat` appear in ruby-vips as Symbols
|
410
420
|
# like `:uchar`. They are documented as a set of classes for convenience, see
|
411
|
-
#
|
421
|
+
# {Vips::BandFormat}, for example.
|
412
422
|
#
|
413
423
|
# # Draw operations
|
414
424
|
#
|
415
|
-
#
|
416
|
-
#
|
417
|
-
#
|
418
|
-
#
|
425
|
+
# There are two ways of calling the libvips draw operations, like
|
426
|
+
# {Image#draw_circle} and {Image#draw_line}.
|
427
|
+
#
|
428
|
+
# First, you can use them like functions. For example:
|
429
|
+
#
|
430
|
+
# ```ruby
|
431
|
+
# y = x.draw_line 255, 0, 0, x.width, x.height
|
432
|
+
# ```
|
433
|
+
#
|
434
|
+
# This will make a new image, `y`, which is a copy of `x` but with a line
|
435
|
+
# drawn across it. `x` is unchanged.
|
436
|
+
#
|
437
|
+
# This is simple, but will be slow if you want to draw many lines, since
|
438
|
+
# ruby-vips will make a copy of the whole image each time.
|
439
|
+
#
|
440
|
+
# You can use {Image#mutate} to make a {MutableImage}. This is an image which
|
441
|
+
# is unshared and is only available inside the {Image#mutate} block. Within
|
442
|
+
# this block, you can use `!` versions of the draw operations to modify images
|
443
|
+
# and avoid the copy. For example:
|
444
|
+
#
|
445
|
+
# ```ruby
|
446
|
+
# image = image.mutate do |mutable|
|
447
|
+
# (0 ... 1).step(0.01) do |i|
|
448
|
+
# mutable.draw_line! 255, mutable.width * i, 0, 0, mutable.height * (1 - i)
|
449
|
+
# end
|
450
|
+
# end
|
451
|
+
# ```
|
452
|
+
#
|
453
|
+
# Now each {Image#draw_line} will directly modify the mutable image, saving
|
454
|
+
# the copy. This is much faster and needs much less memory.
|
455
|
+
#
|
456
|
+
# # Metadata read
|
457
|
+
#
|
458
|
+
# Use {Image#get_fields} to get a list of the metadata fields that an image
|
459
|
+
# supports. ICC profiles, for example, are in a field called
|
460
|
+
# `icc-profile-data`. Use `vipsheader -a something.jpg` at the command-line
|
461
|
+
# to see all the fields on an image.
|
462
|
+
#
|
463
|
+
# Use {Image#get_typeof} to get the type of a field. Types are integers, with
|
464
|
+
# 0 meaning "no such field". Constants like {GObject::GINT_TYPE} are useful for
|
465
|
+
# testing field types.
|
419
466
|
#
|
420
|
-
#
|
421
|
-
#
|
422
|
-
# make it inefficient. If you draw 100 lines on an image, for example, you'll
|
423
|
-
# copy the image 100 times. The wrapper does make sure that memory is recycled
|
424
|
-
# where possible, so you won't have 100 copies in memory.
|
467
|
+
# You can read image metadata using {Image#get}. The field value is converted
|
468
|
+
# to a Ruby value in the obvious way.
|
425
469
|
#
|
426
|
-
#
|
427
|
-
#
|
470
|
+
# # Metadata write
|
471
|
+
#
|
472
|
+
# You can also set and remove image metadata fields. Images are immutable, so
|
473
|
+
# you must make any changes inside a {Image#mutate} block. For example:
|
474
|
+
#
|
475
|
+
# ```ruby
|
476
|
+
# image = image.mutate do |mutable|
|
477
|
+
# image.get_fields.each do |field|
|
478
|
+
# mutable.remove! field unless field == "icc-profile-data"
|
479
|
+
# end
|
480
|
+
# end
|
481
|
+
# ```
|
482
|
+
#
|
483
|
+
# To remove all metadata except the icc profile.
|
484
|
+
#
|
485
|
+
# You can use {MutableImage#set!} to change the value of an existing field,
|
486
|
+
# and {MutableImage#set_type!} to create a new field with a specified type.
|
487
|
+
#
|
488
|
+
# # Progress
|
489
|
+
#
|
490
|
+
# You can attach signal handlers to images to watch computation progress. For
|
491
|
+
# example:
|
492
|
+
#
|
493
|
+
# ```ruby
|
494
|
+
# image = Vips::Image.black 1, 100000
|
495
|
+
# image.set_progress true
|
496
|
+
#
|
497
|
+
# def progress_to_s(name, progress)
|
498
|
+
# puts "#{name}:"
|
499
|
+
# puts " run = #{progress[:run]}"
|
500
|
+
# puts " eta = #{progress[:eta]}"
|
501
|
+
# puts " tpels = #{progress[:tpels]}"
|
502
|
+
# puts " npels = #{progress[:npels]}"
|
503
|
+
# puts " percent = #{progress[:percent]}"
|
504
|
+
# end
|
505
|
+
#
|
506
|
+
# image.signal_connect :preeval do |progress|
|
507
|
+
# progress_to_s("preeval", progress)
|
508
|
+
# end
|
509
|
+
#
|
510
|
+
# image.signal_connect :eval do |progress|
|
511
|
+
# progress_to_s("eval", progress)
|
512
|
+
# image.set_kill(true) if progress[:percent] > 50
|
513
|
+
# end
|
514
|
+
#
|
515
|
+
# image.signal_connect :posteval do |progress|
|
516
|
+
# progress_to_s("posteval", progress)
|
517
|
+
# end
|
518
|
+
#
|
519
|
+
# image.avg
|
520
|
+
# ```
|
521
|
+
#
|
522
|
+
# The `:eval` signal will fire for every tile that is processed. You can stop
|
523
|
+
# progress with {Image#set_kill} and processing will end with an exception.
|
524
|
+
#
|
525
|
+
# User streams
|
526
|
+
#
|
527
|
+
# You can make your own input and output stream objects with {SourceCustom} and
|
528
|
+
# {TargetCustom}. For example:
|
529
|
+
#
|
530
|
+
# ```ruby
|
531
|
+
# file = File.open "some/file", "rb"
|
532
|
+
# source = Vips::SourceCustom.new
|
533
|
+
# source.on_read { |length| file.read length }
|
534
|
+
# image = Vips::Image.new_from_source source, "", access: "sequential"
|
535
|
+
# ```
|
428
536
|
#
|
429
537
|
# # Overloads
|
430
538
|
#
|
@@ -462,16 +570,10 @@ require 'vips/gvalue'
|
|
462
570
|
module Vips
|
463
571
|
extend FFI::Library
|
464
572
|
|
465
|
-
|
466
|
-
vips_libname = 'libvips-42.dll'
|
467
|
-
else
|
468
|
-
vips_libname = 'vips'
|
469
|
-
end
|
470
|
-
|
471
|
-
ffi_lib vips_libname
|
573
|
+
ffi_lib library_name("vips", 42)
|
472
574
|
|
473
575
|
LOG_DOMAIN = "VIPS"
|
474
|
-
GLib
|
576
|
+
GLib.set_log_domain LOG_DOMAIN
|
475
577
|
|
476
578
|
typedef :ulong, :GType
|
477
579
|
|
@@ -485,9 +587,9 @@ module Vips
|
|
485
587
|
def initialize msg = nil
|
486
588
|
if msg
|
487
589
|
@details = msg
|
488
|
-
elsif Vips
|
489
|
-
@details = Vips
|
490
|
-
Vips
|
590
|
+
elsif Vips.vips_error_buffer != ""
|
591
|
+
@details = Vips.vips_error_buffer
|
592
|
+
Vips.vips_error_clear
|
491
593
|
else
|
492
594
|
@details = nil
|
493
595
|
end
|
@@ -497,7 +599,7 @@ module Vips
|
|
497
599
|
#
|
498
600
|
# @return [String] The error message
|
499
601
|
def to_s
|
500
|
-
if
|
602
|
+
if !@details.nil?
|
501
603
|
@details
|
502
604
|
else
|
503
605
|
super.to_s
|
@@ -507,8 +609,8 @@ module Vips
|
|
507
609
|
|
508
610
|
attach_function :vips_init, [:string], :int
|
509
611
|
|
510
|
-
if Vips
|
511
|
-
throw Vips
|
612
|
+
if Vips.vips_init($0) != 0
|
613
|
+
throw Vips.get_error
|
512
614
|
end
|
513
615
|
|
514
616
|
# don't use at_exit to call vips_shutdown, it causes problems with fork, and
|
@@ -528,7 +630,7 @@ module Vips
|
|
528
630
|
# Turn libvips leak testing on and off. Handy for debugging ruby-vips, not
|
529
631
|
# very useful for user code.
|
530
632
|
def self.leak_set leak
|
531
|
-
vips_leak_set
|
633
|
+
vips_leak_set((leak ? 1 : 0))
|
532
634
|
end
|
533
635
|
|
534
636
|
attach_function :vips_cache_set_max, [:int], :void
|
@@ -572,7 +674,7 @@ module Vips
|
|
572
674
|
# Don't use this, instead change GLib::logger.level.
|
573
675
|
def self.set_debug debug
|
574
676
|
if debug
|
575
|
-
GLib
|
677
|
+
GLib.logger.level = Logger::DEBUG
|
576
678
|
end
|
577
679
|
end
|
578
680
|
|
@@ -594,33 +696,37 @@ module Vips
|
|
594
696
|
# vips_foreign_get_suffixes() was added in libvips 8.8
|
595
697
|
return [] unless Vips.respond_to? :vips_foreign_get_suffixes
|
596
698
|
|
597
|
-
array = Vips
|
699
|
+
array = Vips.vips_foreign_get_suffixes
|
598
700
|
|
599
701
|
names = []
|
600
702
|
p = array
|
601
703
|
until (q = p.read_pointer).null?
|
602
704
|
suff = q.read_string
|
603
|
-
GLib
|
705
|
+
GLib.g_free q
|
604
706
|
names << suff unless names.include? suff
|
605
707
|
p += FFI::Type::POINTER.size
|
606
708
|
end
|
607
|
-
GLib
|
709
|
+
GLib.g_free array
|
608
710
|
|
609
711
|
names
|
610
712
|
end
|
611
713
|
|
612
|
-
LIBRARY_VERSION = Vips
|
714
|
+
LIBRARY_VERSION = Vips.version_string
|
613
715
|
|
614
716
|
# libvips has this arbitrary number as a sanity-check upper bound on image
|
615
|
-
# size. It's sometimes useful
|
717
|
+
# size. It's sometimes useful to know when calculating scale factors.
|
616
718
|
MAX_COORD = 10000000
|
617
|
-
|
618
719
|
end
|
619
720
|
|
620
|
-
require
|
621
|
-
require
|
622
|
-
require
|
623
|
-
require
|
624
|
-
require
|
625
|
-
|
626
|
-
|
721
|
+
require "vips/object"
|
722
|
+
require "vips/operation"
|
723
|
+
require "vips/image"
|
724
|
+
require "vips/mutableimage"
|
725
|
+
require "vips/interpolate"
|
726
|
+
require "vips/region"
|
727
|
+
require "vips/version"
|
728
|
+
require "vips/connection"
|
729
|
+
require "vips/source"
|
730
|
+
require "vips/sourcecustom"
|
731
|
+
require "vips/target"
|
732
|
+
require "vips/targetcustom"
|