static void my_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec) { GeglOperation *operation = GEGL_OPERATION (gobject); GeglProperties *o = GEGL_PROPERTIES (operation); Priv *p = get_priv(o); GObject *buffer = NULL; switch (property_id) { case PROP_buffer: if (o->buffer) { // Invariant: valid buffer should always have valid signal handler g_assert(p->buffer_changed_handler > 0); g_signal_handler_disconnect (o->buffer, p->buffer_changed_handler); /* XXX: should decrement signal connected count */ } buffer = G_OBJECT (g_value_get_object (value)); if (buffer) { p->buffer_changed_handler = gegl_buffer_signal_connect (GEGL_BUFFER(buffer), "changed", G_CALLBACK(buffer_changed), operation); } break; default: break; } /* The set_property provided by the chant system does the * storing and reffing/unreffing of the input properties */ set_property(gobject, property_id, value, pspec); }
static gboolean gegl_affine_is_intermediate_node (OpAffine *affine) { GSList *connections; GeglOperation *op = GEGL_OPERATION (affine); connections = gegl_pad_get_connections (gegl_node_get_pad (op->node, "output")); if (! connections) return FALSE; do { GeglOperation *sink; sink = gegl_connection_get_sink_node (connections->data)->operation; if (! IS_OP_AFFINE (sink) || strcmp (affine->filter, OP_AFFINE (sink)->filter)) return FALSE; } while ((connections = g_slist_next (connections))); return TRUE; }
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")); }
static void gimp_operation_histogram_sink_attach (GeglOperation *self) { GeglOperation *operation = GEGL_OPERATION (self); GObjectClass *object_class = G_OBJECT_GET_CLASS (self); GEGL_OPERATION_CLASS (parent_class)->attach (self); gegl_operation_create_pad (operation, g_object_class_find_property (object_class, "aux")); }
static void gimp_n_point_deformation_tool_perform_deformation (GimpNPointDeformationTool *npd_tool) { GObject *operation; g_object_get (npd_tool->npd_node, "gegl-operation", &operation, NULL); gimp_npd_debug (("gegl_operation_invalidate\n")); gegl_operation_invalidate (GEGL_OPERATION (operation), NULL, FALSE); g_object_unref (operation); gimp_npd_debug (("gegl_node_process\n")); gegl_node_process (npd_tool->sink); }
static void finalize(GObject *object) { GeglProperties *o = GEGL_PROPERTIES (object); if (o->user_data != NULL) { cleanup (GEGL_OPERATION (object)); if (o->user_data != NULL) g_free (o->user_data); o->user_data = NULL; } G_OBJECT_CLASS (gegl_op_parent_class)->finalize (object); }
static gboolean gegl_affine_is_composite_node (OpAffine *affine) { GSList *connections; GeglOperation *op = GEGL_OPERATION (affine); GeglOperation *source; connections = gegl_pad_get_connections (gegl_node_get_pad (op->node, "input")); if (! connections) return FALSE; source = gegl_connection_get_source_node (connections->data)->operation; return (IS_OP_AFFINE (source) && ! strcmp (affine->filter, OP_AFFINE (source)->filter)); }
static void gegl_affine_get_source_matrix (OpAffine *affine, GeglMatrix3 *output) { GSList *connections; GeglOperation *op = GEGL_OPERATION (affine); GeglOperation *source; connections = gegl_pad_get_connections (gegl_node_get_pad (op->node, "input")); g_assert (connections); source = gegl_connection_get_source_node (connections->data)->operation; g_assert (IS_OP_AFFINE (source)); gegl_affine_create_composite_matrix (OP_AFFINE (source), output); /*gegl_matrix3_copy (output, OP_AFFINE (source)->matrix);*/ }
static void attach (GeglOperation *self) { GeglOperation *operation = GEGL_OPERATION (self); GParamSpec *pspec; pspec = g_param_spec_object ("output", "Output", "Output pad for generated image buffer.", GEGL_TYPE_BUFFER, G_PARAM_READABLE | GEGL_PARAM_PAD_OUTPUT); gegl_operation_create_pad (operation, pspec); g_param_spec_sink (pspec); pspec = g_param_spec_object ("input", "Input", "Input pad, for image buffer input.", GEGL_TYPE_BUFFER, G_PARAM_READWRITE | GEGL_PARAM_PAD_INPUT); gegl_operation_create_pad (operation, pspec); g_param_spec_sink (pspec); pspec = g_param_spec_object ("aux", "Aux", "Auxiliary image buffer input pad.", GEGL_TYPE_BUFFER, G_PARAM_READWRITE | GEGL_PARAM_PAD_INPUT); gegl_operation_create_pad (operation, pspec); g_param_spec_sink (pspec); pspec = g_param_spec_object ("aux2", "Aux2", "Second auxiliary image buffer input pad.", GEGL_TYPE_BUFFER, G_PARAM_READWRITE | GEGL_PARAM_PAD_INPUT); gegl_operation_create_pad (operation, pspec); g_param_spec_sink (pspec); }
void gegl_operation_meta_property_changed (GeglOperationMeta *self, GParamSpec *pspec, gpointer user_data) { GSList *iter; g_return_if_fail (GEGL_IS_OPERATION_META (self)); g_return_if_fail (pspec); for (iter = self->redirects; iter; iter = iter->next) { Redirect *redirect = iter->data; if (!strcmp (redirect->name, pspec->name)) { gegl_node_copy_property_property (GEGL_OPERATION (self), pspec->name, gegl_node_get_gegl_operation (redirect->internal), redirect->internal_name); } } }
static void create_matrix (OpTransform *op, GeglMatrix3 *matrix) { GeglProperties *o = GEGL_PROPERTIES (op); GeglOperation *operation = GEGL_OPERATION (op); GeglRectangle in_rect = {0,0,0,0}; gdouble height_over_width = 1.0; if (gegl_operation_source_get_bounding_box (operation, "input")) in_rect = *gegl_operation_source_get_bounding_box (operation, "input"); // Avoid divide-by-zero if(in_rect.width < 1) in_rect.width = 1; if(in_rect.height < 1) in_rect.height = 1; height_over_width = in_rect.height/(gdouble)in_rect.width; if (o->x <= 0.0 && o->y <= 0.0) { // No dimensions specified, pass through matrix->coeff [0][0] = 1.0; matrix->coeff [1][1] = 1.0; } else if (o->x <= 0.0 && o->y > 0.0) { // X free, Y specified const gdouble target_x = o->y / height_over_width; matrix->coeff [0][0] = target_x / (gdouble) in_rect.width; matrix->coeff [1][1] = o->y / (gdouble) in_rect.height; } else if (o->y <= 0.0 && o->x > 0.0) { // Y free, X specified const gdouble target_y = o->x * height_over_width; matrix->coeff [0][0] = o->x / (gdouble) in_rect.width; matrix->coeff [1][1] = target_y / (gdouble) in_rect.height; } else { // Fully specified matrix->coeff [0][0] = o->x / (gdouble) in_rect.width; matrix->coeff [1][1] = o->y / (gdouble) in_rect.height; } }
static void drawable_lua_process (GeglOperation *op, GeglBuffer *drawable, GeglBuffer *aux, GeglBuffer *result, const GeglRectangle *roi, const gchar *file, const gchar *buffer, gdouble user_value) { /*GimpRGB background;*/ GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (GEGL_OPERATION (op), "input"); lua_State *L; Priv p; L = luaL_newstate (); luaL_openlibs (L); register_functions (L, gluas_functions); p.rgba_float = babl_format ("RGBA float"); p.L = L; p.width = in_rect->width; p.height = in_rect->height; p.bx1 = roi->x; p.by1 = roi->y; p.bx2 = roi->x + roi->width; p.by2 = roi->y + roi->height; lua_pushnumber (L, (double) user_value); lua_setglobal (L, "user_value"); lua_pushnumber (L, (double) p.width); lua_setglobal (L, "width"); lua_pushnumber (L, (double) p.height); lua_setglobal (L, "height"); lua_pushstring (L, "priv"); lua_pushlightuserdata (L, &p); lua_settable (L, LUA_REGISTRYINDEX); p.in_drawable = drawable; p.aux_drawable = aux; p.out_drawable = result; lua_pushnumber (L, (double) p.bx1); lua_setglobal (L, "bound_x0"); lua_pushnumber (L, (double) p.bx2); lua_setglobal (L, "bound_x1"); lua_pushnumber (L, (double) p.by1); lua_setglobal (L, "bound_y0"); lua_pushnumber (L, (double) p.by2); lua_setglobal (L, "bound_y1"); { gint status = 0; luaL_loadstring (L, "os.setlocale ('C', 'numeric')"); /* insert default loop start/end filling the selection */ if (file && file[0]!='\0') status = luaL_loadfile (L, file); else if (buffer) { GString *str = g_string_new (buffer); if (!strstr (buffer, "for x")) { g_string_prepend (str, "for y=bound_y0, bound_y1 do\n for x=bound_x0, bound_x1 do\n"); g_string_append (str, " end \n progress (y/height)\n end\n"); } status = luaL_loadbuffer (L, str->str, str->len, "buffer"); g_string_free (str, TRUE); } if (status == 0) status = lua_pcall (L, 0, LUA_MULTRET, 0); if (status != 0) gegl_node_set (op->node, "error", lua_tostring (L, -1), NULL); } }
static void buffer_changed (GeglBuffer *buffer, const GeglRectangle *rect, gpointer userdata) { gegl_operation_invalidate (GEGL_OPERATION (userdata), rect, FALSE); }
static void drawable_lua_process (GeglOperation *op, GeglBuffer *drawable, GeglBuffer *aux, GeglBuffer *result, const GeglRectangle *roi, const gchar *file, const gchar *buffer, gdouble user_value) { /*GimpRGB background;*/ GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (GEGL_OPERATION (op), "input"); lua_State *L; Priv p; L = luaL_newstate (); luaL_openlibs (L); register_functions (L, gluas_functions); p.rgba_float = babl_format ("RGBA float"); p.L = L; p.width = in_rect->width; p.height = in_rect->height; p.bx1 = roi->x; p.by1 = roi->y; p.bx2 = roi->x + roi->width; p.by2 = roi->y + roi->height; lua_pushnumber (L, (double) user_value); lua_setglobal (L, "user_value"); lua_pushnumber (L, (double) p.width); lua_setglobal (L, "width"); lua_pushnumber (L, (double) p.height); lua_setglobal (L, "height"); lua_pushstring (L, "priv"); lua_pushlightuserdata (L, &p); lua_settable (L, LUA_REGISTRYINDEX); p.in_drawable = drawable; p.aux_drawable = aux; p.out_drawable = result; lua_pushnumber (L, (double) p.bx1); lua_setglobal (L, "bound_x0"); lua_pushnumber (L, (double) p.bx2); lua_setglobal (L, "bound_x1"); lua_pushnumber (L, (double) p.by1); lua_setglobal (L, "bound_y0"); lua_pushnumber (L, (double) p.by2); lua_setglobal (L, "bound_y1"); { gint status = 0; luaL_loadstring (L, "os.setlocale ('C', 'numeric')"); if (file && file[0]!='\0') status = luaL_loadfile (L, file); else if (buffer) status = luaL_loadbuffer (L, buffer, strlen (buffer), "buffer"); if (status == 0) status = lua_pcall (L, 0, LUA_MULTRET, 0); if (status != 0) g_warning ("lua error: %s", lua_tostring (L, -1)); } }