ruby-vips 2.0.17 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) 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 +13 -0
  7. data/Gemfile +3 -1
  8. data/README.md +4 -4
  9. data/Rakefile +13 -21
  10. data/TODO +3 -6
  11. data/VERSION +1 -1
  12. data/example/annotate.rb +6 -6
  13. data/example/connection.rb +18 -9
  14. data/example/daltonize8.rb +6 -6
  15. data/example/draw_lines.rb +30 -0
  16. data/example/example1.rb +4 -4
  17. data/example/example2.rb +6 -6
  18. data/example/example3.rb +5 -5
  19. data/example/example4.rb +2 -2
  20. data/example/example5.rb +4 -4
  21. data/example/inheritance_with_refcount.rb +35 -36
  22. data/example/progress.rb +3 -3
  23. data/example/thumb.rb +6 -6
  24. data/example/trim8.rb +1 -1
  25. data/example/watermark.rb +2 -2
  26. data/example/wobble.rb +1 -1
  27. data/lib/ruby-vips.rb +1 -1
  28. data/lib/vips.rb +121 -75
  29. data/lib/vips/blend_mode.rb +29 -25
  30. data/lib/vips/connection.rb +4 -4
  31. data/lib/vips/gobject.rb +18 -11
  32. data/lib/vips/gvalue.rb +54 -54
  33. data/lib/vips/image.rb +232 -155
  34. data/lib/vips/interpolate.rb +3 -2
  35. data/lib/vips/methods.rb +165 -15
  36. data/lib/vips/mutableimage.rb +154 -0
  37. data/lib/vips/object.rb +84 -85
  38. data/lib/vips/operation.rb +161 -82
  39. data/lib/vips/region.rb +6 -6
  40. data/lib/vips/source.rb +11 -12
  41. data/lib/vips/sourcecustom.rb +7 -8
  42. data/lib/vips/target.rb +12 -13
  43. data/lib/vips/targetcustom.rb +9 -10
  44. data/lib/vips/version.rb +1 -1
  45. data/ruby-vips.gemspec +26 -22
  46. metadata +28 -48
  47. data/.rubocop.yml +0 -22
  48. data/.rubocop_todo.yml +0 -473
  49. data/.travis.yml +0 -57
  50. data/install-vips.sh +0 -26
data/lib/vips/image.rb CHANGED
@@ -4,13 +4,13 @@
4
4
  # Author:: John Cupitt (mailto:jcupitt@gmail.com)
5
5
  # License:: MIT
6
6
 
7
- require 'ffi'
7
+ require "ffi"
8
8
 
9
9
  module Vips
10
10
  private
11
11
 
12
12
  attach_function :vips_image_new_matrix_from_array,
13
- [:int, :int, :pointer, :int], :pointer
13
+ [:int, :int, :pointer, :int], :pointer
14
14
 
15
15
  attach_function :vips_image_copy_memory, [:pointer], :pointer
16
16
 
@@ -25,29 +25,35 @@ module Vips
25
25
  attach_function :vips_foreign_find_load_buffer, [:pointer, :size_t], :string
26
26
  attach_function :vips_foreign_find_save_buffer, [:string], :string
27
27
 
28
- if Vips::at_least_libvips?(8, 9)
28
+ if Vips.at_least_libvips?(8, 9)
29
29
  attach_function :vips_foreign_find_load_source, [:pointer], :string
30
30
  attach_function :vips_foreign_find_save_target, [:string], :string
31
31
  end
32
32
 
33
33
  attach_function :vips_image_write_to_memory,
34
- [:pointer, SizeStruct.ptr], :pointer
34
+ [:pointer, SizeStruct.ptr], :pointer
35
35
 
36
36
  attach_function :vips_image_get_typeof, [:pointer, :string], :GType
37
37
  attach_function :vips_image_get,
38
- [:pointer, :string, GObject::GValue.ptr], :int
38
+ [:pointer, :string, GObject::GValue.ptr], :int
39
39
 
40
- if Vips::at_least_libvips?(8, 5)
40
+ attach_function :vips_image_get_width, [:pointer], :int
41
+ attach_function :vips_image_get_height, [:pointer], :int
42
+ attach_function :vips_image_get_bands, [:pointer], :int
43
+
44
+ if Vips.at_least_libvips?(8, 5)
41
45
  attach_function :vips_image_get_fields, [:pointer], :pointer
42
46
  attach_function :vips_image_hasalpha, [:pointer], :int
43
47
  end
44
48
 
45
- if Vips::at_least_libvips?(8, 6)
49
+ if Vips.at_least_libvips?(8, 6)
46
50
  attach_function :vips_addalpha, [:pointer, :pointer, :varargs], :int
47
51
  end
48
52
 
53
+ # move these three lines to mutableimage when we finally remove set and
54
+ # remove in this class
49
55
  attach_function :vips_image_set,
50
- [:pointer, :string, GObject::GValue.ptr], :void
56
+ [:pointer, :string, GObject::GValue.ptr], :void
51
57
  attach_function :vips_image_remove, [:pointer, :string], :void
52
58
 
