## VipsOperation VipsOperation — the VIPS operation base object class |

## Stability Level

Stable, unless otherwise indicated

## Functions

gboolean | (*VipsOperationBuildFn) ()
VipsOperationFlags | vips_operation_get_flags ()
void | vips_operation_class_print_usage ()
void | vips_operation_invalidate ()
int | vips_operation_call_valist ()
VipsOperation * | vips_operation_new ()
int | vips_call_required_optional ()
int | vips_call ()
int | vips_call_split ()
int | vips_call_split_option_string ()
void | vips_call_options ()
int | vips_call_argv ()
void | vips_cache_drop_all ()
int | vips_cache_operation_buildp ()
VipsOperation * | vips_cache_operation_build ()
void | vips_cache_print ()
void | vips_cache_set_max ()
void | vips_cache_set_max_mem ()
int | vips_cache_get_max ()
int | vips_cache_get_size ()
size_t | vips_cache_get_max_mem ()
int | vips_cache_get_max_files ()
void | vips_cache_set_max_files ()
void | vips_cache_set_dump ()
void | vips_cache_set_trace ()
void | vips_concurrency_set ()
int | vips_concurrency_get ()
void | vips_operation_block_set ()

## Signals

void | invalidate | Run Last

## Types and Values

enum | VipsOperationFlags

## Object Hierarchy

        GFlags
        ╰── VipsOperationFlags
        GObject
        ╰── VipsObject
            ╰── VipsOperation
                ╰── VipsForeign

## Includes

    #include <vips/vips.h>

## Description

The VipsOperation class and associated types and macros.

VipsOperation is the base class for all operations in libvips. It builds on VipsObject to provide the introspection and command-line interface to libvips.

It also maintains a cache of recent operations. See below.

vips_call(), `vips_call_split()` and `vips_call_split_option_string()` are used by vips to implement the C API. They can execute any VipsOperation, passing in a set of required and optional arguments. Normally you would not use these functions directly: every operation has a tiny wrapper function which provides type-safety for the required arguments. For example, `vips_embed()` is defined as:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int
    vips_embed(VipsImage *in, VipsImage **out,
        int x, int y, int width, int height, ...)
    {
        va_list ap;
        int result;

        va_start(ap, height);
        result = vips_call_split("embed", ap, in, out, x, y, width, height);
        va_end(ap);

        return result;
    }

Use `vips_call_argv()` to run any vips operation from a command-line style argc/argv array. This is the thing used by the vips main program to implement the vips command-line interface.

#### VipsOperation and reference counting

After calling a VipsOperation you are responsible for unreffing any output objects. For example, consider:

    1
    2
    3
    4
    5
    VipsImage *im = ...;
    VipsImage *t1;

    if (vips_invert(im, &t1, NULL))
      error ..

This will invert `im` and return a new VipsImage, `t1` . As the caller of `vips_invert()`, you are responsible for `t1` and must unref it when you no longer need it. If `vips_invert()` fails, no `t1` is returned and you don't need to do anything.

If you don't need to use `im` for another operation, you can unref `im` immediately after the call. If `im` is needed to calculate `t1` , `vips_invert()` will add a ref to `im` and automatically drop it when `t1` is unreffed.

Consider running two operations, one after the other. You could write:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    VipsImage *im = ...;
    VipsImage *t1, *t2;

    if (vips_invert(im, &t1, NULL)) {
        g_object_unref(im);
        return -1;
    }
    g_object_unref(im);

    if (vips_flip(t1, &t2, VIPS_DIRECTION_HORIZONTAL, NULL)) {
        g_object_unref(t1);
        return -1;
    }
    g_object_unref(t1);

This is correct, but rather long-winded. libvips provides a handy thing to make a vector of auto-freeing object references. You can write this as:

    1
    2
    3
    4
    5
    6
    7
    VipsObject *parent = ...;
    VipsImage *im = ...;
    VipsImage *t = (VipsImage **) vips_object_local_array(parent, 2);

    if (vips_invert(im, &t[0], NULL) ||
        vips_flip(t[0], &t[1], VIPS_DIRECTION_HORIZONTAL, NULL))
      return -1;

