ruby-vips 0.3.14 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +22 -0
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +46 -31
  6. data/{LICENSE → LICENSE.txt} +1 -1
  7. data/README.md +101 -145
  8. data/Rakefile +45 -0
  9. data/TODO +8 -32
  10. data/VERSION +1 -0
  11. data/example/annotate.rb +17 -0
  12. data/example/daltonize8.rb +75 -0
  13. data/example/example1.rb +84 -0
  14. data/example/example2.rb +31 -0
  15. data/example/example3.rb +19 -0
  16. data/example/example4.rb +18 -0
  17. data/example/example5.rb +31 -0
  18. data/example/trim8.rb +41 -0
  19. data/example/watermark.rb +44 -0
  20. data/example/wobble.rb +36 -0
  21. data/lib/vips.rb +151 -14
  22. data/lib/vips/access.rb +14 -0
  23. data/lib/vips/align.rb +11 -0
  24. data/lib/vips/angle.rb +12 -0
  25. data/lib/vips/angle45.rb +16 -0
  26. data/lib/vips/argument.rb +163 -0
  27. data/lib/vips/bandformat.rb +20 -0
  28. data/lib/vips/call.rb +302 -0
  29. data/lib/vips/coding.rb +14 -0
  30. data/lib/vips/demandstyle.rb +35 -0
  31. data/lib/vips/direction.rb +11 -0
  32. data/lib/vips/error.rb +30 -0
  33. data/lib/vips/extend.rb +22 -0
  34. data/lib/vips/foreignflags.rb +20 -0
  35. data/lib/vips/image.rb +1382 -0
  36. data/lib/vips/interpolate.rb +37 -0
  37. data/lib/vips/interpretation.rb +28 -0
  38. data/lib/vips/methods.rb +1807 -0
  39. data/lib/vips/operation.rb +19 -0
  40. data/ruby-vips8.gemspec +112 -0
  41. data/spec/image_spec.rb +515 -0
  42. data/spec/samples/balloon.v +0 -0
  43. data/spec/samples/ghost.ppm +405 -0
  44. data/spec/samples/huge.jpg +0 -0
  45. data/spec/samples/icc.jpg +0 -0
  46. data/spec/samples/lcd.icc +0 -0
  47. data/spec/samples/lion.svg +154 -0
  48. data/spec/samples/sample.csv +7 -0
  49. data/spec/samples/sample.exr +0 -0
  50. data/spec/samples/wagon.jpg +0 -0
  51. data/spec/samples/wagon.v +0 -0
  52. data/spec/spec_helper.rb +49 -0
  53. data/spec/vips_spec.rb +74 -0
  54. metadata +110 -70
  55. data/ext/extconf.rb +0 -31
  56. data/ext/header.c +0 -457
  57. data/ext/header.h +0 -9
  58. data/ext/image.c +0 -629
  59. data/ext/image.h +0 -72
  60. data/ext/image_arithmetic.c +0 -936
  61. data/ext/image_arithmetic.h +0 -38
  62. data/ext/image_boolean.c +0 -301
  63. data/ext/image_boolean.h +0 -8
  64. data/ext/image_colour.c +0 -590
  65. data/ext/image_colour.h +0 -36
  66. data/ext/image_conversion.c +0 -884
  67. data/ext/image_conversion.h +0 -38
  68. data/ext/image_convolution.c +0 -368
  69. data/ext/image_convolution.h +0 -13
  70. data/ext/image_freq_filt.c +0 -740
  71. data/ext/image_freq_filt.h +0 -27
  72. data/ext/image_histograms_lut.c +0 -643
  73. data/ext/image_histograms_lut.h +0 -28
  74. data/ext/image_morphology.c +0 -327
  75. data/ext/image_morphology.h +0 -13
  76. data/ext/image_mosaicing.c +0 -554
  77. data/ext/image_mosaicing.h +0 -15
  78. data/ext/image_relational.c +0 -384
  79. data/ext/image_relational.h +0 -8
  80. data/ext/image_resample.c +0 -249
  81. data/ext/image_resample.h +0 -9
  82. data/ext/interpolator.c +0 -106
  83. data/ext/interpolator.h +0 -7
  84. data/ext/mask.c +0 -347
  85. data/ext/mask.h +0 -18
  86. data/ext/reader.c +0 -261
  87. data/ext/reader.h +0 -2
  88. data/ext/ruby_vips.c +0 -188
  89. data/ext/ruby_vips.h +0 -72
  90. data/ext/tags +0 -450
  91. data/ext/writer.c +0 -371
  92. data/ext/writer.h +0 -2
  93. data/lib/vips/reader.rb +0 -272
  94. data/lib/vips/version.rb +0 -3
  95. data/lib/vips/writer.rb +0 -342
  96. data/ruby-vips.gemspec +0 -100
  97. data/ruby.supp +0 -134
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'vips'
4
+
5
+ image = Vips::Image.new_from_file ARGV[0]
6
+
7
+ module Vips
8
+ class Image
9
+ def wobble
10
+ # this makes an image where pixel (0, 0) (at the top-left) has
11
+ # value [0, 0], and pixel (image.width, image.height) at the
12
+ # bottom-right has value [image.width, image.height]
13
+ index = Vips::Image.xyz width, height
14
+
15
+ # make a version with (0, 0) at the centre, negative values up
16
+ # and left, positive down and right
17
+ centre = index - [width / 2, height / 2]
18
+
19
+ # to polar space, so each pixel is now distance and angle in degrees
20
+ polar = centre.polar
21
+
22
+ # scale sin(distance) by 1/distance to make a wavey pattern
23
+ d = ((polar[0] * 3).sin * 10000) / (polar[0] + 1)
24
+
25
+ # and back to rectangular coordinates again to make a set of
26
+ # vectors we can apply to the original index image
27
+ index += d.bandjoin(polar[1]).rect
28
+
29
+ # finally, use our modified index image to distort!
30
+ mapim index
31
+ end
32
+ end
33
+ end
34
+
35
+ image = image.wobble
36
+ image.write_to_file ARGV[1]
@@ -1,16 +1,153 @@
1
- # Vips will print warnings to stdout unless this is set
2
- ENV['IM_WARNING'] = "0"
3
-
4
- require 'vips_ext'
5
- require 'vips/version'
6
- require 'vips/reader'
7
- require 'vips/writer'
8
-
9
- module VIPS
10
- class << self
11
- def sequential_mode_supported?
12
- comp = VIPS::LIB_VERSION_ARRAY <=> [7,28,0]
13
- comp >= 0
1
+ # This module provides a set of overrides for the vips image processing library
2
+ # used via the gobject-introspection gem.
3
+ #
4
+ # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
+ # License:: MIT
6
+
7
+ # @private
8
+ def log str
9
+ if $vips_debug
10
+ puts str
11
+ end
12
+ end
13
+
14
+ # copied from ruby-gnome2/gstreamer/lib/gst.rb without much understanding
15
+
16
+ require 'pathname'
17
+ require 'gobject-introspection'
18
+
19
+ # pick up a local girepository/lib in preference to the system one
20
+ base_dir = Pathname.new(__FILE__).dirname.dirname.expand_path
21
+ vendor_dir = base_dir + "vendor" + "local"
22
+ vendor_bin_dir = vendor_dir + "bin"
23
+ GLib.prepend_dll_path(vendor_bin_dir)
24
+ vendor_girepository_dir = vendor_dir + "lib" + "girepository-1.0"
25
+ GObjectIntrospection.prepend_typelib_path(vendor_girepository_dir)
26
+
27
+ module Vips
28
+ # @private
29
+ LOG_DOMAIN = "VIPS"
30
+ GLib::Log.set_log_domain(LOG_DOMAIN)
31
+
32
+ # about as crude as you could get
33
+ $vips_debug = false
34
+
35
+ # Turn debug logging on and off.
36
+ #
37
+ # @param dbg [Boolean] Set true to print debug log messages
38
+ def self.set_debug dbg
39
+ $vips_debug = dbg
40
+ end
41
+
42
+ class << self
43
+ # @private
44
+ def const_missing(name)
45
+ log "Vips::const_missing: #{name}"
46
+
47
+ init()
48
+ if const_defined?(name)
49
+ const_get(name)
50
+ else
51
+ super
52
+ end
53
+ end
54
+
55
+ # @private
56
+ def method_missing(name, *args, &block)
57
+ log "Vips::method_missing: #{name}, #{args}, #{block}"
58
+
59
+ init()
60
+ if respond_to?(name)
61
+ __send__(name, *args, &block)
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ # @private
68
+ def init(*argv)
69
+ log "Vips::init: #{argv}"
70
+
71
+ class << self
72
+ remove_method(:init)
73
+ remove_method(:const_missing)
74
+ remove_method(:method_missing)
75
+ end
76
+
77
+ loader = Loader.new(self, argv)
78
+ begin
79
+ loader.load("Vips")
80
+ rescue
81
+ puts "Unable to load Vips"
82
+ puts " Check that the vips library has been installed and is"
83
+ puts " on your library path."
84
+ puts " Check that the typelib `Vips-8.0.typelib` has been "
85
+ puts " installed, and that it is on your GI_TYPELIB_PATH."
86
+ raise
87
+ end
88
+
89
+ require 'vips/error'
90
+ require 'vips/argument'
91
+ require 'vips/operation'
92
+ require 'vips/call'
93
+ require 'vips/image'
94
+ end
95
+ end
96
+
97
+ # @private
98
+ class Loader < GObjectIntrospection::Loader
99
+ def initialize(base_module, init_arguments)
100
+ log "Vips::Loader.initialize: #{base_module}, #{init_arguments}"
101
+
102
+ super(base_module)
103
+ @init_arguments = init_arguments
104
+ end
105
+
106
+ private
107
+ def pre_load(repository, namespace)
108
+ log "Vips::Loader.pre_load: #{repository}, #{namespace}"
109
+
110
+ call_init_function(repository, namespace)
111
+ define_value_modules
112
+ end
113
+
114
+ def call_init_function(repository, namespace)
115
+ log "Vips::Loader.call_init_function: #{repository}, #{namespace}"
116
+
117
+ # call Vips::init
118
+ init = repository.find(namespace, "init")
119
+ succeeded, argv, error = init.invoke(:arguments => [$PROGRAM_NAME])
120
+
121
+ # TODO get the vips error buffer
122
+ raise error unless succeeded
123
+ end
124
+
125
+ def define_value_modules
126
+ @value_functions_module = Module.new
127
+ @value_methods_module = Module.new
128
+ @base_module.const_set("ValueFunctions", @value_functions_module)
129
+ @base_module.const_set("ValueMethods", @value_methods_module)
130
+ end
131
+
132
+ def post_load(repository, namespace)
133
+ log "Vips::Loader.post_load:"
134
+ end
135
+
136
+ end
137
+ end
138
+
139
+ at_exit {
140
+ Vips::shutdown if Vips.respond_to? :shutdown
141
+ }
142
+
143
+ # this makes vips keep a list of all active objects which we can print out
144
+ Vips::leak_set true if $vips_debug
145
+
146
+ # @private
147
+ def showall
148
+ if $vips_debug
149
+ GC.start
150
+ Vips::Object::print_all
14
151
  end