53
59
  attach_function :vips_band_format_iscomplex, [:int], :int
@@ -55,6 +61,9 @@ module Vips
55
61
 
56
62
  attach_function :nickname_find, :vips_nickname_find, [:GType], :string
57
63
 
64
+ attach_function :vips_image_new_from_memory, [:pointer, :size_t, :int, :int, :int, :int], :pointer
65
+ attach_function :vips_image_new_from_memory_copy, [:pointer, :size_t, :int, :int, :int, :int], :pointer
66
+
58
67
  # turn a raw pointer that must be freed into a self-freeing Ruby string
59
68
  def self.p2str(pointer)
60
69
  pointer = FFI::AutoPointer.new(pointer, GLib::G_FREE)
@@ -96,17 +105,17 @@ module Vips
96
105
  # handy for overloads ... want to be able to apply a function to an
97
106
  # array or to a scalar
98
107
  def self.smap x, &block
99
- x.is_a?(Array) ? x.map { |y| smap(y, &block) } : block.(x)
108
+ x.is_a?(Array) ? x.map { |y| smap(y, &block) } : block.call(x)
100
109
  end
101
110
 
102
111
  def self.complex? format
103
112
  format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
104
- Vips::vips_band_format_iscomplex(format_number) != 0
113
+ Vips.vips_band_format_iscomplex(format_number) != 0
105
114
  end
106
115
 
107
116
  def self.float? format
108
117
  format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
109
- Vips::vips_band_format_isfloat(format_number) != 0
118
+ Vips.vips_band_format_isfloat(format_number) != 0
110
119
  end
111
120
 
112
121
  # run a complex operation on a complex image, or an image with an even
@@ -115,12 +124,12 @@ module Vips
115
124
  def self.run_cmplx image, &block
116
125
  original_format = image.format
117
126
 
118
- unless Image::complex? image.format
127
+ unless Image.complex? image.format
119
128
  if image.bands % 2 != 0
120
129
  raise Vips::Error, "not an even number of bands"
121
130
  end
122
131
 
123
- unless Image::float? image.format
132
+ unless Image.float? image.format
124
133
  image = image.cast :float
125
134
  end
126
135
 
@@ -128,9 +137,9 @@ module Vips
128
137
  image = image.copy format: new_format, bands: image.bands / 2
129
138
  end
130
139
 
131
- image = block.(image)
140
+ image = block.call(image)
132
141
 
133
- unless Image::complex? original_format
142
+ unless Image.complex? original_format
134
143
  new_format = image.format == :dpcomplex ? :double : :float
135
144
  image = image.copy format: new_format, bands: image.bands * 2
136
145
  end
@@ -189,15 +198,19 @@ module Vips
189
198
  # 36013-heads-up-ruby-implicitly-converts-a-hash-to-keyword-arguments
190
199
  return false if name == :to_hash
191
200
 
201
+ super
202
+ end
203
+
204
+ def respond_to_missing? name, include_all = false
192
205
  # respond to all vips operations by nickname
193
- return true if Vips::type_find("VipsOperation", name.to_s) != 0
206
+ return true if Vips.type_find("VipsOperation", name.to_s) != 0
194
207
 
195
208
  super
196
209
  end
197
210
 
198
- def self.respond_to? name, include_all = false
211
+ def self.respond_to_missing? name, include_all = false
199
212
  # respond to all vips operations by nickname
200
- return true if Vips::type_find("VipsOperation", name.to_s) != 0
213
+ return true if Vips.type_find("VipsOperation", name.to_s) != 0
201
214
 
202
215
  super
203
216
  end
@@ -255,18 +268,18 @@ module Vips
255
268
  def self.new_from_file name, **opts
256
269
  # very common, and Vips::vips_filename_get_filename will segv if we
257
270
  # pass this
258
- raise Vips::Error, "filename is nil" if name == nil
271
+ raise Vips::Error, "filename is nil" if name.nil?
259
272
 
260
- filename = Vips::p2str(Vips::vips_filename_get_filename name)
261
- option_string = Vips::p2str(Vips::vips_filename_get_options name)
262
- loader = Vips::vips_foreign_find_load filename
263
- raise Vips::Error if loader == nil
273
+ filename = Vips.p2str(Vips.vips_filename_get_filename(name))
274
+ option_string = Vips.p2str(Vips.vips_filename_get_options(name))
275
+ loader = Vips.vips_foreign_find_load filename
276
+ raise Vips::Error if loader.nil?
264
277
 
265
278
  Operation.call loader, [filename], opts, option_string
266
279
  end
267
280
 
268
- # Create a new {Image} for an image encoded, in a format such as
269
- # JPEG, in a binary string. Load options may be passed as
281
+ # Create a new {Image} for an image encoded in a format such as
282
+ # JPEG in a binary string. Load options may be passed as
270
283
  # strings or appended as a hash. For example:
271
284
  #
272
285
  # ```
@@ -297,12 +310,75 @@ module Vips
297
310
  # @macro vips.loadopts
298
311
  # @return [Image] the loaded image
299
312
  def self.new_from_buffer data, option_string, **opts
