ruby-vips 2.0.13 → 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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
  3. data/.github/workflows/test.yml +80 -0
  4. data/.standard.yml +17 -0
  5. data/.yardopts +0 -1
  6. data/CHANGELOG.md +44 -0
  7. data/Gemfile +3 -1
  8. data/README.md +45 -47
  9. data/Rakefile +13 -15
  10. data/TODO +19 -10
  11. data/VERSION +1 -1
  12. data/example/annotate.rb +7 -7
  13. data/example/connection.rb +26 -0
  14. data/example/daltonize8.rb +27 -29
  15. data/example/draw_lines.rb +30 -0
  16. data/example/example1.rb +5 -6
  17. data/example/example2.rb +11 -11
  18. data/example/example3.rb +9 -9
  19. data/example/example4.rb +8 -8
  20. data/example/example5.rb +8 -9
  21. data/example/inheritance_with_refcount.rb +203 -221
  22. data/example/progress.rb +30 -0
  23. data/example/thumb.rb +12 -14
  24. data/example/trim8.rb +7 -7
  25. data/example/watermark.rb +15 -36
  26. data/example/wobble.rb +25 -25
  27. data/lib/ruby-vips.rb +1 -1
  28. data/lib/vips.rb +473 -338
  29. data/lib/vips/access.rb +9 -9
  30. data/lib/vips/align.rb +7 -8
  31. data/lib/vips/angle.rb +8 -9
  32. data/lib/vips/angle45.rb +12 -13
  33. data/lib/vips/bandformat.rb +16 -18
  34. data/lib/vips/blend_mode.rb +36 -0
  35. data/lib/vips/coding.rb +11 -12
  36. data/lib/vips/compass_direction.rb +13 -14
  37. data/lib/vips/connection.rb +46 -0
  38. data/lib/vips/direction.rb +7 -8
  39. data/lib/vips/extend.rb +13 -14
  40. data/lib/vips/gobject.rb +111 -100
  41. data/lib/vips/gvalue.rb +243 -237
  42. data/lib/vips/image.rb +1501 -1338
  43. data/lib/vips/interesting.rb +10 -11
  44. data/lib/vips/interpolate.rb +50 -54
  45. data/lib/vips/interpretation.rb +25 -26
  46. data/lib/vips/kernel.rb +18 -19
  47. data/lib/vips/methods.rb +929 -309
  48. data/lib/vips/mutableimage.rb +154 -0
  49. data/lib/vips/object.rb +318 -208
  50. data/lib/vips/operation.rb +467 -320
  51. data/lib/vips/operationboolean.rb +10 -11
  52. data/lib/vips/operationcomplex.rb +8 -9
  53. data/lib/vips/operationcomplex2.rb +6 -7
  54. data/lib/vips/operationcomplexget.rb +7 -8
  55. data/lib/vips/operationmath.rb +14 -15
  56. data/lib/vips/operationmath2.rb +6 -7
  57. data/lib/vips/operationrelational.rb +11 -12
  58. data/lib/vips/operationround.rb +7 -8
  59. data/lib/vips/region.rb +73 -0
  60. data/lib/vips/size.rb +9 -10
  61. data/lib/vips/source.rb +88 -0
  62. data/lib/vips/sourcecustom.rb +89 -0
  63. data/lib/vips/target.rb +86 -0
  64. data/lib/vips/targetcustom.rb +77 -0
  65. data/lib/vips/version.rb +1 -2
  66. data/ruby-vips.gemspec +29 -20
  67. metadata +51 -40
  68. data/.travis.yml +0 -55
  69. data/install-vips.sh +0 -26
data/lib/vips/access.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  module Vips
2
- # The type of access an operation has to supply.
3
- #
4
- # * `:random` means requests can come in any order.
5
- #
6
- # * `:sequential` means requests will be top-to-bottom, but with some
7
- # amount of buffering behind the read point for small non-local
8
- # accesses.
9
- class Access < Symbol
10
- end
2
+ # The type of access an operation has to supply.
3
+ #
4
+ # * `:random` means requests can come in any order.
5
+ #
6
+ # * `:sequential` means requests will be top-to-bottom, but with some
7
+ # amount of buffering behind the read point for small non-local
8
+ # accesses.
9
+ class Access < Symbol
10
+ end
11
11
  end
data/lib/vips/align.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  module Vips
2
+ # Various types of alignment. See {Image#join}, for example.
3
+ #
4
+ # * `:low` Align on the low coordinate edge
5
+ # * `:centre` Align on the centre
6
+ # * `:high` Align on the high coordinate edge
2
7
 