15
- end
16
152
  end
153
+
@@ -0,0 +1,14 @@
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
+ #
10
+ # * `:sequential_unbuffered` means requests will be strictly
11
+ # top-to-bottom with no read-behind. This can save some memory.
12
+ class Access
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Vips
2
+
3
+ # Various types of alignment. See {Vips::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
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Vips
2
+
3
+ # Various fixed 90 degree rotation angles. See {Vips::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
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Vips
2
+
3
+ # Various fixed 45 degree rotation angles. See {Vips::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
15
+ end
16
+ end
@@ -0,0 +1,163 @@
1
+
2
+ module Vips
3
+
4
+ # This class is used internally to convert Ruby values to arguments to
5
+ # libvips operations.
6
+ # @private
7
+ class Argument
8
+ attr_reader :op, :name, :flags, :priority, :isset, :prop
9
+ attr_reader :blurb, :gtype, :type
10
+
11
+ # map gobject-introspection's ruby class names to ours
12
+ @@map_goi_to_vips = {
13
+ "TrueClass" => "Boolean",
14
+ "Vips::ArrayDouble" => "Array<Double>",
15
+ "Vips::ArrayInt" => "Array<Integer>",
16
+ "Vips::ArrayImage" => "Array<Image>",
17
+ "Vips::ArrayString" => "Array<String>",
18
+ }
19
+
20
+ def initialize(op, name)
21
+ @op = op
22
+ @name = name.tr '-', '_'
23
+ @prop = op.gtype.to_class.property name
24
+ @blurb = @prop.blurb
25
+ @gtype = prop.value_type
26
+ @flags = op.get_argument_flags name
27
+ @priority = op.get_argument_priority @name
28
+ @isset = op.argument_isset @name
29
+
30
+ type = GLib::Type[gtype.name].to_class.name
31
+ type = @@map_goi_to_vips[type] if @@map_goi_to_vips.include? type
32
+ @type = type
33
+ end
34
+
35
+ private
36
+
37
+ def self.imageize match_image, value
38
+ return value if match_image == nil
39
+ return value if value.is_a? Vips::Image
40
+
41
+ # 2D array values become tiny 2D images
42
+ if value.is_a? Array and value[0].is_a? Array
43
+ return Vips::Image.new_from_array value
44
+ end
45
+
46
+ # if there's nothing to match to, we also make a 2D image
47
+ if match_image == nil
48
+ return Vips::Image.new_from_array value
49
+ end
50
+
51
+ # we have a 1D array ... use that as a pixel constant and expand
52
+ # to match match_image
53
+ pixel = (Vips::Image.black(1, 1) + value).cast(match_image.format)
54
+ pixel = pixel.copy :interpretation => match_image.interpretation,
55
+ :xres => match_image.xres, :yres => match_image.yres
56
+ pixel.embed(0, 0, match_image.width, match_image.height,
57
+ :extend => :copy)
58
+ end
59
+
60
+ # @private
61
+ class ArrayImageConst < Vips::ArrayImage
62
+ def self.new(value)
63
+ if not value.is_a? Array
64
+ value = [value]
65
+ end
66
+
67
+ match_image = value.find {|x| x.is_a? Vips::Image}
68
+ if match_image == nil
69
+ raise Vips::Error,
70
+ "Argument must contain at least one image."
71
+ end
72
+
73
+ value = value.map {|x| Argument::imageize match_image, x}
74
+
75
+ # we'd like to just
76
+ # super(value)
77
+ # to construct, but the gobject-introspection gem does not
78
+ # support new from object array ... instead, we build in stages
79
+ array = Vips::ArrayImage.empty
80
+ value.each {|x| array = array.append(x)}
81
+
82
+ return array
83
+ end
84
+ end
85
+
86
+ # if this gtype needs an array, try to transform the value into one
87
+ def self.arrayize(gtype, value)
88
+ arrayize_map = {
89
+ GLib::Type["VipsArrayDouble"] => Vips::ArrayDouble,
90
+ GLib::Type["VipsArrayInt"] => Vips::ArrayInt,
91
+ GLib::Type["VipsArrayImage"] => ArrayImageConst
92
+ }
93
+
94
+ if arrayize_map.has_key? gtype
95
+ if not value.is_a? Array
96
+ value = [value]
97
+ end
98
+
99
+ value = arrayize_map[gtype].new(value)
100
+ end
101
+
102
+ value
103
+ end
104
+
105
+ def self.unwrap value
106
+ [Vips::Blob, Vips::ArrayDouble, Vips::ArrayImage,
107
+ Vips::ArrayInt, Vips::RefString].each do |cls|
108
+ if value.is_a? cls
109
+ value, length = value.get
110
+
111
+ # blobs come from gobject-introspection as arrays ...
112
+ # repack as strings for convenience
113
+ if value and cls == Vips::Blob
114
+ value = value.pack("C*")
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ value
122
+ end
123
+
124
+ public
125
+
126
+ def set_value(match_image, value)
127
+ # array-ize
128
+ value = Argument::arrayize gtype, value
129
+
130
+ # blob-ize
131
+ if gtype.type_is_a? GLib::Type["VipsBlob"]
132
+ if not value.is_a? Vips::Blob
133
+ value = Vips::Blob.copy value
134
+ end
135
+ end
136
+
137
+ # image-ize
138
+ if gtype.type_is_a? GLib::Type["VipsImage"]
139
+ if not value.is_a? Vips::Image
140
+ value = Argument::imageize match_image, value
141
+ end
142
+ end
143
+
144
+ # MODIFY input images need to be copied before assigning them
145
+ if (flags & :modify) != 0
146
+ # don't use .copy(): we want to make a new pipeline with no
147
+ # reference back to the old stuff ... this way we can free the
148
+ # previous image earlier
149
+ new_image = Vips::Image.memory
150
+ value.write new_image
151
+ value = new_image
152
+ end
153
+
154
+ op.set_property @name, value
155
+ end
156
+
157
+ def get_value
158
+ Argument::unwrap @op.get_property(@name)
159
+ end
160
+
161
+ end
162
+
163
+ end
@@ -0,0 +1,20 @@
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
18
+ end
19
+
20
+ end