300
- loader = Vips::vips_foreign_find_load_buffer data, data.bytesize
313
+ loader = Vips.vips_foreign_find_load_buffer data, data.bytesize
301
314
  raise Vips::Error if loader.nil?
302
315
 
303
316
  Vips::Operation.call loader, [data], opts, option_string
304
317
  end
305
318
 
319
+ # Create a new {Image} from a C-style array held in memory. For example:
320
+ #
321
+ # ```
322
+ # image = Vips::Image.black(16, 16) + 128
323
+ # data = image.write_to_memory
324
+ #
325
+ # x = Vips::Image.new_from_memory data,
326
+ # image.width, image.height, image.bands, image.format
327
+ # ```
328
+ #
329
+ # {new_from_memory} keeps a reference to the array of pixels you pass in
330
+ # to try to prevent that memory from being freed by the Ruby GC while it
331
+ # is being used.
332
+ #
333
+ # See {new_from_memory_copy} for a version of this method which does not
334
+ # keep a reference.
335
+ #
336
+ # @param data [String, FFI::Pointer] the data to load from
337
+ # @param width [Integer] width in pixels
338
+ # @param height [Integer] height in pixels
339
+ # @param bands [Integer] number of bands
340
+ # @param format [Symbol] band format
341
+ # @return [Image] the loaded image
342
+ def self.new_from_memory data, width, height, bands, format
343
+ size = data.bytesize
344
+
345
+ # prevent data from being freed with JRuby FFI
346
+ if defined?(JRUBY_VERSION) && !data.is_a?(FFI::Pointer)
347
+ data = ::FFI::MemoryPointer.new(:char, data.bytesize).write_bytes data
348
+ end
349
+
350
+ format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
351
+ vi = Vips.vips_image_new_from_memory data, size,
352
+ width, height, bands, format_number
353
+ raise Vips::Error if vi.null?
354
+ image = new(vi)
355
+
356
+ # keep a secret ref to the underlying object .. this reference will be
357
+ # inherited by things that in turn depend on us, so the memory we are
358
+ # using will not be freed
359
+ image.references << data
360
+
361
+ image
362
+ end
363
+
364
+ # Create a new {Image} from memory and copies the memory area. See
365
+ # {new_from_memory} for a version of this method which does not copy the
366
+ # memory area.
367
+ #
368
+ # @param data [String, FFI::Pointer] the data to load from
369
+ # @param width [Integer] width in pixels
370
+ # @param height [Integer] height in pixels
371
+ # @param bands [Integer] number of bands
372
+ # @param format [Symbol] band format
373
+ # @return [Image] the loaded image
374
+ def self.new_from_memory_copy data, width, height, bands, format
375
+ format_number = GObject::GValue.from_nick BAND_FORMAT_TYPE, format
376
+ vi = Vips.vips_image_new_from_memory_copy data, data.bytesize,
377
+ width, height, bands, format_number
378
+ raise Vips::Error if vi.null?
379
+ new(vi)
380
+ end
381
+
306
382
  # Create a new {Image} from a source. Load options may be passed as
307
383
  # strings or appended as a hash. For example:
308
384
  #
@@ -328,7 +404,7 @@ module Vips
328
404
  # TIFF images will work.
329
405
  #
330
406
  # Loading is fast: only enough data is read to be able to fill
331
- # out the header. Pixels will only be read and decompressed when they are
407
+ # out the header. Pixels will only be read and decompressed when they are
332
408
  # needed.
333
409
  #
334
410
  # @param source [Vips::Source] the source to load from
@@ -336,7 +412,7 @@ module Vips
336
412
  # @macro vips.loadopts
337
413
  # @return [Image] the loaded image
338
414
  def self.new_from_source source, option_string, **opts
339
- loader = Vips::vips_foreign_find_load_source source
415
+ loader = Vips.vips_foreign_find_load_source source
340
416
  raise Vips::Error if loader.nil?
341
417
 
342
418
  Vips::Operation.call loader, [source], opts, option_string
@@ -345,8 +421,8 @@ module Vips
345
421
  def self.matrix_from_array width, height, array
346
422
  ptr = FFI::MemoryPointer.new :double, array.length
347
423
  ptr.write_array_of_double array
348
- image = Vips::vips_image_new_matrix_from_array width, height,
349
- ptr, array.length
424
+ image = Vips.vips_image_new_matrix_from_array width, height,
425
+ ptr, array.length
350
426
  Vips::Image.new image
351
427
  end
352
428
 
@@ -399,18 +475,22 @@ module Vips
399
475
  width = array.length
400
476
  end
401
477
 
478
+ unless array.length == width * height
479
+ raise Vips::Error, "Bad array dimensions."
480
+ end
481
+
402
482
  unless array.all? { |x| x.is_a? Numeric }
403
483
  raise Vips::Error, "Not all array elements are Numeric."
404
484
  end
405
485
 
406
486
  image = Vips::Image.matrix_from_array width, height, array
407
- raise Vips::Error if image == nil
487
+ raise Vips::Error if image.nil?
408
488
 
