ruby-vips 2.0.16 → 2.0.17

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.
@@ -14,6 +14,9 @@ module Vips
14
14
 
15
15
  attach_function :vips_image_copy_memory, [:pointer], :pointer
16
16
 
17
+ attach_function :vips_image_set_progress, [:pointer, :bool], :void
18
+ attach_function :vips_image_set_kill, [:pointer, :bool], :void
19
+
17
20
  attach_function :vips_filename_get_filename, [:string], :pointer
18
21
  attach_function :vips_filename_get_options, [:string], :pointer
19
22
 
@@ -22,6 +25,11 @@ module Vips
22
25
  attach_function :vips_foreign_find_load_buffer, [:pointer, :size_t], :string
23
26
  attach_function :vips_foreign_find_save_buffer, [:string], :string
24
27
 
28
+ if Vips::at_least_libvips?(8, 9)
29
+ attach_function :vips_foreign_find_load_source, [:pointer], :string
30
+ attach_function :vips_foreign_find_save_target, [:string], :string
31
+ end
32
+
25
33
  attach_function :vips_image_write_to_memory,
26
34
  [:pointer, SizeStruct.ptr], :pointer
27
35
 
@@ -109,7 +117,7 @@ module Vips
109
117
 
110
118
  unless Image::complex? image.format
111
119
  if image.bands % 2 != 0
112
- raise Error, "not an even number of bands"
120
+ raise Vips::Error, "not an even number of bands"
113
121
  end
114
122
 
115
123
  unless Image::float? image.format
@@ -290,11 +298,50 @@ module Vips
290
298
  # @return [Image] the loaded image
291
299
  def self.new_from_buffer data, option_string, **opts
292
300
  loader = Vips::vips_foreign_find_load_buffer data, data.bytesize
293
- raise Vips::Error if loader == nil
301
+ raise Vips::Error if loader.nil?
294
302
 
295
303
  Vips::Operation.call loader, [data], opts, option_string
296
304
  end
297
305
 
306
+ # Create a new {Image} from a source. Load options may be passed as
307
+ # strings or appended as a hash. For example:
308
+ #
309
+ # ```
310
+ # source = Vips::Source.new_from_file("k2.jpg")
311
+ # image = Vips::Image.new_from_source source, "shrink=2"
312
+ # ```
313
+ #
314
+ # or alternatively:
315
+ #
316
+ # ```
317
+ # image = Vips::Image.new_from_source source, "", shrink: 2
318
+ # ```
319
+ #
320
+ # The options available depend on the file format. Try something like:
321
+ #
322
+ # ```
323
+ # $ vips jpegload_source
324
+ # ```
325
+ #
326
+ # at the command-line to see the available options. Not all loaders
327
+ # support load from source, but at least JPEG, PNG and
328
+ # TIFF images will work.
329
+ #
330
+ # 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
332
+ # needed.
333
+ #
334
+ # @param source [Vips::Source] the source to load from
335
+ # @param option_string [String] load options as a string
336
+ # @macro vips.loadopts
337
+ # @return [Image] the loaded image
338
+ def self.new_from_source source, option_string, **opts
339
+ loader = Vips::vips_foreign_find_load_source source
340
+ raise Vips::Error if loader.nil?
341
+
342
+ Vips::Operation.call loader, [source], opts, option_string
343
+ end
344
+
298
345
  def self.matrix_from_array width, height, array
299
346
  ptr = FFI::MemoryPointer.new :double, array.length
300
347
  ptr.write_array_of_double array
@@ -454,7 +501,7 @@ module Vips
454
501
  option_string = Vips::p2str(Vips::vips_filename_get_options format_string)
455
502
  saver = Vips::vips_foreign_find_save_buffer filename
456
503
  if saver == nil
457
- raise Vips::Error, "No known saver for '#{filename}'."
504
+ raise Vips::Error, "No known buffer saver for '#{filename}'."
458
505
  end
