ruby-vips 1.0.2 → 1.0.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/VERSION +1 -1
- data/lib/vips/call.rb +234 -170
- data/lib/vips/image.rb +48 -18
- data/lib/vips/interpolate.rb +2 -2
- data/lib/vips/kernel.rb +22 -0
- data/lib/vips/methods.rb +269 -119
- data/lib/vips/version.rb +1 -1
- data/ruby-vips.gemspec +6 -3
- metadata +9 -9
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f9821647ddcaaa31442cb2f6ce3b488004bfecd1
         | 
| 4 | 
            +
              data.tar.gz: 77f02bd4c937b0b08d78419878728a2d62e47293
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a7e07153fe581bb27cb56533e3274abdb3dca1bcc95e33e964606c35ed8aa3ad1007131fee4d2d5543bc704dc52ec52ff90f160ee71da996d2f59fc74b90a3e0
         | 
| 7 | 
            +
              data.tar.gz: 865c2cc4d66b7ea6359225f36f9ae6c17274e1c4e0c34f54efc0a6cdce457cbe72fdb7388692b6c5836ef4c24ee243d26b9d1b9383078d0d2d38b2e65a441384
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,6 +1,15 @@ | |
| 1 1 | 
             
            # master 
         | 
| 2 2 |  | 
| 3 | 
            -
            # Version 1.0. | 
| 3 | 
            +
            # Version 1.0.3
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * doc improvements [John Cupitt]
         | 
| 6 | 
            +
            * add #size to get [width, height] [John Cupitt]
         | 
| 7 | 
            +
            * only ask for ruby 2.0 to help OS X [John Cupitt] 
         | 
| 8 | 
            +
            * break up Image.call to make it easier to understand [John Cupitt] 
         | 
| 9 | 
            +
            * detect operation build fail correctly [John Cupitt]
         | 
| 10 | 
            +
            * lock gobject-introspection at 3.0.8 to avoid breakage [John Cupitt]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            # Version 1.0.2
         | 
| 4 13 |  | 
| 5 14 | 
             
            * add .yardopts to fix ruby-gems docs [John Cupitt]
         | 
| 6 15 |  | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            1.0. | 
| 1 | 
            +
            1.0.3
         | 
    
        data/lib/vips/call.rb
    CHANGED
    
    | @@ -1,225 +1,281 @@ | |
| 1 1 | 
             
            module Vips
         | 
| 2 2 |  | 
| 3 | 
            -
                #  | 
| 4 | 
            -
                # I've really no idea why :-(
         | 
| 3 | 
            +
                # Call a vips operation.
         | 
| 5 4 | 
             
                #
         | 
| 6 | 
            -
                #  | 
| 7 | 
            -
                #  | 
| 5 | 
            +
                # This will crash if there's a GC during the call, only use 
         | 
| 6 | 
            +
                # this via {Vips.call}. 
         | 
| 7 | 
            +
                private 
         | 
| 8 | 
            +
                class Call
         | 
| 9 | 
            +
                    attr_writer :instance, :option_string
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    def initialize(name, supplied_values)
         | 
| 12 | 
            +
                        @name = name
         | 
| 13 | 
            +
                        @supplied_values = supplied_values
         | 
| 14 | 
            +
                        @instance = nil
         | 
| 15 | 
            +
                        @option_string = nil
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                        if @supplied_values.last.is_a? Hash
         | 
| 18 | 
            +
                            @optional_values = @supplied_values.last
         | 
| 19 | 
            +
                            @supplied_values.delete_at -1
         | 
| 20 | 
            +
                        else
         | 
| 21 | 
            +
                            @optional_values = {}
         | 
| 22 | 
            +
                        end
         | 
| 8 23 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
                    log "option_string = #{option_string}"
         | 
| 15 | 
            -
                    log "supplied_values are:"
         | 
| 16 | 
            -
                    supplied_values.each {|x| log "   #{x}"}
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    if supplied_values.last.is_a? Hash
         | 
| 19 | 
            -
                        optional_values = supplied_values.last
         | 
| 20 | 
            -
                        supplied_values.delete_at -1
         | 
| 21 | 
            -
                    else
         | 