409
- # be careful to set them as double
410
- image.set_type GObject::GDOUBLE_TYPE, 'scale', scale.to_f
411
- image.set_type GObject::GDOUBLE_TYPE, 'offset', offset.to_f
412
-
413
- return image
489
+ image.mutate do |mutable|
490
+ # be careful to set them as double
491
+ mutable.set_type! GObject::GDOUBLE_TYPE, "scale", scale.to_f
492
+ mutable.set_type! GObject::GDOUBLE_TYPE, "offset", offset.to_f
493
+ end
414
494
  end
415
495
 
416
496
  # A new image is created with the same width, height, format,
@@ -426,7 +506,7 @@ module Vips
426
506
  pixel = (Vips::Image.black(1, 1) + value).cast(format)
427
507
  image = pixel.embed 0, 0, width, height, extend: :copy
428
508
  image.copy interpretation: interpretation, xres: xres, yres: yres,
429
- xoffset: xoffset, yoffset: yoffset
509
+ xoffset: xoffset, yoffset: yoffset
430
510
  end
431
511
 
432
512
  # Write this image to a file. Save options may be encoded in the
@@ -459,12 +539,12 @@ module Vips
459
539
  #
460
540
  # @param name [String] filename to write to
461
541
  def write_to_file name, **opts
462
- filename = Vips::p2str(Vips::vips_filename_get_filename name)
463
- option_string = Vips::p2str(Vips::vips_filename_get_options name)
464
- saver = Vips::vips_foreign_find_save filename
465
- if saver == nil
466
- raise Vips::Error, "No known saver for '#{filename}'."
467
- end
542
+ raise Vips::Error, "filename is nil" if name.nil?
543
+
544
+ filename = Vips.p2str(Vips.vips_filename_get_filename(name))
545
+ option_string = Vips.p2str(Vips.vips_filename_get_options(name))
546
+ saver = Vips.vips_foreign_find_save filename
547
+ raise Vips::Error if saver.nil?
468
548
 
469
549
  Vips::Operation.call saver, [self, filename], opts, option_string
470
550
 
@@ -497,19 +577,18 @@ module Vips
497
577
  # @macro vips.saveopts
498
578
  # @return [String] the image saved in the specified format
499
579
  def write_to_buffer format_string, **opts
500
- filename = Vips::p2str(Vips::vips_filename_get_filename format_string)
501
- option_string = Vips::p2str(Vips::vips_filename_get_options format_string)
502
- saver = Vips::vips_foreign_find_save_buffer filename
503
- if saver == nil
504
- raise Vips::Error, "No known buffer saver for '#{filename}'."
505
- end
580
+ raise Vips::Error, "filename is nil" if format_string.nil?
581
+ filename = Vips.p2str(Vips.vips_filename_get_filename(format_string))
582
+ option_string = Vips.p2str(Vips.vips_filename_get_options(format_string))
583
+ saver = Vips.vips_foreign_find_save_buffer filename
584
+ raise Vips::Error if saver.nil?
506
585
 
507
586
  buffer = Vips::Operation.call saver, [self], opts, option_string
508
- raise Vips::Error if buffer == nil
587
+ raise Vips::Error if buffer.nil?
509
588
 
510
589
  write_gc
511
590
 
512
- return buffer
591
+ buffer
513
592
  end
514
593
 
515
594
  # Write this image to a target. Save options may be encoded in
@@ -539,12 +618,11 @@ module Vips
539
618
  # @param format_string [String] save format plus string options
540
619
  # @macro vips.saveopts
541
620
  def write_to_target target, format_string, **opts
542
- filename = Vips::p2str(Vips::vips_filename_get_filename format_string)
543
- option_string = Vips::p2str(Vips::vips_filename_get_options format_string)
544
- saver = Vips::vips_foreign_find_save_target filename
545
- if saver == nil
546
- raise Vips::Error, "No known target saver for '#{filename}'."
547
- end
621
+ raise Vips::Error, "filename is nil" if format_string.nil?
622
+ filename = Vips.p2str(Vips.vips_filename_get_filename(format_string))
623
+ option_string = Vips.p2str(Vips.vips_filename_get_options(format_string))
624
+ saver = Vips.vips_foreign_find_save_target filename
625
+ raise Vips::Error if saver.nil?
548
626
 
549
627
  Vips::Operation.call saver, [self, target], opts, option_string
550
628
  write_gc
@@ -555,8 +633,8 @@ module Vips
555
633
  # @return [String] the pixels as a huge binary string
556
634
  def write_to_memory
557
635
  len = Vips::SizeStruct.new
558
- ptr = Vips::vips_image_write_to_memory self, len
559
- raise Vips::Error if ptr == nil
636
+ ptr = Vips.vips_image_write_to_memory self, len
637
+ raise Vips::Error if ptr.nil?
560
638
 
561
639
  # wrap up as an autopointer
562
640
  ptr = FFI::AutoPointer.new(ptr, GLib::G_FREE)
@@ -564,15 +642,15 @@ module Vips
564
642
  ptr.get_bytes 0, len[:value]
565
643
  end
566
644
 
567
- # Turn progress signalling on and off.
645
+ # Turn progress signalling on and off.
568
646
  #