3
- # Various types of alignment. See {Image#join}, for example.
4
- #
5
- # * `:low` Align on the low coordinate edge
6
- # * `:centre` Align on the centre
7
- # * `:high` Align on the high coordinate edge
8
-
9
- class Align < Symbol
10
- end
8
+ class Align < Symbol
9
+ end
11
10
  end
data/lib/vips/angle.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  module Vips
2
+ # Various fixed 90 degree rotation angles. See {Image#rot}.
3
+ #
4
+ # * `:d0` no rotate
5
+ # * `:d90` 90 degrees clockwise
6
+ # * `:d180` 180 degrees
7
+ # * `:d270` 90 degrees anti-clockwise
2
8
 
3
- # Various fixed 90 degree rotation angles. See {Image#rot}.
4
- #
5
- # * `:d0` no rotate
6
- # * `:d90` 90 degrees clockwise
7
- # * `:d180` 180 degrees
8
- # * `:d270` 90 degrees anti-clockwise
9
-
10
- class Angle < Symbol
11
- end
9
+ class Angle < Symbol
10
+ end
12
11
  end
data/lib/vips/angle45.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  module Vips
2
+ # Various fixed 45 degree rotation angles. See {Image#rot45}.
3
+ #
4
+ # * `:d0` no rotate
5
+ # * `:d45` 45 degrees clockwise
6
+ # * `:d90` 90 degrees clockwise
7
+ # * `:d135` 135 degrees clockwise
8
+ # * `:d180` 180 degrees
9
+ # * `:d225` 135 degrees anti-clockwise
10
+ # * `:d270` 90 degrees anti-clockwise
11
+ # * `:d315` 45 degrees anti-clockwise
2
12
 
3
- # Various fixed 45 degree rotation angles. See {Image#rot45}.
4
- #
5
- # * `:d0` no rotate
6
- # * `:d45` 45 degrees clockwise
7
- # * `:d90` 90 degrees clockwise
8
- # * `:d135` 135 degrees clockwise
9
- # * `:d180` 180 degrees
10
- # * `:d225` 135 degrees anti-clockwise
11
- # * `:d270` 90 degrees anti-clockwise
12
- # * `:d315` 45 degrees anti-clockwise
13
-
14
- class Angle45 < Symbol
15
- end
13
+ class Angle45 < Symbol
14
+ end
16
15
  end
@@ -1,20 +1,18 @@
1
1
  module Vips
2
-
3
- # The format used for each band element. Each corresponds to a native C type
4
- # for the current machine.
5
- #
6
- # * `:notset` invalid setting
7
- # * `:uchar` unsigned char format
8
- # * `:char` char format
9
- # * `:ushort` unsigned short format
10
- # * `:short` short format
11
- # * `:uint` unsigned int format
12
- # * `:int` int format
13
- # * `:float` float format
14
- # * `:complex` complex (two floats) format
15
- # * `:double` double float format
16
- # * `:dpcomplex` double complex (two double) format
17
- class BandFormat < Symbol
18
- end
19
-
2
+ # The format used for each band element. Each corresponds to a native C type
3
+ # for the current machine.
4
+ #
5
+ # * `:notset` invalid setting
6
+ # * `:uchar` unsigned char format
7
+ # * `:char` char format
8
+ # * `:ushort` unsigned short format
9
+ # * `:short` short format
10
+ # * `:uint` unsigned int format
11
+ # * `:int` int format
12
+ # * `:float` float format
13
+ # * `:complex` complex (two floats) format
14
+ # * `:double` double float format
15
+ # * `:dpcomplex` double complex (two double) format
16
+ class BandFormat < Symbol
17
+ end
20
18
  end
