1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
# This module provides an interface to the top level bits of libvips
# via ruby-ffi.
#
# Author:: John Cupitt (mailto:jcupitt@gmail.com)
# License:: MIT
require "ffi"
module Vips
if Vips.at_least_libvips?(8, 9)
attach_function :vips_target_custom_new, [], :pointer
end
# A target you can attach action signal handlers to to implememt
# custom output types.
#
# For example:
#
# ```ruby
# file = File.open "some/file/name", "wb"
# target = Vips::TargetCustom.new
# target.on_write { |bytes| file.write bytes }
# image.write_to_target target, ".png"
# ```
#
# (just an example -- of course in practice you'd use {Target#new_to_file}
# to write to a named file)
class TargetCustom < Vips::Target
module TargetCustomLayout
def self.included(base)
base.class_eval do
layout :parent, Vips::Target::Struct
# rest opaque
end
end
end
class Struct < Vips::Target::Struct
include TargetCustomLayout
end
class ManagedStruct < Vips::Target::ManagedStruct
include TargetCustomLayout
end
def initialize
pointer = Vips.vips_target_custom_new
raise Vips::Error if pointer.null?
super pointer
end
# The block is executed to write data to the source. The interface is
# exactly as IO::write, ie. it should write the string and return the
# number of bytes written.
#
# @yieldparam bytes [String] Write these bytes to the file
# @yieldreturn [Integer] The number of bytes written, or -1 on error
def on_write &block
signal_connect "write" do |p, len|
chunk = p.get_bytes(0, len)
bytes_written = block.call chunk
chunk.clear
bytes_written
end
end
# The block is executed at the end of write. It should do any necessary
# finishing action, such as closing a file.
def on_finish &block
signal_connect "finish" do
block.call
end
end
end
end
|