569
647
  # If this is on, the most-downstream image from this image will issue
570
- # progress signals.
648
+ # progress signals.
571
649
  #
572
650
  # @see Object#signal_connect
573
651
  # @param state [Boolean] progress signalling state
574
652
  def set_progress state
575
- Vips::vips_image_set_progress self, state
653
+ Vips.vips_image_set_progress self, state
576
654
  end
577
655
 
578
656
  # Kill computation of this time.
@@ -583,7 +661,7 @@ module Vips
583
661
  # @see Object#signal_connect
584
662
  # @param kill [Boolean] stop computation
585
663
  def set_kill kill
586
- Vips::vips_image_set_kill self, kill
664
+ Vips.vips_image_set_kill self, kill
587
665
  end
588
666
 
589
667
  # Get the `GType` of a metadata field. The result is 0 if no such field
@@ -595,12 +673,12 @@ module Vips
595
673
  def get_typeof name
596
674
  # on libvips before 8.5, property types must be searched first,
597
675
  # since vips_image_get_typeof returned built-in enums as int
598
- unless Vips::at_least_libvips?(8, 5)
676
+ unless Vips.at_least_libvips?(8, 5)
599
677
  gtype = parent_get_typeof name
600
678
  return gtype if gtype != 0
601
679
  end
602
680
 
603
- Vips::vips_image_get_typeof self, name
681
+ Vips.vips_image_get_typeof self, name
604
682
  end
605
683
 
606
684
  # Get a metadata item from an image. Ruby types are constructed
@@ -619,12 +697,12 @@ module Vips
619
697
  def get name
620
698
  # with old libvips, we must fetch properties (as opposed to
621
699
  # metadata) via VipsObject
622
- unless Vips::at_least_libvips?(8, 5)
700
+ unless Vips.at_least_libvips?(8, 5)
623
701
  return super if parent_get_typeof(name) != 0
624
702
  end
625
703
 
626
704
  gvalue = GObject::GValue.alloc
627
- raise Vips::Error if Vips::vips_image_get(self, name, gvalue) != 0
705
+ raise Vips::Error if Vips.vips_image_get(self, name, gvalue) != 0
628
706
  result = gvalue.get
629
707
  gvalue.unset
630
708
 
@@ -639,67 +717,64 @@ module Vips
639
717
  # vips_image_get_fields() was added in libvips 8.5
640
718
  return [] unless Vips.respond_to? :vips_image_get_fields
641
719
 
642
- array = Vips::vips_image_get_fields self
720
+ array = Vips.vips_image_get_fields self
643
721
 
644
722
  names = []
645
723
  p = array
646
724
  until (q = p.read_pointer).null?
647
725
  names << q.read_string
648
- GLib::g_free q
726
+ GLib.g_free q
649
727
  p += FFI::Type::POINTER.size
650
728
  end
651
- GLib::g_free array
729
+ GLib.g_free array
652
730
 
653
731
  names
654
732
  end
655
733
 
656
- # Create a metadata item on an image of the specifed type. Ruby types
657
- # are automatically transformed into the matching `GType`, if possible.
734
+ # Mutate an image with a block. Inside the block, you can call methods
735
+ # which modify the image, such as setting or removing metadata, or
736
+ # modifying pixels.
658
737
  #
659
- # For example, you can use this to set an image's ICC profile:
738
+ # For example:
660
739
  #
661
- # ```
662
- # x = y.set_type Vips::BLOB_TYPE, "icc-profile-data", profile
740
+ # ```ruby
741
+ # image = image.mutate do |x|
742
+ # (0 ... 1).step(0.01) do |i|
743
+ # x.draw_line! 255, x.width * i, 0, 0, x.height * (1 - i)
744
+ # end
745
+ # end
663
746
  # ```
664
747
  #
665
- # where `profile` is an ICC profile held as a binary string object.
748
+ # See {MutableImage}.
749
+ def mutate
750
+ mutable = Vips::MutableImage.new self
751
+ yield mutable
752
+ mutable.image
753
+ end
754
+
755
+ # This method is deprecated.
666
756
  #
667
- # @see set
668
- # @param gtype [Integer] GType of item
669
- # @param name [String] Metadata field to set
670
- # @param value [Object] Value to set
757
+ # Please use {MutableImage#set_type!} instead.
671
758
  def set_type gtype, name, value
672
759
  gvalue = GObject::GValue.alloc
673
760
  gvalue.init gtype
674
761
  gvalue.set value
675
- Vips::vips_image_set self, name, gvalue
762
+ Vips.vips_image_set self, name, gvalue
676
763
  gvalue.unset
677
764
  end
678
765
 
679
- # Set the value of a metadata item on an image. The metadata item must
680
- # already exist. Ruby types are automatically transformed into the
681
- # matching `GValue`, if possible.
682
- #
683
- # For example, you can use this to set an image's ICC profile:
766
+ # This method is deprecated.
684
767
  #
685
- # ```
686
- # x = y.set "icc-profile-data", profile
687
- # ```
688
- #
689
- # where `profile` is an ICC profile held as a binary string object.
690
- #
691
- # @see set_type
692
- # @param name [String] Metadata field to set
693
- # @param value [Object] Value to set
768
+ # Please use {MutableImage#set!} instead.
694
769
  def set name, value
