class_docstr: Call libvips operations.
  
  This class wraps the libvips VipsOperation class.
class_docstr_tok: ["Call","libvips","operations",".","This","class","wraps","the","libvips","VipsOperation","class","."]
docstr: Call a libvips operation.
  
  Use this method to call any libvips operation. For example::
  
      black_image = pyvips.Operation.call('black', 10, 10)
  
  See the Introduction for notes on how this works.
docstr_tok: ["Call","a","libvips","operation",".","Use","this","method","to","call","any","libvips","operation",".","For","example",":",":","black_image","=","pyvips.Operation.call","(","'black","'",",","10",",","10",")","See","the","Introduction","for","notes","on","how","this","works","."]
code: def call(operation_name, *args, **kwargs):
      """Call a libvips operation.
  
      Use this method to call any libvips operation. For example::
  
          black_image = pyvips.Operation.call('black', 10, 10)
  
      See the Introduction for notes on how this works.
  
      """
  
      logger.debug(
          "VipsOperation.call: operation_name = %s", operation_name
      )
      # logger.debug('VipsOperation.call: args = %s, kwargs =%s',
      #              args, kwargs)
  
      intro = Introspect.get(operation_name)
  
      if len(intro.required_input) != len(args):
          raise Error(
              "{0} needs {1} arguments, but {2} given".format(
                  operation_name, len(intro.required_input), len(args)
              )
          )
  
      op = Operation.new_from_name(operation_name)
  
      # set any string options before any args so they can't be
      # overridden
      string_options = kwargs.pop("string_options", "")
      if not op.set_string(string_options):
          raise Error("unable to call {0}".format(operation_name))
  
      # the first image argument is the thing we expand constants to
      # match ... look inside tables for images, since we may be passing
      # an array of images as a single param
      match_image = _find_inside(
          lambda x: isinstance(x, pyvips.Image), args
      )
  
      logger.debug("VipsOperation.call: match_image = %s", match_image)
  
      # collect a list of all input references here
      # we can't use a set because set elements are unique under "==", and
      # Python checks memoryview equality with hash functions, not pointer
      # equality
      references = []
  
      # does a list contain an element using pointer equality
      # we can't use "in" since that uses "==", which means hash equality
      def contains(array, x):
          for y in array:
              if id(x) == id(y):
                  return True
          return False
  
      def add_reference(x):
          if isinstance(x, pyvips.Image):
              for i in x._references:
                  if not contains(references, i):
                      references.append(i)
          return False
  
      # set required input args
      for name, value in zip(intro.required_input, args):
          _find_inside(add_reference, value)
          op.set(name, intro.details[name]["flags"], match_image, value)
  
      # set any optional args
      for name in kwargs:
          if (
              name not in intro.optional_input
              and name not in intro.optional_output
          ):
              raise Error(
                  "{0} does not support optional argument {1}".format(
                      operation_name, name
                  )
              )
  
          value = kwargs[name]
          details = intro.details[name]
  
          if (details["flags"] & _DEPRECATED) != 0:
              logger.info(
                  "%s argument %s is deprecated", operation_name, name
              )
  
          _find_inside(add_reference, value)
          op.set(name, details["flags"], match_image, value)
  
      # build operation
      vop = vips_lib.vips_cache_operation_build(op.pointer)
      if vop == ffi.NULL:
          vips_lib.vips_object_unref_outputs(op.vobject)
          raise Error("unable to call {0}".format(operation_name))
      op = Operation(vop)
  
      # attach all input refs to output x
      def set_reference(x):
          if isinstance(x, pyvips.Image):
              x._references.extend(references)
          return False
  
      # fetch required output args (plus modified input images)
      result = []
      for name in intro.required_output:
          value = op.get(name)
          _find_inside(set_reference, value)
          result.append(value)
  
      # fetch optional output args
      opts = {}
      for name in intro.optional_output:
          if name in kwargs:
              value = op.get(name)
              _find_inside(set_reference, value)
              opts[name] = value
  
      if len(opts) > 0:
          result.append(opts)
  
      vips_lib.vips_object_unref_outputs(op.vobject)
  
      if len(result) == 0:
          result = None
      elif len(result) == 1:
          result = result[0]
  
      logger.debug("VipsOperation.call: result = %s", result)
  
      return result
  
imports: from __future__ import division, print_function
  import logging
  import pyvips
  from pyvips import ffi, vips_lib, Error, _to_bytes, _to_string, GValue, type_map, type_from_name, nickname_find, at_least_libvips
label_desc: Use image node_id 4 for calling the Operation obj's underlying member method code with example usage: obj.call(operation_name) and returns: result, False, False, False, True