Commit 52574cdc authored by Øyvind Kolås's avatar Øyvind Kolås

Applied slightly modified patch from Luidnel Maignan that adds

point composers with 3 inputs as requested in bug #548007.
* gegl/operation/gegl-operation-composer3.c: new file
* gegl/operation/gegl-operation-composer3.h: new file
* gegl/operation/gegl-operation-point-composer3.c: new file
* gegl/operation/gegl-operation-point-composer3.h: new file
* gegl/operation/Makefile.am: added new files.
Added the new classes to the following places:
* gegl/gegl-chant.h: allow subclassing the new classes with the
chanting framework.
* gegl/gegl-plugin.h: include the new headers.
* gegl/operation/gegl-operation-processors.c: make the type-aware
functions pointer lookup aware of the new classes.

svn path=/trunk/; revision=2580
parent 74e5fee0
2008-08-16 Øyvind Kolås <pippin@gimp.org>
Applied slightly modified patch from Luidnel Maignan that adds
point composers with 3 inputs as requested in bug #548007.
* gegl/operation/gegl-operation-composer3.c: new file
* gegl/operation/gegl-operation-composer3.h: new file
* gegl/operation/gegl-operation-point-composer3.c: new file
* gegl/operation/gegl-operation-point-composer3.h: new file
* gegl/operation/Makefile.am: added new files.
Added the new classes to the following places:
* gegl/gegl-chant.h: allow subclassing the new classes with the
chanting framework.
* gegl/gegl-plugin.h: include the new headers.
* gegl/operation/gegl-operation-processors.c: make the type-aware
functions pointer lookup aware of the new classes.
2008-08-07 Øyvind Kolås <pippin@gimp.org>
* configure.ac: updated minimal glib requirement to 2.14.0
......
......@@ -187,6 +187,22 @@ GEGL_DEFINE_DYNAMIC_OPERATION(GEGL_TYPE_OPERATION_COMPOSER);
#endif
#ifdef GEGL_CHANT_TYPE_COMPOSER3
struct _GeglChant
{
GeglOperationComposer3 parent_instance;
gpointer properties;
};
typedef struct
{
GeglOperationComposer3Class parent_class;
} GeglChantClass;
GEGL_DEFINE_DYNAMIC_OPERATION(GEGL_TYPE_OPERATION_COMPOSER3);
#endif
#ifdef GEGL_CHANT_TYPE_POINT_FILTER
struct _GeglChant
{
......@@ -264,6 +280,20 @@ typedef struct
GEGL_DEFINE_DYNAMIC_OPERATION(GEGL_TYPE_OPERATION_POINT_COMPOSER);
#endif
#ifdef GEGL_CHANT_TYPE_POINT_COMPOSER3
struct _GeglChant
{
GeglOperationPointComposer3 parent_instance;
gpointer properties;
};
typedef struct
{
GeglOperationPointComposer3Class parent_class;
} GeglChantClass;
GEGL_DEFINE_DYNAMIC_OPERATION(GEGL_TYPE_OPERATION_POINT_COMPOSER3);
#endif
#define GEGL_CHANT(obj) ((GeglChant*)(obj))
/* if GEGL_CHANT_CUSTOM is defined you have to provide the following
......
......@@ -90,7 +90,9 @@ const gchar * gegl_extension_handler_get (const gchar *extensi
#include <operation/gegl-operation-area-filter.h>
#include <operation/gegl-operation-point-filter.h>
#include <operation/gegl-operation-composer.h>
#include <operation/gegl-operation-composer3.h>
#include <operation/gegl-operation-point-composer.h>
#include <operation/gegl-operation-point-composer3.h>
#include <operation/gegl-operation-point-render.h>
#include <operation/gegl-operation-temporal.h>
#include <operation/gegl-operation-source.h>
......
......@@ -5,9 +5,11 @@ OPERATION_sources = \
gegl-operation.c \
gegl-operation-area-filter.c \
gegl-operation-composer.c \
gegl-operation-composer3.c \
gegl-operation-filter.c \
gegl-operation-meta.c \
gegl-operation-point-composer.c \
gegl-operation-point-composer3.c \
gegl-operation-point-filter.c \
gegl-operation-point-render.c \
gegl-operation-sink.c \
......@@ -22,9 +24,11 @@ OPERATION_headers = \
gegl-operation.h \
gegl-operation-area-filter.h \
gegl-operation-composer.h \
gegl-operation-composer3.h \
gegl-operation-filter.h \
gegl-operation-meta.h \
gegl-operation-point-composer.h \
gegl-operation-point-composer3.h \
gegl-operation-point-filter.h \
gegl-operation-point-render.h \
gegl-operation-sink.h \
......@@ -37,9 +41,11 @@ public_headers = \
gegl-operation.h \
gegl-operation-area-filter.h \
gegl-operation-composer.h \
gegl-operation-composer3.h \
gegl-operation-filter.h \
gegl-operation-meta.h \
gegl-operation-point-composer.h \
gegl-operation-point-composer3.h \
gegl-operation-point-filter.h \
gegl-operation-point-render.h \
gegl-operation-sink.h \
......
/* This file is part of GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås
*/
#define GEGL_INTERNAL
#include "config.h"
#include <glib-object.h>
#include <string.h>
#include "gegl-types.h"
#include "gegl-operation-composer3.h"
#include "gegl-utils.h"
#include "graph/gegl-node.h"
#include "graph/gegl-connection.h"
#include "graph/gegl-pad.h"
#include "buffer/gegl-region.h"
#include "buffer/gegl-buffer.h"
enum
{
PROP_0,
PROP_OUTPUT,
PROP_INPUT,
PROP_AUX,
PROP_AUX2,
};
static void get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static gboolean gegl_operation_composer3_process (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result);
static void attach (GeglOperation *operation);
static GeglNode*detect (GeglOperation *operation,
gint x,
gint y);
static GeglRectangle get_bounding_box (GeglOperation *self);
static GeglRectangle get_required_for_output (GeglOperation *self,
const gchar *input_pad,
const GeglRectangle *roi);
G_DEFINE_TYPE (GeglOperationComposer3, gegl_operation_composer3,
GEGL_TYPE_OPERATION)
static void
gegl_operation_composer3_class_init (GeglOperationComposer3Class * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
object_class->set_property = set_property;
object_class->get_property = get_property;
operation_class->process = gegl_operation_composer3_process;
operation_class->attach = attach;
operation_class->detect = detect;
operation_class->get_bounding_box = get_bounding_box;
operation_class->get_required_for_output = get_required_for_output;
g_object_class_install_property (object_class, PROP_OUTPUT,
g_param_spec_object ("output",
"Output",
"Ouput pad for generated image buffer.",
GEGL_TYPE_BUFFER,
G_PARAM_READABLE |
GEGL_PARAM_PAD_OUTPUT));
g_object_class_install_property (object_class, PROP_INPUT,
g_param_spec_object ("input",
"Input",
"Input pad, for image buffer input.",
GEGL_TYPE_BUFFER,
G_PARAM_READWRITE |
GEGL_PARAM_PAD_INPUT));
g_object_class_install_property (object_class, PROP_AUX,
g_param_spec_object ("aux",
"Input",
"Auxiliary image buffer input pad.",
GEGL_TYPE_BUFFER,
G_PARAM_READWRITE |
GEGL_PARAM_PAD_INPUT));
g_object_class_install_property (object_class, PROP_AUX2,
g_param_spec_object ("aux2",
"Input",
"Second auxiliary image buffer input pad.",
GEGL_TYPE_BUFFER,
G_PARAM_READWRITE |
GEGL_PARAM_PAD_INPUT));
}
static void
gegl_operation_composer3_init (GeglOperationComposer3 *self)
{
}
static void
attach (GeglOperation *self)
{
GeglOperation *operation = GEGL_OPERATION (self);
GObjectClass *object_class = G_OBJECT_GET_CLASS (self);
gegl_operation_create_pad (operation,
g_object_class_find_property (object_class,
"output"));
gegl_operation_create_pad (operation,
g_object_class_find_property (object_class,
"input"));
gegl_operation_create_pad (operation,
g_object_class_find_property (object_class,
"aux"));
gegl_operation_create_pad (operation,
g_object_class_find_property (object_class,
"aux2"));
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
}
static void
set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
}
static gboolean
gegl_operation_composer3_process (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result)
{
GeglOperationComposer3Class *klass = GEGL_OPERATION_COMPOSER3_GET_CLASS (operation);
GeglBuffer *input;
GeglBuffer *aux;
GeglBuffer *aux2;
GeglBuffer *output;
gboolean success = FALSE;
if (strcmp (output_prop, "output"))
{
g_warning ("requested processing of %s pad on a composer", output_prop);
return FALSE;
}
input = gegl_operation_context_get_source (context, "input");
aux = gegl_operation_context_get_source (context, "aux");
aux2 = gegl_operation_context_get_source (context, "aux2");
output = gegl_operation_context_get_target (context, "output");
/* A composer with a NULL aux, can still be valid, the
* subclass has to handle it.
*/
if (input != NULL ||
aux != NULL ||
aux2 != NULL)
{
success = klass->process (operation, input, aux, aux2, output, result);
if (input)
g_object_unref (input);
if (aux)
g_object_unref (aux);
if (aux2)
g_object_unref (aux2);
}
else
{
g_warning ("%s received NULL input, aux, and aux2",
gegl_node_get_debug_name (operation->node));
}
return success;
}
static GeglRectangle
get_bounding_box (GeglOperation *self)
{
GeglRectangle result = { 0, 0, 0, 0 };
GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (self, "input");
GeglRectangle *aux_rect = gegl_operation_source_get_bounding_box (self, "aux");
GeglRectangle *aux2_rect = gegl_operation_source_get_bounding_box (self, "aux2");
if (!in_rect)
if (!aux_rect)
if (!aux2_rect)
return result;
else
return *aux2_rect;
else
if (!aux2_rect)
return *aux_rect;
else
gegl_rectangle_bounding_box (&result, aux_rect, aux2_rect);
else
if (!aux_rect)
if (!aux2_rect)
return *in_rect;
else
gegl_rectangle_bounding_box (&result, in_rect, aux2_rect);
else
if (!aux2_rect)
gegl_rectangle_bounding_box (&result, in_rect, aux_rect);
else
{
gegl_rectangle_bounding_box (&result, in_rect, aux_rect);
gegl_rectangle_bounding_box (&result, &result, aux2_rect);
}
return result;
}
static GeglRectangle
get_required_for_output (GeglOperation *self,
const gchar *input_pad,
const GeglRectangle *roi)
{
GeglRectangle rect = *roi;
return rect;
}
static GeglNode *
detect (GeglOperation *operation,
gint x,
gint y)
{
GeglNode *input_node = gegl_operation_get_source_node (operation, "input");
GeglNode *aux_node = gegl_operation_get_source_node (operation, "aux");
GeglNode *aux2_node = gegl_operation_get_source_node (operation, "aux2");
if (input_node)
input_node = gegl_node_detect (input_node, x, y);
if (aux_node)
aux_node = gegl_node_detect (aux_node, x, y);
if (aux2_node)
aux2_node = gegl_node_detect (aux2_node, x, y);
if (aux2_node)
return aux2_node;
if (aux_node)
return aux_node;
if (input_node)
return input_node;
return NULL;
}
/* This file is part of GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås
*/
#ifndef __GEGL_OPERATION_COMPOSER3_H__
#define __GEGL_OPERATION_COMPOSER3_H__
#include "gegl-operation.h"
G_BEGIN_DECLS
#define GEGL_TYPE_OPERATION_COMPOSER3 (gegl_operation_composer3_get_type ())
#define GEGL_OPERATION_COMPOSER3(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_OPERATION_COMPOSER3, GeglOperationComposer3))
#define GEGL_OPERATION_COMPOSER3_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_OPERATION_COMPOSER3, GeglOperationComposer3Class))
#define GEGL_IS_OPERATION_COMPOSER3(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_OPERATION_COMPOSER3))
#define GEGL_IS_OPERATION_COMPOSER3_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_OPERATION_COMPOSER3))
#define GEGL_OPERATION_COMPOSER3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_OPERATION_COMPOSER3, GeglOperationComposer3Class))
typedef struct _GeglOperationComposer3 GeglOperationComposer3;
struct _GeglOperationComposer3
{
GeglOperation parent_instance;
};
typedef struct _GeglOperationComposer3Class GeglOperationComposer3Class;
struct _GeglOperationComposer3Class
{
GeglOperationClass parent_class;
gboolean (* process) (GeglOperation *self,
GeglBuffer *input,
GeglBuffer *aux,
GeglBuffer *aux2,
GeglBuffer *output,
const GeglRectangle *result);
};
GType gegl_operation_composer3_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif
/* This file is part of GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås
*/
#define GEGL_INTERNAL
#include "config.h"
#include <glib-object.h>
#include "gegl-types.h"
#include "gegl-operation-point-composer3.h"
#include "gegl-utils.h"
#include "graph/gegl-node.h"
#include "graph/gegl-pad.h"
#include <string.h>
static gboolean gegl_operation_point_composer3_process
(GeglOperation *operation,
GeglBuffer *input,
GeglBuffer *aux,
GeglBuffer *aux2,
GeglBuffer *output,
const GeglRectangle *result);
static gboolean
gegl_operation_composer3_process2 (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result);
G_DEFINE_TYPE (GeglOperationPointComposer3, gegl_operation_point_composer3, GEGL_TYPE_OPERATION_COMPOSER3)
static void prepare (GeglOperation *operation)
{
Babl *format = babl_format ("RGBA float");
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "aux2", format);
gegl_operation_set_format (operation, "output", format);
}
static void
gegl_operation_point_composer3_class_init (GeglOperationPointComposer3Class *klass)
{
/*GObjectClass *object_class = G_OBJECT_CLASS (klass);*/
GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
GeglOperationComposer3Class *composer_class = GEGL_OPERATION_COMPOSER3_CLASS (klass);
composer_class->process = gegl_operation_point_composer3_process;
operation_class->prepare = prepare;
operation_class->no_cache =TRUE;
operation_class->process = gegl_operation_composer3_process2;
}
static void
gegl_operation_point_composer3_init (GeglOperationPointComposer3 *self)
{
}
/* we replicate the process function from GeglOperationComposer3 to be
* able to bail out earlier for some common processing time pitfalls
*/
static gboolean
gegl_operation_composer3_process2 (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result)
{
GeglOperationComposer3Class *klass = GEGL_OPERATION_COMPOSER3_GET_CLASS (operation);
GeglBuffer *input;
GeglBuffer *aux;
GeglBuffer *aux2;
GeglBuffer *output;
gboolean success = FALSE;
if (strcmp (output_prop, "output"))
{
g_warning ("requested processing of %s pad on a composer", output_prop);
return FALSE;
}
input = gegl_operation_context_get_source (context, "input");
aux = gegl_operation_context_get_source (context, "aux");
aux2 = gegl_operation_context_get_source (context, "aux2");
/* we could be even faster by not alway writing to this buffer, that
* would potentially break other assumptions we want to make from the
* GEGL core so we avoid doing that
*/
output = gegl_operation_context_get_target (context, "output");
if (input != NULL ||
aux != NULL ||
aux2 != NULL)
{
gboolean done = FALSE;
if (result->width == 0 ||
result->height == 0)
done = TRUE;
success = done;
if (!done)
{
success = klass->process (operation, input, aux, aux2, output, result);
}
if (input)
g_object_unref (input);
if (aux)
g_object_unref (aux);
if (aux2)
g_object_unref (aux2);
}
else
{
g_warning ("%s received NULL input, aux, and aux2",
gegl_node_get_debug_name (operation->node));
}
return success;
}
static gboolean
gegl_operation_point_composer3_process (GeglOperation *operation,
GeglBuffer *input,
GeglBuffer *aux,
GeglBuffer *aux2,
GeglBuffer *output,
const GeglRectangle *result)
{
GeglOperationPointComposer3Class *point_composer3_class = GEGL_OPERATION_POINT_COMPOSER3_GET_CLASS (operation);
const Babl *in_format = gegl_operation_get_format (operation, "input");
const Babl *aux_format = gegl_operation_get_format (operation, "aux");
const Babl *aux2_format = gegl_operation_get_format (operation, "aux2");
const Babl *out_format = gegl_operation_get_format (operation, "output");
if ((result->width > 0) && (result->height > 0))
{
GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, out_format, GEGL_BUFFER_WRITE);
gint read = gegl_buffer_iterator_add (i, input, result, in_format, GEGL_BUFFER_READ);
if (aux)
{
gint foo = gegl_buffer_iterator_add (i, aux, result, aux_format, GEGL_BUFFER_READ);
if (aux2)
{
gint bar = gegl_buffer_iterator_add (i, aux2, result, aux2_format, GEGL_BUFFER_READ);
while (gegl_buffer_iterator_next (i))
{
point_composer3_class->process (operation, i->data[read], i->data[foo], i->data[bar], i->data[0], i->length, &(i->roi[0]));
}
}
else
{
while (gegl_buffer_iterator_next (i))
{
point_composer3_class->process (operation, i->data[read], i->data[foo], NULL, i->data[0], i->length, &(i->roi[0]));
}
}
}
else
{
if (aux2)
{
gint bar = gegl_buffer_iterator_add (i, aux2, result, aux2_format, GEGL_BUFFER_READ);
while (gegl_buffer_iterator_next (i))
{
point_composer3_class->process (operation, i->data[read], NULL, i->data[bar], i->data[0], i->length, &(i->roi[0]));
}
}
else
{
while (gegl_buffer_iterator_next (i))
{
point_composer3_class->process (operation, i->data[read], NULL, NULL, i->data[0], i->length, &(i->roi[0]));
}
}
}
return TRUE;
}
return TRUE;
}
/* This file is part of GEGL
*
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2006 Øyvind Kolås
*/
#ifndef __GEGL_OPERATION_POINT_COMPOSER3_H__
#define __GEGL_OPERATION_POINT_COMPOSER3_H__
#include "gegl-operation-composer3.h"
G_BEGIN_DECLS
#define GEGL_TYPE_OPERATION_POINT_COMPOSER3 (gegl_operation_point_composer3_get_type ())
#define GEGL_OPERATION_POINT_COMPOSER3(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_OPERATION_POINT_COMPOSER3, GeglOperationPointComposer3))
#define GEGL_OPERATION_POINT_COMPOSER3_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_OPERATION_POINT_COMPOSER3, GeglOperationPointComposer3Class))
#define GEGL_IS_OPERATION_POINT_COMPOSER3(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_OPERATION_POINT_COMPOSER3))
#define GEGL_IS_OPERATION_POINT_COMPOSER3_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_OPERATION_POINT_COMPOSER3))
#define GEGL_OPERATION_POINT_COMPOSER3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_OPERATION_POINT_COMPOSER3, GeglOperationPointComposer3Class))
typedef struct _GeglOperationPointComposer3 GeglOperationPointComposer3;
struct _GeglOperationPointComposer3
{
GeglOperationComposer3 parent_instance;
/*< private >*/
};
typedef struct _GeglOperationPointComposer3Class GeglOperationPointComposer3Class;
struct _GeglOperationPointComposer3Class
{
GeglOperationComposer3Class parent_class;
gboolean (* process) (GeglOperation *self, /* for parameters */
void *in,
void *aux,
void *aux2,
void *out,
glong samples, /* number of samples */
const GeglRectangle *roi /* rectangular region in output buffer */
);
};
GType gegl_operation_point_composer3_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif
......@@ -37,9 +37,11 @@
#include "gegl-operations.h"
#include "gegl-operation-area-filter.h"
#include "gegl-operation-composer3.h"
#include "gegl-operation-composer.h"
#include "gegl-operation-filter.h"
#include "gegl-operation-meta.h"
#include "gegl-operation-point-composer3.h"
#include "gegl-operation-point-composer.h"
#include "gegl-operation-point-filter.h"
#include "gegl-operation-sink.h"
......@@ -225,6 +227,10 @@ ELSE_IF( GEGL_TYPE_OPERATION_COMPOSER)
vfunc_offset = G_STRUCT_OFFSET (GeglOperationComposerClass, process);
ELSE_IF( GEGL_TYPE_OPERATION_POINT_COMPOSER)
vfunc_offset = G_STRUCT_OFFSET (GeglOperationPointComposerClass, process);
ELSE_IF( GEGL_TYPE_OPERATION_COMPOSER3)
vfunc_offset = G_STRUCT_OFFSET (GeglOperationComposer3Class, process);
ELSE_IF( GEGL_TYPE_OPERATION_POINT_COMPOSER3)
vfunc_offset = G_STRUCT_OFFSET (GeglOperationPointComposer3Class, process);
#undef ELSE_IF
else
{
......