695
770
  set_type get_typeof(name), name, value
696
771
  end
697
772
 
698
- # Remove a metadata item from an image.
773
+ # This method is deprecated.
699
774
  #
700
- # @param name [String] Metadata field to remove
775
+ # Please use {MutableImage#remove!} instead.
701
776
  def remove name
702
- Vips::vips_image_remove self, name
777
+ Vips.vips_image_remove self, name
703
778
  end
704
779
 
705
780
  # compatibility: old name for get
@@ -707,7 +782,9 @@ module Vips
707
782
  get name
708
783
  end
709
784
 
710
- # compatibility: old name for set
785
+ # This method is deprecated.
786
+ #
787
+ # Please use {MutableImage#set!} instead.
711
788
  def set_value name, value
712
789
  set name, value
713
790
  end
@@ -716,21 +793,21 @@ module Vips
716
793
  #
717
794
  # @return [Integer] image width, in pixels
718
795
  def width
719
- get "width"
796
+ Vips.vips_image_get_width self
720
797
  end
721
798
 
722
799
  # Get image height, in pixels.
723
800
  #
724
801
  # @return [Integer] image height, in pixels
725
802
  def height
726
- get "height"
803
+ Vips.vips_image_get_height self
727
804
  end
728
805
 
729
806
  # Get number of image bands.
730
807
  #
731
808
  # @return [Integer] number of image bands
732
809
  def bands
733
- get "bands"
810
+ Vips.vips_image_get_bands self
734
811
  end
735
812
 
736
813
  # Get image format.
@@ -814,23 +891,23 @@ module Vips
814
891
  [width, height]
815
892
  end
816
893
 
817
- if Vips::at_least_libvips?(8, 5)
894
+ if Vips.at_least_libvips?(8, 5)
818
895
  # Detect if image has an alpha channel
819
896
  #
820
897
  # @return [Boolean] true if image has an alpha channel.
821
898
  def has_alpha?
822
- return Vips::vips_image_hasalpha(self) != 0
899
+ Vips.vips_image_hasalpha(self) != 0
823
900
  end
824
901
  end
825
902
 
826
903
  # vips_addalpha was added in libvips 8.6
827
- if Vips::at_least_libvips?(8, 6)
904
+ if Vips.at_least_libvips?(8, 6)
828
905
  # Append an alpha channel to an image.
829
906
  #
830
907
  # @return [Image] new image
831
908
  def add_alpha
832
909
  ptr = GenericPtr.new
833
- result = Vips::vips_addalpha self, ptr
910
+ result = Vips.vips_addalpha self, ptr
834
911
  raise Vips::Error if result != 0
835
912
 
836
913
  Vips::Image.new ptr[:value]
@@ -845,7 +922,7 @@ module Vips
845
922
  #
846
923
  # @return [Image] new memory image
847
924
  def copy_memory
848
- new_image = Vips::vips_image_copy_memory self
925
+ new_image = Vips.vips_image_copy_memory self
849
926
  Vips::Image.new new_image
850
927
  end
851
928
 
@@ -855,7 +932,7 @@ module Vips
855
932
  #
856
933
  # @return [Image] modified image
857
934
  def draw_point ink, left, top, **opts
858
- draw_rect ink, left, top, 1, 1, opts
935
+ draw_rect ink, left, top, 1, 1, **opts
859
936
  end
860
937
 
861
938
  # Add an image, constant or array.
@@ -873,7 +950,7 @@ module Vips
873
950
  # @return [Image] result of subtraction
874
951
  def - other
875
952
  other.is_a?(Vips::Image) ?
876
- subtract(other) : linear(1, Image::smap(other) { |x| x * -1 })
953
+ subtract(other) : linear(1, Image.smap(other) { |x| x * -1 })
877
954
  end
878
955
 
879
956
  # Multiply an image, constant or array.
@@ -891,7 +968,7 @@ module Vips
891
968
  # @return [Image] result of division
892
969
  def / other
893
970
  other.is_a?(Vips::Image) ?
894
- divide(other) : linear(Image::smap(other) { |x| 1.0 / x }, 0)
971
+ divide(other) : linear(Image.smap(other) { |x| 1.0 / x }, 0)
895
972
  end
896
973
 
897
974
  # Remainder after integer division with an image, constant or array.
@@ -1017,7 +1094,7 @@ module Vips
1017
1094
  # @return [Image] result of equality
1018
1095
  def == other
1019
1096
  # for equality, we must allow tests against nil
1020
- if other == nil
1097
+ if other.nil?
1021
1098
  false
1022
1099
  else
1023
1100
  call_enum "relational", other, :equal
@@ -1030,7 +1107,7 @@ module Vips
1030
1107
  # @return [Image] result of inequality
1031
1108
  def != other
1032
1109
  # for equality, we must allow tests against nil
1033
- if other == nil
1110
+ if other.nil?
1034
1111
  true
1035
1112
  else
1036
1113
  call_enum "relational", other, :noteq