459
506
 
460
507
  buffer = Vips::Operation.call saver, [self], opts, option_string
@@ -465,6 +512,44 @@ module Vips
465
512
  return buffer
466
513
  end
467
514
 
515
+ # Write this image to a target. Save options may be encoded in
516
+ # the format_string or given as a hash. For example:
517
+ #
518
+ # ```ruby
519
+ # target = Vips::Target.new_to_file "k2.jpg"
520
+ # image.write_to_target target, ".jpg[Q=90]"
521
+ # ```
522
+ #
523
+ # or equivalently:
524
+ #
525
+ # ```ruby
526
+ # image.write_to_target target, ".jpg", Q: 90
527
+ # ```
528
+ #
529
+ # The full set of save options depend on the selected saver. Try
530
+ # something like:
531
+ #
532
+ # ```
533
+ # $ vips jpegsave_target
534
+ # ```
535
+ #
536
+ # to see all the available options for JPEG save.
537
+ #
538
+ # @param target [Vips::Target] the target to write to
539
+ # @param format_string [String] save format plus string options
540
+ # @macro vips.saveopts
541
+ 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
548
+
549
+ Vips::Operation.call saver, [self, target], opts, option_string
550
+ write_gc
551
+ end
552
+
468
553
  # Write this image to a large memory buffer.
469
554
  #
470
555
  # @return [String] the pixels as a huge binary string
@@ -479,6 +564,28 @@ module Vips
479
564
  ptr.get_bytes 0, len[:value]
480
565
  end
481
566
 
567
+ # Turn progress signalling on and off.
568
+ #
569
+ # If this is on, the most-downstream image from this image will issue
570
+ # progress signals.
571
+ #
572
+ # @see Object#signal_connect
573
+ # @param state [Boolean] progress signalling state
574
+ def set_progress state
575
+ Vips::vips_image_set_progress self, state
576
+ end
577
+
578
+ # Kill computation of this time.
579
+ #
580
+ # Set true to stop computation of this image. You can call this from a
581
+ # progress handler, for example.
582
+ #
583
+ # @see Object#signal_connect
584
+ # @param kill [Boolean] stop computation
585
+ def set_kill kill
586
+ Vips::vips_image_set_kill self, kill
587
+ end
588
+
482
589
  # Get the `GType` of a metadata field. The result is 0 if no such field
483
590
  # exists.
484
591
  #
@@ -517,10 +624,11 @@ module Vips
517
624
  end
518
625
 
519
626
  gvalue = GObject::GValue.alloc
520
- result = Vips::vips_image_get self, name, gvalue
521
- raise Vips::Error if result != 0
627
+ raise Vips::Error if Vips::vips_image_get(self, name, gvalue) != 0
628
+ result = gvalue.get
629
+ gvalue.unset
522
630
 
523
- gvalue.get
631
+ result
524
632
  end
525
633
 
526
634
  # Get the names of all fields on an image. Use this to loop over all
@@ -565,6 +673,7 @@ module Vips
565
673
  gvalue.init gtype
566
674
  gvalue.set value
567
675
  Vips::vips_image_set self, name, gvalue
676
+ gvalue.unset
568
677
  end
569
678
 
570
679
  # Set the value of a metadata item on an image. The metadata item must
@@ -1065,7 +1174,7 @@ module Vips
1065
1174
  GObject::GValue.from_nick Vips::BLEND_MODE_TYPE, x
1066
1175
  end
1067
1176
 
1068
- Vips::Image.composite([self] + overlay, mode, opts)
1177
+ Vips::Image.composite([self] + overlay, mode, **opts)
1069
1178
  end
1070
1179
 
1071
1180
  # Return the coordinates of the image maximum.
@@ -1315,29 +1424,26 @@ module Vips
1315
1424
  # @param opts [Hash] Set of options
1316
1425
  # @return [Vips::Image] Output image