@@ -0,0 +1,36 @@
1
+ module Vips
2
+ # Blend mode to use when compositing images. See {Image#composite}.
3
+ #
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
33
+
34
+ class BlendMode < Symbol
35
+ end
36
+ end
data/lib/vips/coding.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  module Vips
2
-
3
- # How pixels are coded.
4
- #
5
- # Normally, pixels are uncoded and can be manipulated as you would expect.
6
- # However some file formats code pixels for compression, and sometimes it's
7
- # useful to be able to manipulate images in the coded format.
8
- #
9
- # * `:none` pixels are not coded
10
- # * `:labq` pixels encode 3 float CIELAB values as 4 uchar
11
- # * `:rad` pixels encode 3 float RGB as 4 uchar (Radiance coding)
12
- class Coding < Symbol
13
- end
2
+ # How pixels are coded.
3
+ #
4
+ # Normally, pixels are uncoded and can be manipulated as you would expect.
5
+ # However some file formats code pixels for compression, and sometimes it's
6
+ # useful to be able to manipulate images in the coded format.
7
+ #
8
+ # * `:none` pixels are not coded
9
+ # * `:labq` pixels encode 3 float CIELAB values as 4 uchar
10
+ # * `:rad` pixels encode 3 float RGB as 4 uchar (Radiance coding)
11
+ class Coding < Symbol
12
+ end
14
13
  end
@@ -1,17 +1,16 @@
1
1
  module Vips
2
+ # A direction on a compass used for placing images. See {Image#gravity}.
3
+ #
4
+ # * `:centre`
5
+ # * `:north`
6
+ # * `:east`
7
+ # * `:south`
8
+ # * `:west`
9
+ # * `:"north-east"`
10
+ # * `:"south-east"`
11
+ # * `:"south-west"`
12
+ # * `:"north-west"`
2
13
 
3
- # A direction on a compass used for placing images. See {Image#gravity}.
4
- #
5
- # * `:centre`
6
- # * `:north`
7
- # * `:east`
8
- # * `:south`
9
- # * `:west`
10
- # * `:north-east`
11
- # * `"south-east`
12
- # * `:south-west`
13
- # * `:north-west`
14
-
15
- class CompassDirection < Symbol
16
- end
14
+ class CompassDirection < Symbol
15
+ end
17
16
  end
@@ -0,0 +1,46 @@
1
+ # This module provides an interface to the top level bits of libvips
2
+ # via ruby-ffi.
3
+ #
4
+ # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
+ # License:: MIT
6
+
7
+ require "ffi"
8
+
9
+ module Vips
10
+ if Vips.at_least_libvips?(8, 9)
11
+ attach_function :vips_connection_filename, [:pointer], :string
12
+ attach_function :vips_connection_nick, [:pointer], :string
13
+ end
14
+
15
+ # Abstract base class for connections.
16
+ class Connection < Vips::Object
17
+ # The layout of the VipsRegion struct.
18
+ module ConnectionLayout
19
+ def self.included(base)
20
+ base.class_eval do
21
+ layout :parent, Vips::Object::Struct
22
+ # rest opaque
23
+ end
24
+ end
25
+ end
26
+
27
+ class Struct < Vips::Object::Struct
28
+ include ConnectionLayout
29
+ end
30
+
31
+ class ManagedStruct < Vips::Object::ManagedStruct
32
+ include ConnectionLayout
33
+ end
34
+
35
+ # Get any filename associated with a connection, or nil.
36
+ def filename
37
+ Vips.vips_connection_filename self
38
+ end
39
+
40
+ # Get a nickname (short description) of a connection that could be shown to
41
+ # the user.
42
+ def nick
43
+ Vips.vips_connection_nick self
44
+ end
45
+ end
46
+ end
@@ -1,11 +1,10 @@
1
1
  module Vips
2
+ # Operations like {Image#flip} need to be told whether to flip
3
+ # left-right or top-bottom.
4
+ #
5
+ # * `:horizontal` left-right
6
+ # * `:vertical` top-bottom
2
7
 
3
- # Operations like {Image#flip} need to be told whether to flip
4
- # left-right or top-bottom.
5
- #
6
- # * `:horizontal` left-right
7
- # * `:vertical` top-bottom
8
-
9
- class Direction < Symbol
10
- end
8
+ class Direction < Symbol
9
+ end
11
10
  end
data/lib/vips/extend.rb CHANGED
@@ -1,17 +1,16 @@
1
1
  module Vips
2
+ # When the edges of an image are extended, you can specify
3
+ # how you want the extension done.
4
+ # See {Image#embed}, {Image#conv}, {Image#affine} and
5
+ # so on.
6
+ #
7
+ # * `:black` new pixels are black, ie. all bits are zero.
8
+ # * `:copy` each new pixel takes the value of the nearest edge pixel
9
+ # * `:repeat` the image is tiled to fill the new area
10
+ # * `:mirror` the image is reflected and tiled to reduce hash edges
11
+ # * `:white` new pixels are white, ie. all bits are set
12
+ # * `:background` colour set from the @background property
2
13
 