@@ -1062,17 +1139,17 @@ module Vips
1062
1139
 
1063
1140
  # make the template for unpack
1064
1141
  template = {
1065
- char: 'c',
1066
- uchar: 'C',
1067
- short: 's_',
1068
- ushort: 'S_',
1069
- int: 'i_',
1070
- uint: 'I_',
1071
- float: 'f',
1072
- double: 'd',
1073
- complex: 'f',
1074
- dpcomplex: 'd'
1075
- }[format] + '*'
1142
+ char: "c",
1143
+ uchar: "C",
1144
+ short: "s_",
1145
+ ushort: "S_",
1146
+ int: "i_",
1147
+ uint: "I_",
1148
+ float: "f",
1149
+ double: "d",
1150
+ complex: "f",
1151
+ dpcomplex: "d"
1152
+ }[format] + "*"
1076
1153
 
1077
1154
  # and unpack into something like [1, 2, 3, 4 ..]
1078
1155
  array = memory.unpack(template)
@@ -1081,9 +1158,7 @@ module Vips
1081
1158
  pixel_array = array.each_slice(bands).to_a
1082
1159
 
1083
1160
  # build rows
1084
- row_array = pixel_array.each_slice(width).to_a
1085
-
1086
- return row_array
1161
+ pixel_array.each_slice(width).to_a
1087
1162
  end
1088
1163
 
1089
1164
  # Return the largest integral value not greater than the argument.
@@ -1159,7 +1234,10 @@ module Vips
1159
1234
  # @param overlay [Image, Array<Image>] images to composite
1160
1235
  # @param mode [BlendMode, Array<BlendMode>] blend modes to use
1161
1236
  # @param opts [Hash] Set of options
1162
- # @option opts [Vips::Interpretation] :compositing_space Composite images in this colour space
1237
+ # @option opts [Array<Integer>] :x x positions of overlay
1238
+ # @option opts [Array<Integer>] :y y positions of overlay
1239
+ # @option opts [Vips::Interpretation] :compositing_space Composite images
1240
+ # in this colour space
1163
1241
  # @option opts [Boolean] :premultiplied Images have premultiplied alpha
1164
1242
  # @return [Image] blended image
1165
1243
  def composite overlay, mode, **opts
@@ -1183,9 +1261,9 @@ module Vips
1183
1261
  # coordinate of maximum
1184
1262
  def maxpos
1185
1263
  v, opts = max x: true, y: true
1186
- x = opts['x']
1187
- y = opts['y']
1188
- return v, x, y
1264
+ x = opts["x"]
1265
+ y = opts["y"]
1266
+ [v, x, y]
1189
1267
  end
1190
1268
 
1191
1269
  # Return the coordinates of the image minimum.
@@ -1194,9 +1272,9 @@ module Vips
1194
1272
  # coordinate of minimum
1195
1273
  def minpos
1196
1274
  v, opts = min x: true, y: true
1197
- x = opts['x']
1198
- y = opts['y']
1199
- return v, x, y
1275
+ x = opts["x"]
1276
+ y = opts["y"]
1277
+ [v, x, y]
1200
1278
  end
1201
1279
 
1202
1280
  # a median filter
@@ -1204,7 +1282,7 @@ module Vips
1204
1282
  # @param size [Integer] size of filter window
1205
1283
  # @return [Image] result of median filter
1206
1284
  def median size = 3
1207
- rank size, size, (size * size) / 2
1285
+ rank size, size, size**2 / 2
1208
1286
  end
1209
1287
 
1210
1288
  # Return the real part of a complex image.
@@ -1231,7 +1309,7 @@ module Vips
1231
1309
  # @see xyz
1232
1310
  # @return [Image] image converted to polar coordinates
1233
1311
  def polar
1234
- Image::run_cmplx(self) { |x| x.complex :polar }
1312
+ Image.run_cmplx(self) { |x| x.complex :polar }
1235
1313
  end
1236
1314
 
1237
1315
  # Return an image with polar pixels converted to rectangular.
@@ -1244,7 +1322,7 @@ module Vips
1244
1322
  # @see xyz
1245
1323
  # @return [Image] image converted to rectangular coordinates
1246
1324
  def rect
1247
- Image::run_cmplx(self) { |x| x.complex :rect }
1325
+ Image.run_cmplx(self) { |x| x.complex :rect }
1248
1326
  end
1249
1327
 
1250
1328
  # Return the complex conjugate of an image.
@@ -1256,7 +1334,7 @@ module Vips
1256
1334
  #
1257
1335
  # @return [Image] complex conjugate
1258
1336
  def conj
1259
- Image::run_cmplx(self) { |x| x.complex :conj }
1337
+ Image.run_cmplx(self) { |x| x.complex :conj }
1260
1338
  end
1261
1339
 
1262
1340
  # Calculate the cross phase of two images.
@@ -1437,7 +1515,7 @@ module Vips
1437
1515
  #
1438
1516
  # ```
1439
1517
  # $ ruby > methods.rb
1440
- # require 'vips'; Vips::Yard.generate
1518
+ # require "vips"; Vips::Yard.generate
1441
1519
  # ^D