where `parent` is some enclosing object which will be unreffed when this task is complete. `vips_object_local_array()` makes an array of VipsObject (or VipsImage, in this case) where when `parent` is freed, all non-NULL VipsObject in the array are also unreffed.

#### The VipsOperation cache

Because all VipsObject are immutable, they can be cached. The cache is very simple to use: instead of calling `vips_object_build()`, call `vips_cache_operation_build()`. This function calculates a hash from the operations's input arguments and looks it up in table of all recent operations. If there's a hit, the new operation is unreffed, the old operation reffed, and the old operation returned in place of the new one.

The cache size is controlled with `vips_cache_set_max()` and friends.

## Functions

### VipsOperationBuildFn ()

    gboolean
    (*VipsOperationBuildFn) (VipsObject *object);

### vips_operation_get_flags ()

    VipsOperationFlags
    vips_operation_get_flags (VipsOperation *operation);

Returns the set of flags for this operation.

#### Parameters

operation | operation to fetch flags from |

#### Returns

0 on success, or -1 on error.

### vips_operation_class_print_usage ()

    void
    vips_operation_class_print_usage (VipsOperationClass *operation_class);

Print a usage message for the operation to stdout.

[skip]

#### Parameters

operation_class | class to print usage for |

### vips_operation_invalidate ()

    void
    vips_operation_invalidate (VipsOperation *operation);

### vips_operation_call_valist ()

    int
    vips_operation_call_valist (VipsOperation *operation,
                                va_list ap);

### vips_operation_new ()

    VipsOperation *
    vips_operation_new (const char *name);

Return a new VipsOperation with the specified nickname. Useful for language bindings.

You'll need to set any arguments and build the operation before you can use it. See `vips_call()` for a higher-level way to make new operations.

[constructor]

#### Parameters

name | nickname of operation to create |

#### Returns

the new operation.

[transfer full]

### vips_call_required_optional ()

    int
    vips_call_required_optional (VipsOperation **operation,
                                 va_list required,
                                 va_list optional);

This is the main entry point for the C and C++ varargs APIs. `operation` is executed, supplying `required` and `optional` arguments.

Beware, this can change `operation` to point at an old, cached one.

#### Parameters

operation | the operation to execute |
required | `va_list` of required arguments |
optional | NULL-terminated `va_list` of name / value pairs |

#### Returns

0 on success, -1 on error

### vips_call ()

    int
    vips_call (const char *operation_name,
               ...);

vips_call() calls the named operation, passing in required arguments and then setting any optional ones from the remainder of the arguments as a set of name/value pairs.

For example, `vips_embed()` takes six required arguments, `in` , `out` , `x` , `y` , `width` , `height` , and has two optional arguments, `extend` and `background` . You can run it with `vips_call()` like this:

    1
    2
    3
    4
    5
    6
    7
    VipsImage *in = ...
    VipsImage *out;

    if (vips_call("embed", in, &out, 10, 10, 100, 100,
            "extend", VIPS_EXTEND_COPY,
            NULL))
        ... error

Normally of course you'd just use the `vips_embed()` wrapper function and get type-safety for the required arguments.

See also: `vips_call_split()`, `vips_call_options()`.

#### Parameters

operation_name | name of operation to call |
... | required args, then a `NULL`-terminated list of argument/value pairs |

#### Returns

0 on success, -1 on error

### vips_call_split ()

    int
    vips_call_split (const char *operation_name,
                     va_list optional,
                     ...);

### vips_call_split_option_string ()

    int
    vips_call_split_option_string (const char *operation_name,
                                   const char *option_string,
                                   va_list optional,
                                   ...);

### vips_call_options ()

    void
    vips_call_options (GOptionGroup *group,
                       VipsOperation *operation);

### vips_call_argv ()

    int
    vips_call_argv (VipsOperation *operation,
                    int argc,
                    char **argv);