3
- # When the edges of an image are extended, you can specify
4
- # how you want the extension done.
5
- # See {Image#embed}, {Image#conv}, {Image#affine} and
6
- # so on.
7
- #
8
- # * `:black` new pixels are black, ie. all bits are zero.
9
- # * `:copy` each new pixel takes the value of the nearest edge pixel
10
- # * `:repeat` the image is tiled to fill the new area
11
- # * `:mirror` the image is reflected and tiled to reduce hash edges
12
- # * `:white` new pixels are white, ie. all bits are set
13
- # * `:background` colour set from the @background property
14
-
15
- class Extend < Symbol
16
- end
14
+ class Extend < Symbol
15
+ end
17
16
  end
data/lib/vips/gobject.rb CHANGED
@@ -4,119 +4,130 @@
4
4
  # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
5
  # License:: MIT
6
6
 
7
- require 'ffi'
8
- require 'forwardable'
7
+ require "ffi"
8
+ require "forwardable"
9
9
 
10
10
  module GObject
11
-
12
- # we have a number of things we need to inherit in different ways:
13
- #
14
- # - we want to be able to subclass GObject in Ruby in a simple way
15
- # - the layouts of the nested structs need to inherit
16
- # - we need to be able to cast between structs which share a base struct
17
- # without creating new wrappers or messing up refcounting
18
- # - we need automatic gobject refcounting
19
- #
20
- # the solution is to split the class into four areas which we treat
21
- # differently:
22
- #
23
- # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
24
- # @struct member which holds the actual pointer
25
- # - we use "forwardable" to forward the various ffi methods on to the
26
- # @struct member ... we arrange things so that subclasses do not need to
27
- # do the forwarding themselves
28
- # - we have two versions of the struct: a plain one which we can use for
29
- # casting that will not change the refcounts
30
- # - and a managed one with an unref which we just use for .new
31
- # - we separate the struct layout into a separate module to avoid repeating
32
- # ourselves
33
-
34
- class GObject
35
- extend Forwardable
36
- extend SingleForwardable
37
-
38
- def_instance_delegators :@struct, :[], :to_ptr
39
- def_single_delegators :ffi_struct, :ptr
40
-
41
- # the layout of the GObject struct
42
- module GObjectLayout
43
- def self.included base
44
- base.class_eval do
45
- layout :g_type_instance, :pointer,
46
- :ref_count, :uint,
47
- :qdata, :pointer
48
- end
49
- end
50
- end
51
-
52
- # the struct with unref ... manage object lifetime with this
53
- class ManagedStruct < FFI::ManagedStruct
54
- include GObjectLayout
55
-
56
- def self.release ptr
57
- # GLib::logger.debug("GObject::GObject::ManagedStruct.release") {
58
- # "unreffing #{ptr}"
59
- # }
60
- ::GObject::g_object_unref ptr
61
- end
11
+ # we have a number of things we need to inherit in different ways:
12
+ #
13
+ # - we want to be able to subclass GObject in Ruby in a simple way
14
+ # - the layouts of the nested structs need to inherit
15
+ # - we need to be able to cast between structs which share a base struct
16
+ # without creating new wrappers or messing up refcounting
17
+ # - we need automatic gobject refcounting
18
+ #
19
+ # the solution is to split the class into four areas which we treat
20
+ # differently:
21
+ #
22
+ # - we have a "wrapper" Ruby class to allow easy subclassing ... this has a
23
+ # @struct member which holds the actual pointer
24
+ # - we use "forwardable" to forward the various ffi methods on to the
25
+ # @struct member ... we arrange things so that subclasses do not need to
26
+ # do the forwarding themselves
27
+ # - we have two versions of the struct: a plain one which we can use for
28
+ # casting that will not change the refcounts
29
+ # - and a managed one with an unref which we just use for .new
30
+ # - we separate the struct layout into a separate module to avoid repeating
31
+ # ourselves
32
+
33
+ class GObject
34
+ extend Forwardable
35
+ extend SingleForwardable
36
+
37
+ def_instance_delegators :@struct, :[], :to_ptr
38
+ def_single_delegators :ffi_struct, :ptr
39
+
40
+ attr_reader :references
41
+
42
+ # the layout of the GObject struct
43
+ module GObjectLayout
44
+ def self.included base
45
+ base.class_eval do
46
+ layout :g_type_instance, :pointer,
47
+ :ref_count, :uint,
48
+ :qdata, :pointer
62
49
  end