| 22 | 
            -
                        optional_values = {}
         | 
| 23 | 
            -
                    end
         | 
| 24 | 
            +
                        begin
         | 
| 25 | 
            +
                            @op = Vips::Operation.new @name
         | 
| 26 | 
            +
                        rescue
         | 
| 27 | 
            +
                            raise Vips::Error, "no operator '#{@name}'"
         | 
| 28 | 
            +
                        end
         | 
| 24 29 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
                         | 
| 27 | 
            -
             | 
| 28 | 
            -
                         | 
| 30 | 
            +
                        log "Vips::Call.init"
         | 
| 31 | 
            +
                        log "name = #{@name}"
         | 
| 32 | 
            +
                        log "supplied_values are:"
         | 
| 33 | 
            +
                        @supplied_values.each {|x| log "   #{x}"}
         | 
| 34 | 
            +
                        log "optional_values are:"
         | 
| 35 | 
            +
                        @optional_values.each {|x| log "   #{x}"}
         | 
| 29 36 | 
             
                    end
         | 
| 30 37 |  | 
| 31 | 
            -
                    # set string options  | 
| 32 | 
            -
                     | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 38 | 
            +
                    # set any string options on the operation
         | 
| 39 | 
            +
                    def set_string_args
         | 
| 40 | 
            +
                        if @option_string
         | 
| 41 | 
            +
                            log "setting string options #{@option_string} ..."
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                            if @op.set_from_string(@option_string) != 0
         | 
| 44 | 
            +
                                raise Error
         | 
| 45 | 
            +
                            end
         | 
| 36 46 | 
             
                        end
         | 
| 37 47 | 
             
                    end
         | 
| 38 48 |  | 
| 39 | 
            -
                     | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 49 | 
            +
                    # set @match_image to be the image we build constants to match
         | 
| 50 | 
            +
                    def find_match_image
         | 
| 51 | 
            +
                        # the instance, if supplied, must be a vips image ... we use it for
         | 
| 52 | 
            +
                        # match_image, below
         | 
| 53 | 
            +
                        if @instance and not @instance.is_a? Vips::Image
         | 
| 54 | 
            +
                            raise Vips::Error, "@instance is not a Vips::Image."
         | 
| 55 | 
            +
                        end
         | 
| 46 56 |  | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
                    if match_image == nil
         | 
| 56 | 
            -
                        match = optional_values.find do |name, value|
         | 
| 57 | 
            -
                            value.is_a? Vips::Image
         | 
| 57 | 
            +
                        # if the op needs images but the user supplies constants, we expand
         | 
| 58 | 
            +
                        # them to match the first input image argument ... find the first
         | 
| 59 | 
            +
                        # image
         | 
| 60 | 
            +
                        log "searching for first image argument ..."
         | 
| 61 | 
            +
                        match_image = @instance
         | 
| 62 | 
            +
                        if match_image == nil
         | 
| 63 | 
            +
                            match_image = @supplied_values.find {|x| x.is_a? Vips::Image}
         | 
| 58 64 | 
             
                        end
         | 
| 59 | 
            -
                         | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 65 | 
            +
                        if match_image == nil
         | 
| 66 | 
            +
                            match = @optional_values.find do |name, value|
         | 
| 67 | 
            +
                                value.is_a? Vips::Image
         | 
| 68 | 
            +
                            end
         | 
| 69 | 
            +
                            # if we found a match, it'll be [name, value]
         | 
| 70 | 
            +
                            if match
         | 
| 71 | 
            +
                                match_image = match[1]
         | 
| 72 | 
            +
                            end
         | 
| 62 73 | 
             
                        end
         | 
| 63 | 
            -
                    end
         | 
| 64 74 |  | 
| 65 | 
            -
             | 
| 66 | 
            -
                    log "finding unassigned required input arguments ..."
         | 
| 67 | 
            -
                    required_input = all_args.select do |arg|
         | 
| 68 | 
            -
                        not arg.isset and
         | 
| 69 | 
            -
                        (arg.flags & :input) != 0 and
         | 
| 70 | 
            -
                        (arg.flags & :required) != 0 
         | 
| 75 | 
            +
                        return match_image
         | 
| 71 76 | 
             
                    end
         | 