1317
1426
  def scaleimage **opts
1318
- Vips::Image.scale self, opts
1427
+ Vips::Image.scale self, **opts
1319
1428
  end
1320
1429
  end
1321
1430
  end
1322
1431
 
1323
1432
  module Vips
1324
- # This method generates yard comments for all the dynamically bound
1433
+ # This module generates yard comments for all the dynamically bound
1325
1434
  # vips operations.
1326
1435
  #
1327
1436
  # Regenerate with something like:
1328
1437
  #
1329
1438
  # ```
1330
1439
  # $ ruby > methods.rb
1331
- # require 'vips'; Vips::generate_yard
1440
+ # require 'vips'; Vips::Yard.generate
1332
1441
  # ^D
1333
1442
  # ```
1334
1443
 
1335
- def self.generate_yard
1336
- # these have hand-written methods, see above
1337
- no_generate = ["scale", "bandjoin", "composite", "ifthenelse"]
1338
-
1444
+ module Yard
1339
1445
  # map gobject's type names to Ruby
1340
- map_go_to_ruby = {
1446
+ MAP_GO_TO_RUBY = {
1341
1447
  "gboolean" => "Boolean",
1342
1448
  "gint" => "Integer",
1343
1449
  "gdouble" => "Float",
@@ -1345,116 +1451,99 @@ module Vips
1345
1451
  "gchararray" => "String",
1346
1452
  "VipsImage" => "Vips::Image",
1347
1453
  "VipsInterpolate" => "Vips::Interpolate",
1454
+ "VipsConnection" => "Vips::Connection",
1455
+ "VipsSource" => "Vips::Source",
1456
+ "VipsTarget" => "Vips::Target",
1457
+ "VipsSourceCustom" => "Vips::SourceCustom",
1458
+ "VipsTargetCustom" => "Vips::TargetCustom",
1348
1459
  "VipsArrayDouble" => "Array<Double>",
1349
1460
  "VipsArrayInt" => "Array<Integer>",
1350
1461
  "VipsArrayImage" => "Array<Image>",
1351
1462
  "VipsArrayString" => "Array<String>",
1352
1463
  }
1353
1464
 
1354
- generate_operation = lambda do |gtype, nickname, op|
1355
- op_flags = op.get_flags
1356
- return if (op_flags & OPERATION_DEPRECATED) != 0
1357
- return if no_generate.include? nickname
1358
-
1359
- description = Vips::vips_object_get_description op
1360
-
1361
- # find and classify all the arguments the operator can take
1362
- required_input = []
1363
- optional_input = []
1364
- required_output = []
1365
- optional_output = []
1366
- member_x = nil
1367
- op.argument_map do |pspec, argument_class, _argument_instance|
1368
- arg_flags = argument_class[:flags]
1369
- next if (arg_flags & ARGUMENT_CONSTRUCT) == 0
1370
- next if (arg_flags & ARGUMENT_DEPRECATED) != 0
1371
-
1372
- name = pspec[:name].tr("-", "_")
1373
- # 'in' as a param name confuses yard
1374
- name = "im" if name == "in"
1375
- gtype = pspec[:value_type]
1376
- fundamental = GObject::g_type_fundamental gtype
1377
- type_name = GObject::g_type_name gtype
1378
- if map_go_to_ruby.include? type_name
1379
- type_name = map_go_to_ruby[type_name]
1380
- end
1381
- if fundamental == GObject::GFLAGS_TYPE ||
1382
- fundamental == GObject::GENUM_TYPE
1383
- type_name = "Vips::" + type_name[/Vips(.*)/, 1]
1384
- end
1385
- blurb = GObject::g_param_spec_get_blurb pspec
1386
- value = {
1387
- name: name,
1388
- flags: arg_flags,
1389
- gtype: gtype,
1390
- type_name: type_name,
1391
- blurb: blurb
1392
- }
1393
-
1394
- if (arg_flags & ARGUMENT_INPUT) != 0
1395
- if (arg_flags & ARGUMENT_REQUIRED) != 0
1396
- # note the first required input image, if any ... we
1397
- # will be a method of this instance
1398
- if !member_x && gtype == Vips::IMAGE_TYPE
1399
- member_x = value
1400
- else
1401
- required_input << value
1402
- end
1403
- else
1404
- optional_input << value
1405
- end
1406
- end
1465
+ # these have hand-written methods, see above
1466
+ NO_GENERATE = ["scale", "bandjoin", "composite", "ifthenelse"]
1407
1467
 
1408
- # MODIFY INPUT args count as OUTPUT as well
1409
- if (arg_flags & ARGUMENT_OUTPUT) != 0 ||
1410
- ((arg_flags & ARGUMENT_INPUT) != 0 &&
1411
- (arg_flags & ARGUMENT_MODIFY) != 0)
1412
- if (arg_flags & ARGUMENT_REQUIRED) != 0
1413
- required_output << value
1414
- else
1415
- optional_output << value
1416
- end
1417
- end
1468
+ # these are aliased (appear under several names)
1469
+ ALIAS = ["crop"]
1470
+
1471
+ # turn a gtype into a ruby type name
1472
+ def self.gtype_to_ruby gtype
1473
+ fundamental = GObject::g_type_fundamental gtype
1474
+ type_name = GObject::g_type_name gtype
1475
+
1476
+ if MAP_GO_TO_RUBY.include? type_name
1477
+ type_name = MAP_GO_TO_RUBY[type_name]
1478
+ end
1479
+
1480
+ if fundamental == GObject::GFLAGS_TYPE ||
1481
+ fundamental == GObject::GENUM_TYPE
1482
+ type_name = "Vips::" + type_name[/Vips(.*)/, 1]
1418
1483
  end
1419
1484
 
1485
+ type_name
1486
+ end
1487
+
1488
+ def self.generate_operation introspect
1489
+ return if (introspect.flags & OPERATION_DEPRECATED) != 0
1490
+ return if NO_GENERATE.include? introspect.name
1491
+
1492
+ method_args = introspect.method_args
1493
+ required_output = introspect.required_output
1494
+ optional_input = introspect.optional_input
1495
+ optional_output = introspect.optional_output
1496
+
1420
1497
  print "# @!method "
1421
- print "self." unless member_x
1422
- print "#{nickname}("
1423
- print required_input.map { |x| x[:name] }.join(", ")
1424
- print ", " if required_input.length > 0
1498
+ print "self." unless introspect.member_x
1499
+ print "#{introspect.name}("
1500
+ print method_args.map{ |x| x[:yard_name] }.join(", ")
1501
+ print ", " if method_args.length > 0
1425
1502
  puts "**opts)"
1426
1503
 
1427
- puts "# #{description.capitalize}."
1504
+ puts "# #{introspect.description.capitalize}."
1505
+
1506
+ method_args.each do |details|
1507
+ yard_name = details[:yard_name]
1508
+ gtype = details[:gtype]
1509
+ blurb = details[:blurb]
1428
1510
 
1429
- required_input.each do |arg|
1430
- puts "# @param #{arg[:name]} [#{arg[:type_name]}] #{arg[:blurb]}"
1511
+ puts "# @param #{yard_name} [#{gtype_to_ruby(gtype)}] #{blurb}"
1431
1512
  end
1432
1513
 
1433
1514
  puts "# @param opts [Hash] Set of options"
1434
- optional_input.each do |arg|
1435
- puts "# @option opts [#{arg[:type_name]}] :#{arg[:name]} " +
1436
- "#{arg[:blurb]}"
1515
+ optional_input.each do |arg_name, details|
1516
+ yard_name = details[:yard_name]
1517
+ gtype = details[:gtype]
1518
+ blurb = details[:blurb]
1519
+
1520
+ puts "# @option opts [#{gtype_to_ruby(gtype)}] :#{yard_name} " +
1521
+ "#{blurb}"
1437
1522
  end
1438
- optional_output.each do |arg|
1439
- print "# @option opts [#{arg[:type_name]}] :#{arg[:name]}"
1440
- puts " Output #{arg[:blurb]}"
1523
+ optional_output.each do |arg_name, details|
1524
+ yard_name = details[:yard_name]
1525
+ gtype = details[:gtype]
1526
+ blurb = details[:blurb]
1527
+
1528
+ print "# @option opts [#{gtype_to_ruby(gtype)}] :#{yard_name}"
1529
+ puts " Output #{blurb}"
1441
1530
  end
1442
1531
 
1443
1532
  print "# @return ["
1444
1533
  if required_output.length == 0
1445
1534
  print "nil"
1446
1535
  elsif required_output.length == 1
1447
- print required_output.first[:type_name]
1536
+ print gtype_to_ruby(required_output.first[:gtype])
1448
1537
  else
1449
1538
  print "Array<"
1450
- print required_output.map { |x| x[:type_name] }.join(", ")
1539
+ print required_output.map{ |x| gtype_to_ruby(x[:gtype]) }.join(", ")
1451
1540
  print ">"
1452
1541
  end
1453
1542
  if optional_output.length > 0
1454
1543
  print ", Hash<Symbol => Object>"
1455
1544
  end
1456
1545
  print "] "
1457
- print required_output.map { |x| x[:blurb] }.join(", ")
1546
+ print required_output.map{ |x| x[:blurb] }.join(", ")
1458
1547
  if optional_output.length > 0
1459
1548
  print ", " if required_output.length > 0
1460
1549
  print "Hash of optional output items"
@@ -1464,30 +1553,42 @@ module Vips
1464
1553
  puts ""
1465
1554
  end
1466
1555
 
1467
- generate_class = lambda do |gtype, _|
1468
- nickname = Vips::nickname_find gtype
1556
+ def self.generate
1557
+ alias_gtypes = {}
1558
+ ALIAS.each do |name|
1559
+ gtype = Vips::type_find "VipsOperation", name
1560
+ alias_gtypes[gtype] = name
1561
+ end
1469
1562
 
1470
- if nickname
1471
- begin
1472
- # can fail for abstract types
1473
- op = Vips::Operation.new nickname
1474
- rescue Vips::Error
1475
- nil
1563
+ generate_class = lambda do |gtype, _|
1564
+ if alias_gtypes.key? gtype
1565
+ name = alias_gtypes[gtype]
1566
+ else
1567
+ name = Vips::nickname_find gtype
1476
1568
  end
1477
1569
 
1478
- generate_operation.(gtype, nickname, op) if op
1479
- end
1570
+ if name
1571
+ begin
1572
+ # can fail for abstract types
1573
+ introspect = Vips::Introspect.get_yard name
1574
+ rescue Vips::Error
1575
+ nil
1576
+ end
1480
1577
 
1481
- Vips::vips_type_map gtype, generate_class, nil
1482
- end
1578
+ generate_operation(introspect) if introspect
1579
+ end
1483
1580
 
1484
- puts "module Vips"
1485
- puts " class Image"
1486
- puts ""
1581
+ Vips::vips_type_map gtype, generate_class, nil
1582
+ end
1487
1583
 
1488
- generate_class.(GObject::g_type_from_name("VipsOperation"), nil)
1584
+ puts "module Vips"
1585
+ puts " class Image"
1586
+ puts ""
1489
1587
 
1490
- puts " end"
1491
- puts "end"
1588
+ generate_class.(GObject::g_type_from_name("VipsOperation"), nil)
1589
+
1590
+ puts " end"
1591
+ puts "end"
1592
+ end
1492
1593
  end
1493
1594
  end