The GEGL API
This document is both a tutorial and the reference for the C API of GEGL. The concepts covered in the tutotrial should be applicable using other languages as well.
The core API of GEGL isn't frozen yet and feedback regarding it's use as well as the clarity of this documentation is most welcome.
Introduction
Algorithms created with GEGL are expressed as graphs of nodes. The nodes have associated image processing operations. A node has output and input pads which can be connected. By connecting these nodes in chains a set of image operation filters and combinators can be applied to the image data.
To make GEGL process data you request a rectangular region of an node's output pad to be rendered into a provided linear buffer, of any (supported by babl) pixel format. GEGL is using information about the rectangular bounding-boxes for regions that are needed to compute the requested result. For many forms of processing it should thus be efficient to ask for only a subregion to be recomputed. This fits well with being able to back an api that requests rectangular regions to be repainted.
Initialization
Before GEGL can be used the engine should be initialized by either calling gegl_init or through the use of gegl_get_option_group. To shut down the GEGL engine call gegl_exit.
#include <gegl.h>
int main(int argc, char **argv)
{
gegl_init (&argc, &argv);
# other GEGL code
gegl_exit ();
}
Call this function before using any other GEGL functions. It will initialize everything needed to operate GEGL and parses some standard command line options. argc and argv are adjusted accordingly so your own code will never see those standard arguments.
Note that there is an alternative way to initialize GEGL: if you are calling g_option_context_parse() with the option group returned by gegl_get_option_group(), you don't have to call gegl_init().
Arguments:
argc | a pointer to the number of command line arguments. |
argv | a pointer to the array of command line arguments. |
Call this function when you're done using GEGL. It will clean up caches and write/dump debug information if the correct debug flags are set.
GeglNode
The Node is the image processing primitive connected to create compositions in GEGL. The toplevel GeglNode which contains a graph of GeglNodes is created with gegl_node_new. Using this toplevel node we can create children of this node which are individual processing elements using gegl_node_new_child
A node either has an associated operation or is a parent for other nodes, that are connected to their parent through proxies created with gegl_node_get_input_proxy and gegl_node_get_output_proxy.
The properties available on a node depends on which operation is specified.
GeglNode *gegl, *load, *bcontrast; gegl = gegl_node_new (); load = gegl_node_new_child (gegl, "operation", "load", "path", "input.png", NULL); bcontrast = gegl_node_new_child (gegl, "operation", "brightness-contrast", "brightness", 0.2, "contrast", 1.5, NULL);
Create a new graph that can contain further processing nodes.
Creates a new processing node that performs the specified operation with a NULL terminated list of key/value pairs for initial parameter values configuring the operation. Usually the first pair should be "operation" and the type of operation to be associated. If no operation is provided the node doesn't have an initial operation and can be used to construct a subgraph with special middle-man routing nodes created with gegl_node_get_output_proxy and gegl_node_get_input_proxy.
Arguments:
parent | a GeglNode |
first_property_name | the first property name |
... | first property value, optionally followed by more key/value pairs, ended terminated with NULL. |
Making connections
Nodes in GEGL are connected to each other. The resulting graph of nodes represents the image processing pipeline to be processed.
gegl_node_link_many (background, over, png_save, NULL); gegl_node_connect_to (translate, "output", over, "aux"); gegl_node_link_many (text, blur, translate);
Makes a connection between the pads of two nodes.
Arguments:
sink | the node we're connecting an input to |
input_pad_name | the name of the input pad we are connecting to |
source | the node producing data we want to connect. |
output_pad_name | the output pad we want to use on the source. |
Makes a connection between the pads of two nodes.
Arguments:
source | the node producing data we want to connect. |
output_pad_name | the output pad we want to use on the source. |
sink | the node we're connecting an input to |
input_pad_name | the name of the input pad we are connecting to |
Synthetic sugar for linking a chain of nodes with "input"->"output". The list is NULL terminated.
Arguments:
source | the producer of data. |
first_sink | the first consumer of data. |
... | NULL, or optionally more consumers followed by NULL. |
Setting properties
Properties can be set either when creating the node with gegl_node_new_child as well as later when changing the initial value with gegl_node_set.
To see what operations are available for a given operation look in the Operations reference or use gegl_node_get_properties.
Set properties on a node, possible properties to be set are the properties of the currently set operations as well as "name" and "operation". "operation" changes the current operations set for the node, "name" doesn't have any role internally in GEGL.
Arguments:
node | a GeglNode |
first_property_name | name of the first property to set |
... | value for the first property, followed optionally by more name/value pairs, followed by NULL. |
gegl_node_set (node, "brightness", -0.2, "contrast", 2.0, NULL);
Processing
There are two different ways to do processing with GEGL, either you query any node providing output for a rectangular region to be rendered using gegl_node_blit, or you use gegl_node_process on a sink node (A display node, an image file writer or similar). To do iterative processing you need to use a GeglProcessor see gegl_processor_work for a code sample.
Render a rectangular region from a node.
Arguments:
node | a GeglNode |
roi | the upper left coordinates to render, and the width/height of the destination buffer. |
scale | the scale to render at 1.0 is default, other values changes the width/height of the sampled region. |
format | the BablFormat desired. |
rowstride | rowstride in bytes (currently ignored) |
destination_buf | a memory buffer large enough to contain the data. |
flags | an or'ed combination of GEGL_BLIT_DEFAULT, GEGL_BLIT_CACHE and GEGL_BLIT_DIRTY. if cache is enabled, a cache will be set up for subsequent requests of image data from this node. By passing in GEGL_BLIT_DIRTY the function will return with the latest rendered results in the cache without regard to wheter the regions has been rendered or not. |
Render a composition. This can be used for instance on a node with a "png-save" operation to render all neccesary data, and make it be written to file. The function is blocking for a non blocking way of doing the same see GeglProcessor.
Arguments:
sink_node | a GeglNode without outputs. |
GeglNode *gegl; GeglRectangle roi; GeglNode *png_save; unsigned char *buffer; gegl = gegl_parse_xml (xml_data); roi = gegl_node_get_bounding_box (gegl); # create png_save from the graph, the parent/child relationship # only mean anything when it comes to memory management. png_save = gegl_node_new_child (gegl, "operation", "png-save", "path", "output.png", NULL); gegl_node_link (gegl, png_save); gegl_node_process (png_save); buffer = malloc (roi.w*roi.h*4); gegl_node_blit (gegl, &roi, 1.0, babl_format("R'G'B'A u8", roi.w*4, buffer, GEGL_BLIT_DEFAULT);
A GeglProcessor, is a worker that can be used for background rendering of regions in a node's cache. Or for processing a sink node. For most non GUI tasks using gegl_node_blit and gegl_node_process directly should be sufficient. See gegl_processor_work for a code sample.
Arguments:
node | a GeglNode |
rectangle | the GeglRectangle to work on or NULL to work on all available data. |
Change the rectangle a GeglProcessor is working on.
Arguments:
processor | a GeglProcessor |
rectangle | the new GeglRectangle the processor shold work on or NULL to make it work on all data in the buffer. |
Do an iteration of work for the processor.
Arguments:
processor | a GeglProcessor |
progress | a location to store the (estimated) percentage complete. |
GeglProcessor *processor = gegl_node_new_processor (node, &roi); double progress; while (gegl_processor_work (processor, &progress)) g_warning ("%f%% complete", progress); gegl_processor_destroy (processor);
State queries
This section lists functions that retrieve information, mostly needed for interacting with a graph in a GUI, not creating one from scratch.
You can figure out what the bounding box of a node is with gegl_node_get_bounding_box, retrieve the values of named properties using gegl_node_get.
Arguments:
n_operations_p | return location for number of operations. |
operations = gegl_list_operations (&n_operations); g_print ("Available operations:\n"); for (i=0; i < n_operations; i++) { g_print ("\t%s\n", operations[i]); } g_free (operations);
Arguments:
operation_type | the name of the operation type we want to query to properties of. |
n_properties_p | return location for number of properties. |
Performs hit detection by returning the node providing data at a given coordinate pair. Currently operates only on bounding boxes and not pixel data.
Arguments:
node | a GeglNode |
x | x coordinate |
y | y coordinate |
Arguments:
node | the node to lookup a paramspec on |
property_name | the name of the property to get a paramspec for. |
Gets properties of a GeglNode.
Arguments:
node | a GeglNode |
first_property_name | name of the first property to get. |
... | return location for the first property, followed optionally by more name/value pairs, followed by NULL. |
double level; char *path; gegl_node_get (png_save, "path", &path, NULL); gegl_node_get (threshold, "level", &level, NULL);
Arguments:
node | a GeglNode |
Retrieve which pads on which nodes are connected to a named output_pad, and the number of connections. Both the location for the generated nodes array and pads array can be left as NULL. If they are non NULL both should be freed with g_free. The arrays are NULL terminated.
Arguments:
node | the node we are querying. |
output_pad | the output pad we want to know who uses. |
nodes | optional return location for array of nodes. |
pads | optional return location for array of pad names. |
Proxies are used to route between nodes of a subgraph contained within a node.
Arguments:
node | a GeglNode |
pad_name | the name of the pad. |
Proxies are used to route between nodes of a subgraph contained within a node.
Arguments:
node | a GeglNode |
pad_name | the name of the pad. |
Arguments:
node | the node we are querying |
input_pad_name | the input pad we want to get the producer for |
output_pad_name | optional pointer to a location where we can store a freshly allocated string with the name of the output pad. |
XML
The XML format used by GEGL is not stable and should not be relied on for anything but testing purposes yet.
The GeglNode returned contains the graph described by the tree of stacks in the XML document. The tree is connected to the "output" pad of the returned node and thus can be used directly for processing.
Arguments:
xmldata | a \0 terminated string containing XML data to be parsed. |
path_root | a file system path that relative paths in the XML will be resolved in relation to. |
Arguments:
node | a GeglNode |
path_root | filesystem path to construct relative paths from. |
GeglRectangle
GeglRectangles are used in gegl_node_get_bounding_box and gegl_node_blit for specifying rectangles.
struct GeglRectangle { gint x; gint y; gint width; gint height; };
GeglColor
GeglColor is used for properties that use a gegl color, use gegl_color_new with a NULL string to create a new blank one, gegl_colors are destroyed with g_object_unref when they no longer are needed.
The colors used by gegls are described in a format similar to CSS. The textstring "rgb(1.0,1.0,1.0)" signifies opaque white and "rgba(1.0,0.0,0.0,0.75)" is a 75% opaque red. Hexadecimal forms like RRGGBB and RRGGBBAA are also supported.
Arguments:
string | an CSS style color string. |
Bindings conveniences
The following functions are mostly included to make it easier to create language bindings. The varargs versions most often lead to more readable C code.
Creates a new processing node that performs the specified operation.
Arguments:
parent | a GeglNode |
operation | the type of node to create. |
This is mainly included for language bindings. Using gegl_node_get is more convenient when programming in C.
Arguments:
node | the node to get a property from |
property_name | the name of the property to get |
value | pointer to a GValue where the value of the property should be stored |
This is mainly included for language bindings. Using gegl_node_set is more convenient when programming in C.
Arguments:
node | a GeglNode |
property_name | the name of the property to set |
value | a GValue containing the value to be set in the property. |