| 72 77 |  | 
| 73 | 
            -
                    #  | 
| 74 | 
            -
                     | 
| 75 | 
            -
             | 
| 76 | 
            -
                         | 
| 77 | 
            -
                            gtype = GLib::Type["VipsImage"]
         | 
| 78 | 
            -
                            vtype = arg.prop.value_type
         | 
| 78 | 
            +
                    # look through the operation args and find required and optional 
         | 
| 79 | 
            +
                    # input args
         | 
| 80 | 
            +
                    def find_input
         | 
| 81 | 
            +
                        all_args = @op.get_args
         | 
| 79 82 |  | 
| 80 | 
            -
             | 
| 83 | 
            +
                        # find unassigned required input args
         | 
| 84 | 
            +
                        log "finding unassigned required input arguments ..."
         | 
| 85 | 
            +
                        required_input = all_args.select do |arg|
         | 
| 86 | 
            +
                            not arg.isset and
         | 
| 87 | 
            +
                            (arg.flags & :input) != 0 and
         | 
| 88 | 
            +
                            (arg.flags & :required) != 0 
         | 
| 81 89 | 
             
                        end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 90 | 
            +
             | 
| 91 | 
            +
                        # find optional unassigned input args
         | 
| 92 | 
            +
                        log "finding optional unassigned input arguments ..."
         | 
| 93 | 
            +
                        optional_input = all_args.select do |arg|
         | 
| 94 | 
            +
                            not arg.isset and
         | 
| 95 | 
            +
                            (arg.flags & :input) != 0 and
         | 
| 96 | 
            +
                            (arg.flags & :required) == 0 
         | 
| 85 97 | 
             
                        end
         | 
| 86 | 
            -
                        x.set_value match_image, instance
         | 
| 87 | 
            -
                        required_input.delete x
         | 
| 88 | 
            -
                    end
         | 
| 89 98 |  | 
| 90 | 
            -
             | 
| 91 | 
            -
                         | 
| 92 | 
            -
                             | 
| 93 | 
            -
                            "#{required_input.length} arguments, you supplied " +
         | 
| 94 | 
            -
                            "#{supplied_values.length}."
         | 
| 95 | 
            -
                    end
         | 
| 99 | 
            +
                        # make a hash from name to arg for the options
         | 
| 100 | 
            +
                        optional_input = Hash[
         | 
| 101 | 
            +
                            optional_input.map(&:name).zip(optional_input)]
         | 
| 96 102 |  | 
| 97 | 
            -
             | 
| 98 | 
            -
                    required_input.zip(supplied_values).each do |arg, value|
         | 
| 99 | 
            -
                        arg.set_value match_image, value
         | 
| 103 | 
            +
                        return required_input, optional_input
         | 
| 100 104 | 
             
                    end
         | 
| 101 105 |  | 
| 102 | 
            -
                     | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
                         | 
| 106 | 
            -
                         | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 106 | 
            +
                    def find_optional_output
         | 
| 107 | 
            +
                        all_args = @op.get_args
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                        log "finding optional output arguments ..."
         | 
| 110 | 
            +
                        optional_output = all_args.select do |arg|
         | 
| 111 | 
            +
                            (arg.flags & :output) != 0 and
         | 
| 112 | 
            +
                            (arg.flags & :required) == 0 
         | 
| 113 | 
            +
                        end
         | 
| 114 | 
            +
                        optional_output = Hash[
         | 
| 115 | 
            +
                            optional_output.map(&:name).zip(optional_output)]
         | 
| 109 116 |  | 
| 110 | 
            -
             | 
| 111 | 
            -
                    optional_input = Hash[
         | 
| 112 | 
            -
                        optional_input.map(&:name).zip(optional_input)]
         | 
| 117 | 
            +
                        return optional_output
         | 
| 113 118 |  | 
| 114 | 
            -
                    # find optional unassigned output args
         | 
| 115 | 
            -
                    log "finding optional unassigned output arguments ..."
         | 
| 116 | 
            -
                    optional_output = all_args.select do |arg|
         | 
| 117 | 
            -
                        not arg.isset and
         | 
| 118 | 
            -
                        (arg.flags & :output) != 0 and
         | 