### vips_cache_drop_all ()

    void
    vips_cache_drop_all (void);

Drop the whole operation cache, handy for leak tracking. Also called automatically on `vips_shutdown()`.

### vips_cache_operation_buildp ()

    int
    vips_cache_operation_buildp (VipsOperation **operation);

Look up `operation` in the cache. If we get a hit, unref `operation` , ref the old one and return that through the argument pointer.

If we miss, build and add `operation` .

Operators that have been tagged as invalid by the `invalidate` signal are removed from cache.

Operators with the VIPS_OPERATION_BLOCKED flag are never executed.

Operators with the VIPS_OPERATION_REVALIDATE flag are always executed and any old cache value is replaced.

Operators with the VIPS_OPERATION_NOCACHE flag are never cached.

[skip]

#### Parameters

operation | pointer to operation to lookup |

#### Returns

0 on success, or -1 on error.

### vips_cache_operation_build ()

    VipsOperation *
    vips_cache_operation_build (VipsOperation *operation);

A binding-friendly version of `vips_cache_operation_buildp()`.

After calling this, `operation` has the same ref count as when it went in, and the result must be freed with `vips_object_unref_outputs()` and `g_object_unref()`.

#### Parameters

operation | operation to lookup. | [transfer none]

#### Returns

The built operation.

[transfer full]

### vips_cache_print ()

    void
    vips_cache_print (void);

Print the whole operation cache to stdout. Handy for debugging.

### vips_cache_set_max ()

    void
    vips_cache_set_max (int max);

Set the maximum number of operations we keep in cache.

#### Parameters

max | maximum number of operation to cache |

### vips_cache_set_max_mem ()

    void
    vips_cache_set_max_mem (size_t max_mem);

Set the maximum amount of tracked memory we allow before we start dropping cached operations. See `vips_tracked_get_mem()`.

libvips only tracks memory it allocates, it can't track memory allocated by external libraries. If you use an operation like `vips_magickload()`, most of the memory it uses won't be included.

See also: `vips_tracked_get_mem()`.

#### Parameters

max_mem | maximum amount of tracked memory we use |

### vips_cache_get_max ()

    int
    vips_cache_get_max (void);

Get the maximum number of operations we keep in cache.

#### Returns

the maximum number of operations we keep in cache

### vips_cache_get_size ()

    int
    vips_cache_get_size (void);

Get the current number of operations in cache.

#### Returns

get the current number of operations in cache.

### vips_cache_get_max_mem ()

    size_t
    vips_cache_get_max_mem (void);

Get the maximum amount of tracked memory we allow before we start dropping cached operations. See `vips_tracked_get_mem()`.

See also: `vips_tracked_get_mem()`.

#### Returns

the maximum amount of tracked memory we allow

### vips_cache_get_max_files ()

    int
    vips_cache_get_max_files (void);

Get the maximum number of tracked files we allow before we start dropping cached operations. See `vips_tracked_get_files()`.

libvips only tracks file descriptors it allocates, it can't track ones allocated by external libraries. If you use an operation like `vips_magickload()`, most of the descriptors it uses won't be included.

See also: `vips_tracked_get_files()`.

#### Returns

the maximum number of tracked files we allow

### vips_cache_set_max_files ()

    void
    vips_cache_set_max_files (int max_files);

Set the maximum number of tracked files we allow before we start dropping cached operations. See `vips_tracked_get_files()`.

See also: `vips_tracked_get_files()`.

#### Parameters

max_files | max open files we allow |

### vips_cache_set_dump ()

    void
    vips_cache_set_dump (gboolean dump);

Handy for debugging. Print the operation cache to stdout just before exit.

See also: `vips_cache_set_trace()`.

#### Parameters

dump | if `TRUE`, dump the operation cache on exit |

### vips_cache_set_trace ()

    void
    vips_cache_set_trace (gboolean trace);

Handy for debugging. Print operation cache actions to stdout as we run.

