ruby-vips 2.0.17 → 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 (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"