| 119 | 
            -
                        (arg.flags & :required) == 0 
         | 
| 120 119 | 
             
                    end
         | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
             | 
| 131 | 
            -
                             | 
| 132 | 
            -
             | 
| 120 | 
            +
             | 
| 121 | 
            +
                    def set_required_input(match_image, required_input)
         | 
| 122 | 
            +
                        # do we have a non-nil instance? set the first image arg with this
         | 
| 123 | 
            +
                        if @instance != nil
         | 
| 124 | 
            +
                            log "setting first image arg with instance ..."
         | 
| 125 | 
            +
                            x = required_input.find do |arg|
         | 
| 126 | 
            +
                                gtype = GLib::Type["VipsImage"]
         | 
| 127 | 
            +
                                vtype = arg.prop.value_type
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                                vtype.type_is_a? gtype
         | 
| 130 | 
            +
                            end
         | 
| 131 | 
            +
                            if x == nil
         | 
| 132 | 
            +
                                raise Vips::Error, 
         | 
| 133 | 
            +
                                    "No #{@instance.class} argument to #{@name}."
         | 
| 134 | 
            +
                            end
         | 
| 135 | 
            +
                            x.set_value match_image, @instance
         | 
| 136 | 
            +
                            required_input.delete x
         | 
| 137 | 
            +
                        end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                        if required_input.length != @supplied_values.length
         | 
| 133 140 | 
             
                            raise Vips::Error, 
         | 
| 134 | 
            -
                                " | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 141 | 
            +
                                "Wrong number of arguments. '#{@name}' requires " +
         | 
| 142 | 
            +
                                "#{required_input.length} arguments, you supplied " +
         | 
| 143 | 
            +
                                "#{@supplied_values.length}."
         | 
| 144 | 
            +
                        end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                        log "setting required input arguments ..."
         | 
| 147 | 
            +
                        required_input.zip(@supplied_values).each do |arg, value|
         | 
| 148 | 
            +
                            arg.set_value match_image, value
         | 
| 149 | 
            +
                        end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                    end       
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                    def set_optional_input(match_image, optional_input, optional_output)
         | 
| 154 | 
            +
                        log "setting optional input args ..."
         | 
| 155 | 
            +
                        @optional_values.each do |name, value|
         | 
| 156 | 
            +
                            # we are passed symbols as keys
         | 
| 157 | 
            +
                            name = name.to_s
         | 
| 158 | 
            +
                            if optional_input.has_key? name
         | 
| 159 | 
            +
                                log "setting #{name} to #{value}"
         | 
| 160 | 
            +
                                optional_input[name].set_value match_image, value
         | 
| 161 | 
            +
                            elsif optional_output.has_key? name and value != true
         | 
| 162 | 
            +
                                raise Vips::Error, 
         | 
| 163 | 
            +
                                    "Optional output argument #{name} must be true."
         | 
| 164 | 
            +
                            elsif not optional_output.has_key? name 
         | 
| 165 | 
            +
                                raise Vips::Error, "No such option '#{name}',"
         | 
| 166 | 
            +
                            end
         | 
| 137 167 | 
             
                        end
         | 
| 138 168 | 
             
                    end
         | 
| 139 169 |  | 
| 140 | 
            -
                     | 
| 170 | 
            +
                    def build
         | 
| 171 | 
            +
                        log "building ..."
         | 
| 141 172 |  | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
                        op = op2
         | 
| 173 | 
            +
                        op2 = Vips::cache_operation_lookup @op
         | 
| 174 | 
            +
                        if op2
         | 
| 175 | 
            +
                            log "cache hit"
         | 
| 146 176 |  | 
| 147 | 
            -
             | 
| 177 | 
            +
                            hit = true
         | 
| 178 | 
            +
                            @op = op2
         | 
| 179 | 
            +
                        else
         | 
| 180 | 
            +
                            log "cache miss ... building"
         | 
| 148 181 |  | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
                             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
                             | 
| 156 | 
            -
             | 
| 157 | 
            -
                        log "cache miss ... building"
         | 
| 158 | 
            -
                        if not op.build
         | 
| 159 | 
            -
                            raise Vips::Error
         | 
