GEGL architecture within GIMP

What is GEGL?

GEGL (Generic Graphics Library) is a data flow based (or graph-based) image processing framework.

Basically it means each filter is a node in a graph. Source nodes will have no inputs, sink nodes will have no outputs and all intermediate nodes may have 1 or more inputs and 1 output. Your original image flows through, possibly modified at each node, until a new image is created in the end.

GEGL was born around 1997 out of the GIMP project, until it got first integration in GIMP code in 2007. Nowadays it is the core engine of every image processing in GIMP and in particular allows very efficient non-destructive editing.

Among some of the very powerful features of GEGL is its efficient handling of image buffers, allowing GIMP to work on bigger-than-memory image data.

In this tutorial, you will learn how to create a filter to be used in a GEGL node, and more specifically for GIMP, it means it will be accessible in the GIMP interface, shareable and installable by others. This tutorial is not a generic tutorial on GEGL (on how to create graphs, process buffers efficiently, convert buffers from one format to another…).

GIMP-GEGL Architecture

Though GIMP is the main consumer of GEGL operations (since it originated from the GIMP project) nowadays, filters are fully installed on GEGL namespace.

Basically what happens when you start GIMP is that:

  1. GIMP loads and initialize GEGL;
  2. GEGL loads its core operations;
  3. GEGL looks up standard paths for additional (third-party) operations to load.

This is this third step which you will make use of. Each third-party filter takes the shape of a dynamic library (.so file on most UNIX-like OSes, .dll on Windows, .dylib on macOS…) with specific code inside and loaded by libgegl.

Installing Filters

Apart from the standard operations bundled with GEGL, GEGL searches for custom operations in:

  • Folders listed in the $GEGL_PATH environment variable if it exists, overriding all other standard paths.

  • The user data directory:

    • Linux and most UNIXes (except macOS, see below): $XDG_DATA_HOME/gegl-0.4/plug-ins/

      Note: this path defaults to $HOME/.local/share/gegl-0.4/plug-ins if XDG_DATA_HOME environment variable is not set (see the XDG Base Directory Specification).

    • Windows: %LOCALAPPDATA%\gegl-0.4\plug-ins

      Note 1: %LOCALAPPDATA% can be directly used in your file browser and represents the local application data.
      Very often, the directory will be: C:\Users\<UserLogin>\AppData\Local\gegl-0.4\plug-ins\

      Note 2: if the XDG_DATA_HOME environment variable is set, it is used instead of %LOCALAPPDATA%.

    • macOS: ~/Library/Application Support/gegl-0.4/plug-ins/

Just install your .so|.dll|.dylib filters in there and GEGL will see them, which means that GIMP will see them too the next time you start it!

GeglOperation class

Similarly to how GIMP API is object-oriented, this is also the case for GEGL. What will happen in your code is simply that you will create a custom subclass of GeglOperation and various GEGL macros will take care of the registration of your new class for you.

A very core feature of GEGL operations is that operations are introspectable, which is how GIMP is able to generate dialogs with descriptive texts, and widgets adapted to the various arguments.

Furthermore, GEGL has a few additional utilities which are used by GIMP for GUI generation and menu item creation.

Now there are in fact already quite a few GeglOperation subclasses. So you may be more interested into creating a sub-subclass, such as:

  • GeglOperationMeta (GEGL_OP_META) are a way to create operations simply using other operations, by basically constructing a subgraph.
  • GeglOperationFilter (GEGL_OP_FILTER) is a basic filter class. It sets up GeglBuffers for “input” and “output” pads. This class also adds infrastructure for multi-threaded operations by splitting the input into smaller buffers to process in threads.
    • GeglOperationPointFilter (GEGL_OP_POINT_FILTER) is for filters where an output pixel only depends on the color and alpha values of the corresponding input pixel. This allows you to do the processing on linear buffers.
    • GeglOperationAreaFilter (GEGL_OP_AREA_FILTER) is for operations where the output data depends on a neighbourhood with an input window that extends beyond the output window, the information about needed extra pixels in different directions should be set up in the prepare() callback for the operation.
    • GeglOperationTemporal (GEGL_OP_TEMPORAL) are operations that want access to previous frames in a video sequence; it contains API to configure the amounts of frames to store as well as getting a GeglBuffer pointing to any of the previously stored frames.
  • GeglOperationComposer (GEGL_OP_COMPOSER) are operations that take two inputs named “input” and “aux” and write their output to the “output” pad output.
    • GeglOperationPointComposer (GEGL_OP_POINT_COMPOSER) are Composer functions where the output pixels’ values depends only on the values of the single corresponding “input” and “aux” pixels.
  • GeglOperationComposer3 (GEGL_OP_COMPOSER3) are operations that take three inputs named “input”, “aux” and “aux2” and write their output to the “output” pad output.
    • GeglOperationPointComposer3 (GEGL_OP_POINT_COMPOSER3) are Composer3 functions where the output pixels’ values depends only on the values of the single corresponding “input”, “aux” and “aux2” pixels.
  • GeglOperationSource (GEGL_OP_SOURCE) are operations loading data without any input pads. They are adapted for reading image data from files, or for fully generating image data in the output.
    • GeglOperationPointRender is a specialized source operation where the render is done in small piece to lower the need to do copies. It’s dedicated to operation which may be rendered in pieces, like pattern generation.
  • GeglOperationSink (GEGL_OP_SINK) are operations without output pads, usually for saving data into files, display, etc.

In this tutorial, we will create 2 Hello World filters:

  1. The first one as a Meta operation, because it demonstrates one of the most simpler code, though it is limited to reusing already-existing operations.
  2. Our second plug-in will be a Hello World as Point Filter operation, which are still quite a simple way to filter an image, yet are already much closer to how we imagine a full-featured filter algorithm would work (editing pixel data directly).

As a first version of this tutorial, we will not show examples of every possible type of filter. If you are interested into studying actual GEGL operations, I would suggest to start with the ones from the common/ directory in the GEGL repository. In particular, we often advise to look at the Brightness Contrast filter for being already quite heavily commented.

You may go up one folder to see even more categories of effects.

We may update the tutorial in the future with more Hello World demo filters.