50
+ end
51
+ end
63
52
 
64
- # the plain struct ... cast with this
65
- class Struct < FFI::Struct
66
- include GObjectLayout
67
-
68
- end
53
+ # the struct with unref ... manage object lifetime with this
54
+ class ManagedStruct < FFI::ManagedStruct
55
+ include GObjectLayout
69
56
 
70
- # don't allow ptr == nil, we never want to allocate a GObject struct
71
- # ourselves, we just want to wrap GLib-allocated GObjects
72
- #
73
- # here we use ManagedStruct, not Struct, since this is the ref that will
74
- # need the unref
75
- def initialize ptr
76
- # GLib::logger.debug("GObject::GObject.initialize") {"ptr = #{ptr}"}
77
- @struct = ffi_managed_struct.new ptr
78
- end
57
+ def self.release ptr
58
+ # GLib::logger.debug("GObject::GObject::ManagedStruct.release") {
59
+ # "unreffing #{ptr}"
60
+ # }
61
+ ::GObject.g_object_unref ptr
62
+ end
63
+ end
79
64
 
80
- # access to the casting struct for this class
81
- def ffi_struct
82
- self.class.ffi_struct
83
- end
65
+ # the plain struct ... cast with this
66
+ class Struct < FFI::Struct
67
+ include GObjectLayout
68
+ end
84
69
 
85
- class << self
86
- def ffi_struct
87
- self.const_get :Struct
88
- end
89
- end
70
+ # don't allow ptr == nil, we never want to allocate a GObject struct
71
+ # ourselves, we just want to wrap GLib-allocated GObjects
72
+ #
73
+ # here we use ManagedStruct, not Struct, since this is the ref that will
74
+ # need the unref
75
+ def initialize ptr
76
+ # GLib::logger.debug("GObject::GObject.initialize") {"ptr = #{ptr}"}
77
+ @ptr = ptr
78
+ @struct = ffi_managed_struct.new ptr
79
+
80
+ # sometimes we need to keep refs across C calls ... hide them here
81
+ @references = []
82
+ end
90
83
 
91
- # access to the managed struct for this class
92
- def ffi_managed_struct
93
- self.class.ffi_managed_struct
94
- end
84
+ # access to the casting struct for this class
85
+ def ffi_struct
86
+ self.class.ffi_struct
87
+ end
95
88
 
96
- class << self
97
- def ffi_managed_struct
98
- self.const_get :ManagedStruct
99
- end
100
- end
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
101
92
 
93
+ class << self
94
+ def ffi_struct
95
+ const_get :Struct
96
+ end
102
97
  end
103
98
 
104
- class GParamSpec < FFI::Struct
105
- # the first few public fields
106
- layout :g_type_instance, :pointer,
107
- :name, :string,
108
- :flags, :uint,
109
- :value_type, :GType,
110
- :owner_type, :GType
99
+ # access to the managed struct for this class
100
+ def ffi_managed_struct
101
+ self.class.ffi_managed_struct
111
102
  end
112
103
 
113
- class GParamSpecPtr < FFI::Struct
114
- layout :value, GParamSpec.ptr
104
+ class << self
105
+ def ffi_managed_struct
106
+ const_get :ManagedStruct
107
+ end
115
108
  end
116
-
117
- attach_function :g_param_spec_get_blurb, [GParamSpec.ptr], :string
118
-
119
- attach_function :g_object_ref, [:pointer], :void
120
- attach_function :g_object_unref, [:pointer], :void
121
-
109
+ end
110
+
111
+ class GParamSpec < FFI::Struct
112
+ # the first few public fields
113
+ layout :g_type_instance, :pointer,
114
+ :name, :string,
115
+ :flags, :uint,
116
+ :value_type, :GType,
117
+ :owner_type, :GType
118
+ end
119
+
120
+ class GParamSpecPtr < FFI::Struct
121
+ layout :value, GParamSpec.ptr
122
+ end
123
+
124
+ attach_function :g_param_spec_get_blurb, [:pointer], :string
125
+
126
+ attach_function :g_object_ref, [:pointer], :void
127
+ attach_function :g_object_unref, [:pointer], :void
128
+
129
+ # we just use one gcallback type for every signal, hopefully this is OK
130
+ callback :gcallback, [:pointer], :void
131
+ attach_function :g_signal_connect_data,
132
+ [:pointer, :string, :gcallback, :pointer, :pointer, :int], :long
122
133
  end