| 182 | 
            +
                            hit = false
         | 
| 183 | 
            +
                            if @op.build() != 0
         | 
| 184 | 
            +
                                raise Vips::Error
         | 
| 185 | 
            +
                            end
         | 
| 186 | 
            +
                            # showall
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                            log "adding to cache ... "
         | 
| 189 | 
            +
                            Vips::cache_operation_add @op
         | 
| 160 190 | 
             
                        end
         | 
| 161 | 
            -
                        showall
         | 
| 162 191 |  | 
| 163 | 
            -
                         | 
| 164 | 
            -
                        Vips::cache_operation_add op
         | 
| 192 | 
            +
                        return hit
         | 
| 165 193 | 
             
                    end
         | 
| 166 194 |  | 
| 167 | 
            -
                     | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 195 | 
            +
                    def fetch_output(optional_output)
         | 
| 196 | 
            +
                        log "fetching outputs ..."
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                        # gather output args 
         | 
| 199 | 
            +
                        out = []
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                        all_args = @op.get_args
         | 
| 202 | 
            +
                        all_args.each do |arg|
         | 
| 203 | 
            +
                            # required output
         | 
| 204 | 
            +
                            if (arg.flags & :output) != 0 and
         | 
| 205 | 
            +
                                (arg.flags & :required) != 0 
         | 
| 206 | 
            +
                                log "fetching required output #{arg.name}"
         | 
| 207 | 
            +
                                out << arg.get_value
         | 
| 208 | 
            +
                            end
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                            # modified input arg ... this will get the result of the 
         | 
| 211 | 
            +
                            # copy() we did in Argument.set_value 
         | 
| 212 | 
            +
                            if (arg.flags & :input) != 0 and
         | 
| 213 | 
            +
                                (arg.flags & :modify) != 0 
         | 
| 214 | 
            +
                                log "fetching modified input arg ..."
         | 
| 215 | 
            +
                                out << arg.get_value
         | 
| 216 | 
            +
                            end
         | 
| 217 | 
            +
                        end
         | 
| 171 218 |  | 
| 172 | 
            -
             | 
| 173 | 
            -
                         | 
| 174 | 
            -
             | 
| 175 | 
            -
                             | 
| 176 | 
            -
                             | 
| 177 | 
            -
             | 
| 219 | 
            +
                        opts = {}
         | 
| 220 | 
            +
                        @optional_values.each do |name, value|
         | 
| 221 | 
            +
                            # we are passed symbols as keys
         | 
| 222 | 
            +
                            name = name.to_s
         | 
| 223 | 
            +
                            if optional_output.has_key? name
         | 
| 224 | 
            +
                                log "fetching optional output arg ..."
         | 
| 225 | 
            +
                                opts[name] = optional_output[name].get_value
         | 
| 226 | 
            +
                            end
         | 
| 178 227 | 
             
                        end
         | 
| 228 | 
            +
                        out << opts if opts != {}
         | 
| 179 229 |  | 
| 180 | 
            -
                         | 
| 181 | 
            -
             | 
| 182 | 
            -
                         | 
| 183 | 
            -
                             | 
| 184 | 
            -
                            log "fetching modified input arg ..."
         | 
| 185 | 
            -
                            out << arg.get_value
         | 
| 230 | 
            +
                        if out.length == 1
         | 
| 231 | 
            +
                            out = out[0]
         | 
| 232 | 
            +
                        elsif out.length == 0
         | 
| 233 | 
            +
                            out = nil
         | 
| 186 234 | 
             
                        end
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                        return out
         | 
| 237 | 
            +
             | 
| 187 238 | 
             
                    end
         | 
| 188 239 |  | 
| 189 | 
            -
                     | 
| 190 | 
            -
             | 
| 191 | 
            -
                         | 
| 192 | 
            -
                         | 
| 193 | 
            -
                         | 
| 194 | 
            -
             | 
| 195 | 
            -
             | 
| 240 | 
            +
                    def invoke
         | 
| 241 | 
            +
                        set_string_args()
         | 
| 242 | 
            +
                        match_image = find_match_image()
         | 
| 243 | 
            +
                        required_input, optional_input = find_input()
         | 