1442
1520
  # ```
1443
1521
 
@@ -1459,7 +1537,7 @@ module Vips
1459
1537
  "VipsArrayDouble" => "Array<Double>",
1460
1538
  "VipsArrayInt" => "Array<Integer>",
1461
1539
  "VipsArrayImage" => "Array<Image>",
1462
- "VipsArrayString" => "Array<String>",
1540
+ "VipsArrayString" => "Array<String>"
1463
1541
  }
1464
1542
 
1465
1543
  # these have hand-written methods, see above
@@ -1470,15 +1548,15 @@ module Vips
1470
1548
 
1471
1549
  # turn a gtype into a ruby type name
1472
1550
  def self.gtype_to_ruby gtype
1473
- fundamental = GObject::g_type_fundamental gtype
1474
- type_name = GObject::g_type_name gtype
1551
+ fundamental = GObject.g_type_fundamental gtype
1552
+ type_name = GObject.g_type_name gtype
1475
1553
 
1476
1554
  if MAP_GO_TO_RUBY.include? type_name
1477
1555
  type_name = MAP_GO_TO_RUBY[type_name]
1478
1556
  end
1479
1557
 
1480
1558
  if fundamental == GObject::GFLAGS_TYPE ||
1481
- fundamental == GObject::GENUM_TYPE
1559
+ fundamental == GObject::GENUM_TYPE
1482
1560
  type_name = "Vips::" + type_name[/Vips(.*)/, 1]
1483
1561
  end
1484
1562
 
@@ -1497,7 +1575,7 @@ module Vips
1497
1575
  print "# @!method "
1498
1576
  print "self." unless introspect.member_x
1499
1577
  print "#{introspect.name}("
1500
- print method_args.map{ |x| x[:yard_name] }.join(", ")
1578
+ print method_args.map { |x| x[:yard_name] }.join(", ")
1501
1579
  print ", " if method_args.length > 0
1502
1580
  puts "**opts)"
1503
1581
 
@@ -1517,8 +1595,7 @@ module Vips
1517
1595
  gtype = details[:gtype]
1518
1596
  blurb = details[:blurb]
1519
1597
 
1520
- puts "# @option opts [#{gtype_to_ruby(gtype)}] :#{yard_name} " +
1521
- "#{blurb}"
1598
+ puts "# @option opts [#{gtype_to_ruby(gtype)}] :#{yard_name} #{blurb}"
1522
1599
  end
1523
1600
  optional_output.each do |arg_name, details|
1524
1601
  yard_name = details[:yard_name]
@@ -1536,14 +1613,14 @@ module Vips
1536
1613
  print gtype_to_ruby(required_output.first[:gtype])
1537
1614
  else
1538
1615
  print "Array<"
1539
- print required_output.map{ |x| gtype_to_ruby(x[:gtype]) }.join(", ")
1616
+ print required_output.map { |x| gtype_to_ruby(x[:gtype]) }.join(", ")
1540
1617
  print ">"
1541
1618
  end
1542
1619
  if optional_output.length > 0
1543
1620
  print ", Hash<Symbol => Object>"
1544
1621
  end
1545
1622
  print "] "
1546
- print required_output.map{ |x| x[:blurb] }.join(", ")
1623
+ print required_output.map { |x| x[:blurb] }.join(", ")
1547
1624
  if optional_output.length > 0
1548
1625
  print ", " if required_output.length > 0
1549
1626
  print "Hash of optional output items"
@@ -1555,16 +1632,16 @@ module Vips
1555
1632
 
1556
1633
  def self.generate
1557
1634
  alias_gtypes = {}
1558
- ALIAS.each do |name|
1559
- gtype = Vips::type_find "VipsOperation", name
1560
- alias_gtypes[gtype] = name
1635
+ ALIAS.each do |name|
1636
+ gtype = Vips.type_find "VipsOperation", name
1637
+ alias_gtypes[gtype] = name
1561
1638
  end
1562
1639
 
1563
1640
  generate_class = lambda do |gtype, _|
1564
- if alias_gtypes.key? gtype
1565
- name = alias_gtypes[gtype]
1641
+ name = if alias_gtypes.key? gtype
1642
+ alias_gtypes[gtype]
1566
1643
  else
1567
- name = Vips::nickname_find gtype
1644
+ Vips.nickname_find gtype
1568
1645
  end
1569
1646
 
1570
1647
  if name
@@ -1578,14 +1655,14 @@ module Vips
1578
1655
  generate_operation(introspect) if introspect
1579
1656
  end
1580
1657
 
1581
- Vips::vips_type_map gtype, generate_class, nil
1658
+ Vips.vips_type_map gtype, generate_class, nil
1582
1659
  end
1583
1660
 
1584
1661
  puts "module Vips"
1585
1662
  puts " class Image"
1586
1663
  puts ""
1587
1664
 
1588
- generate_class.(GObject::g_type_from_name("VipsOperation"), nil)
1665
+ generate_class.call(GObject.g_type_from_name("VipsOperation"), nil)
1589
1666
 
1590
1667
  puts " end"
1591
1668
  puts "end"