You can set the environment variable `VIPS_TRACE` to turn this option on, or use the command-line flag `--vips-cache-trace`.

See also: `vips_cache_set_dump()`.

#### Parameters

trace | if `TRUE`, trace the operation cache |

### vips_concurrency_set ()

    void
    vips_concurrency_set (int concurrency);

Sets the number of worker threads that vips should use when running a VipsThreadPool.

The special value 0 means "default". In this case, the number of threads is set by the environment variable VIPS_CONCURRENCY, or if that is not set, the number of threads available on the host machine.

See also: `vips_concurrency_get()`.

#### Parameters

concurrency | number of threads to run |

### vips_concurrency_get ()

    int
    vips_concurrency_get (void);

Returns the number of worker threads that vips should use when running a VipsThreadPool.

vips gets this values from these sources in turn:

If `vips_concurrency_set()` has been called, this value is used. The special value 0 means "default". You can also use the command-line argument "--vips-concurrency" to set this value.

If `vips_concurrency_set()` has not been called and no command-line argument was used, vips uses the value of the environment variable VIPS_CONCURRENCY,

If VIPS_CONCURRENCY has not been set, vips finds the number of hardware threads that the host machine can run in parallel and uses that value.

The final value is clipped to the range 1 - 1024.

See also: `vips_concurrency_get()`.

#### Returns

number of worker threads to use.

### vips_operation_block_set ()

    void
    vips_operation_block_set (const char *name,
                              gboolean state);

Set the block state on all operations in the libvips class hierarchy at `name` and below.

For example:

    1
    2
    vips_operation_block_set("VipsForeignLoad", TRUE);
    vips_operation_block_set("VipsForeignLoadJpeg", FALSE);

Will block all load operations, except JPEG.

Use `vips -l` at the command-line to see the class hierarchy.

This call does nothing if the named operation is not found.

See also: `vips_block_untrusted_set()`.

#### Parameters

name | set block state at this point and below |
state | the block state to set |

## Types and Values

### enum VipsOperationFlags

Flags we associate with an operation.

`VIPS_OPERATION_SEQUENTIAL` means that the operation works like `vips_conv()`: it can process images top-to-bottom with only small non-local references.

Every scan-line must be requested, you are not allowed to skip ahead, but as a special case, the very first request can be for a region not at the top of the image. In this case, the first part of the image will be read and discarded

Every scan-line must be requested, you are not allowed to skip ahead, but as a special case, the very first request can be for a region not at the top of the image. In this case, the first part of the image will be read and discarded

`VIPS_OPERATION_NOCACHE` means that the operation must not be cached by vips.

`VIPS_OPERATION_DEPRECATED` means this is an old operation kept in vips for compatibility only and should be hidden from users.

`VIPS_OPERATION_UNTRUSTED` means the operation depends on external libraries which have not been hardened against attack. It should probably not be used on untrusted input. Use `vips_block_untrusted_set()` to block all untrusted operations.

`VIPS_OPERATION_BLOCKED` means the operation is prevented from executing. Use `vips_operation_block_set()` to enable and disable groups of operations.

`VIPS_OPERATION_REVALIDATE` force the operation to run, updating the cache with the new value. This is used by eg. VipsForeignLoad to implement the "revalidate" argument.

#### Members

VIPS_OPERATION_NONE | no flags |
VIPS_OPERATION_SEQUENTIAL | can work sequentially with a small buffer |
VIPS_OPERATION_SEQUENTIAL_UNBUFFERED |  |
VIPS_OPERATION_NOCACHE | must not be cached |
VIPS_OPERATION_DEPRECATED | a compatibility thing |
VIPS_OPERATION_UNTRUSTED | not hardened for untrusted input |
VIPS_OPERATION_BLOCKED | prevent this operation from running |
VIPS_OPERATION_REVALIDATE | force the operation to run |

## Signal Details

### The `“invalidate”` signal

    void
    user_function (VipsOperation *vipsoperation,
                   gpointer       user_data)

Flags: Run Last

## See Also

object