| 244 | 
            +
                        optional_output = find_optional_output()
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                        set_required_input(match_image, required_input)
         | 
| 247 | 
            +
                        set_optional_input(match_image, optional_input, optional_output)
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                        hit = build()
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                        # if there was a cache hit, we need to refind this since all the arg
         | 
| 252 | 
            +
                        # pointers will have changed
         | 
| 253 | 
            +
                        if hit
         | 
| 254 | 
            +
                            optional_output = find_optional_output()
         | 
| 196 255 | 
             
                        end
         | 
| 197 | 
            -
             | 
| 198 | 
            -
                    out << opts if opts != {}
         | 
| 256 | 
            +
                        out = fetch_output(optional_output)
         | 
| 199 257 |  | 
| 200 | 
            -
             | 
| 201 | 
            -
                         | 
| 202 | 
            -
             | 
| 203 | 
            -
                         | 
| 204 | 
            -
                    end
         | 
| 258 | 
            +
                        log "unreffing outputs ..."
         | 
| 259 | 
            +
                        @op.unref_outputs()
         | 
| 260 | 
            +
                        @op = nil
         | 
| 261 | 
            +
                        # showall
         | 
| 205 262 |  | 
| 206 | 
            -
             | 
| 207 | 
            -
                    op.unref_outputs
         | 
| 208 | 
            -
                    op = nil
         | 
| 209 | 
            -
                    # showall
         | 
| 263 | 
            +
                        log "success! #{@name}.out = #{out}"
         | 
| 210 264 |  | 
| 211 | 
            -
             | 
| 265 | 
            +
                        return out
         | 
| 266 | 
            +
                    end
         | 
| 212 267 |  | 
| 213 | 
            -
                    return out
         | 
| 214 268 | 
             
                end
         | 
| 215 269 |  | 
| 216 | 
            -
                #  | 
| 270 | 
            +
                # full-fat call, with the GC disabled
         | 
| 217 271 | 
             
                private
         | 
| 218 272 | 
             
                def self.call_base(name, instance, option_string, supplied_values)
         | 
| 219 273 | 
             
                    gc_was_enabled = GC.disable
         | 
| 220 274 | 
             
                    begin
         | 
| 221 | 
            -
                         | 
| 222 | 
            -
             | 
| 275 | 
            +
                        call = Call.new(name, supplied_values)
         | 
| 276 | 
            +
                        call.instance = instance
         | 
| 277 | 
            +
                        call.option_string = option_string
         | 
| 278 | 
            +
                        result = call.invoke
         | 
| 223 279 | 
             
                    ensure
         | 
| 224 280 | 
             
                        GC.enable if gc_was_enabled
         | 
| 225 281 | 
             
                    end
         | 
| @@ -283,7 +339,7 @@ module Vips | |
| 283 339 | 
             
                # y = x % [1]
         | 
| 284 340 | 
             
                # ```
         | 
| 285 341 | 
             
                #
         | 
| 286 | 
            -
                # Similarly,  | 
| 342 | 
            +
                # Similarly, wherever an image is required, you can use a constant. The
         | 
| 287 343 | 
             
                # constant will be expanded to an image matching the first input image
         | 
| 288 344 | 
             
                # argument. For example, you can write:
         | 
| 289 345 | 
             
                #
         | 
| @@ -296,7 +352,15 @@ module Vips | |
| 296 352 | 
             
                # the constant value 255. 
         | 
| 297 353 |  | 
| 298 354 | 
             
                def self.call(name, *args)
         | 
| 299 | 
            -
                     | 
| 355 | 
            +
                    gc_was_enabled = GC.disable
         | 
| 356 | 
            +
                    begin
         | 
| 357 | 
            +
                        call = Call.new(name, args)
         | 
| 358 | 
            +
                        result = call.invoke
         | 
| 359 | 
            +
                    ensure
         | 
| 360 | 
            +
                        GC.enable if gc_was_enabled
         | 
| 361 | 
            +
                    end
         | 
| 362 | 
            +
             | 
| 363 | 
            +
                    return result
         | 
| 300 364 | 
             
                end
         | 
| 301 365 |  | 
| 302 366 | 
             
            end
         |