static void _gegl_graph_do_build (GeglGraphTraversal *path, GeglNode *node) { GeglPad *pad = NULL; GeglListVisitor *list_visitor = g_object_new (GEGL_TYPE_LIST_VISITOR, NULL); /* We need to check the real node of the output/input pad in case this is a proxy node */ pad = gegl_node_get_pad (node, "output"); if (pad) { node = gegl_pad_get_node (pad); } else { pad = gegl_node_get_pad (node, "input"); if (pad) node = gegl_pad_get_node (pad); } path->dfs_path = gegl_list_visitor_get_dfs_path (list_visitor, GEGL_VISITABLE (node)); path->bfs_path = gegl_list_visitor_get_bfs_path (list_visitor, GEGL_VISITABLE (node)); path->contexts = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)gegl_operation_context_destroy); path->rects_dirty = FALSE; g_object_unref (list_visitor); }
static gboolean gegl_operation_point_render_process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglPad *pad; const Babl *out_format; GeglOperationPointRenderClass *point_render_class; point_render_class = GEGL_OPERATION_POINT_RENDER_GET_CLASS (operation); pad = gegl_node_get_pad (operation->node, "output"); out_format = gegl_pad_get_format (pad); if (!out_format) { g_warning ("%s", gegl_node_get_debug_name (operation->node)); } g_assert (out_format); if ((result->width > 0) && (result->height > 0)) { GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (i)) point_render_class->process (operation, i->data[0], i->length, &i->roi[0], level); } return TRUE; }
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; }
void layer_add_gegl_node(GeglEditorLayer* layer, GeglNode* node) { //get input pads //gegl_pad_is_output GSList *pads = gegl_node_get_input_pads(node); guint num_inputs = g_slist_length(pads); gchar** inputs = malloc(sizeof(gchar*)*num_inputs); int i; for(i = 0; pads != NULL; pads = pads->next, i++) { inputs[i] = (gchar*)gegl_pad_get_name(pads->data); } gint id; if(gegl_node_get_pad(node, "output") == NULL) { id = gegl_editor_add_node(layer->editor, gegl_node_get_operation(node), num_inputs, inputs, 0, NULL); } else { gchar* output = "output"; gchar* outputs[] = {output}; id = gegl_editor_add_node(layer->editor, gegl_node_get_operation(node), num_inputs, inputs, 1, outputs); } node_id_pair* new_pair = malloc(sizeof(node_id_pair)); new_pair->node = node; new_pair->id = id; layer->pairs = g_slist_append(layer->pairs, new_pair); }
static void print_info(GeglNode* gegl) { GSList *list = gegl_node_get_children(gegl); for(;list != NULL; list = list->next) { GeglNode* node = GEGL_NODE(list->data); g_print("Node %s\n", gegl_node_get_operation(node)); if(gegl_node_get_pad(node, "output") == NULL) { g_print("Output pad is NULL\n"); } /* GeglNode** nodes; const gchar** pads; gint num = gegl_node_get_consumers(node, "output", &nodes, &pads); g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num); int i; for(i = 0; i < num; i++) { g_print("Connection: (%s to %s)\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]); } g_print("\n");*/ } }
/** * gegl_dot_add_node_and_dependencies: * @string: * @node: * * Adds @node to the graph, and all nodes that @node depends on both * directly and indirectly. There is no grouping of subgraphs. **/ static void gegl_dot_add_node_and_dependencies (GString *string, GeglNode *node) { GeglDotVisitor *dot_visitor; GeglPad *pad; gpointer context_id = string; dot_visitor = g_object_new (GEGL_TYPE_DOT_VISITOR, "id", context_id, NULL); gegl_dot_visitor_set_string_to_append (dot_visitor, string); /* Add the nodes */ gegl_visitor_bfs_traverse (GEGL_VISITOR (dot_visitor), GEGL_VISITABLE (node)); /* Add the edges */ pad = gegl_node_get_pad (node, "output"); if (! pad) { pad = gegl_node_get_pad (node, "input"); if (pad) { /* This is a sink node, we need to add these edges manually * since no pad depends on this input pad */ GSList *iter; for (iter = pad->connections; iter; iter = g_slist_next (iter)) { GeglConnection *connection = iter->data; gegl_dot_util_add_connection (string, connection); } } } gegl_visitor_bfs_traverse (GEGL_VISITOR (dot_visitor), GEGL_VISITABLE (pad)); g_object_unref (dot_visitor); }
void gegl_operation_set_format (GeglOperation *self, const gchar *pad_name, const Babl *format) { GeglPad *pad; g_return_if_fail (GEGL_IS_OPERATION (self)); g_return_if_fail (pad_name != NULL); pad = gegl_node_get_pad (self->node, pad_name); g_return_if_fail (pad != NULL); pad->format = format; }
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);*/ }
const Babl * gegl_operation_get_format (GeglOperation *self, const gchar *pad_name) { GeglPad *pad; g_return_val_if_fail (GEGL_IS_OPERATION (self), NULL); g_return_val_if_fail (pad_name != NULL, NULL); pad = gegl_node_get_pad (self->node, pad_name); if (pad == NULL || pad->format == NULL) { g_warning ("%s: returns NULL", G_STRFUNC); } g_return_val_if_fail (pad != NULL, NULL); return pad->format; }
GeglNode * gegl_operation_get_source_node (GeglOperation *operation, const gchar *input_pad_name) { GeglPad *pad; g_assert (operation && operation->node && input_pad_name); pad = gegl_node_get_pad (operation->node, input_pad_name); if (!pad) return NULL; pad = gegl_pad_get_connected_to (pad); if (!pad) return NULL; g_assert (gegl_pad_get_node (pad)); return gegl_pad_get_node (pad); }
/** * gegl_graph_process: * @path: The traversal path * * Process the prepared request. This will return the * resulting buffer from the final node, or NULL if * that node is a sink. * * If gegl_graph_prepare_request has not been called * the behavior of this function is undefined. * * Return value: (transfer full): The result of the graph, or NULL if * there is no output pad. */ GeglBuffer * gegl_graph_process (GeglGraphTraversal *path, gint level) { GList *list_iter = NULL; GeglBuffer *result = NULL; GeglOperationContext *context = NULL; GeglOperationContext *last_context = NULL; GeglBuffer *operation_result = NULL; for (list_iter = path->dfs_path; list_iter; list_iter = list_iter->next) { GeglNode *node = GEGL_NODE (list_iter->data); GeglOperation *operation = node->operation; g_return_val_if_fail (node, NULL); g_return_val_if_fail (operation, NULL); GEGL_INSTRUMENT_START(); operation_result = NULL; if (last_context) gegl_operation_context_purge (last_context); context = g_hash_table_lookup (path->contexts, node); g_return_val_if_fail (context, NULL); GEGL_NOTE (GEGL_DEBUG_PROCESS, "Will process %s result_rect = %d, %d %d×%d", gegl_node_get_debug_name (node), context->result_rect.x, context->result_rect.y, context->result_rect.width, context->result_rect.height); if (context->need_rect.width > 0 && context->need_rect.height > 0) { if (context->cached) { GEGL_NOTE (GEGL_DEBUG_PROCESS, "Using cached result for %s", gegl_node_get_debug_name (node)); operation_result = GEGL_BUFFER (node->cache); } else { /* provide something on input pad, always - this makes having behavior depending on it not being set.. not work, is sacrifising that worth it? */ if (gegl_node_has_pad (node, "input") && !gegl_operation_context_get_object (context, "input")) { gegl_operation_context_set_object (context, "input", G_OBJECT (gegl_graph_get_shared_empty(path))); } context->level = level; /* note: this hard-coding of "output" makes some more custom * graph topologies harder than neccesary. */ gegl_operation_process (operation, context, "output", &context->need_rect, context->level); operation_result = GEGL_BUFFER (gegl_operation_context_get_object (context, "output")); if (operation_result && operation_result == (GeglBuffer *)operation->node->cache) gegl_cache_computed (operation->node->cache, &context->need_rect, level); } } else { operation_result = NULL; } if (operation_result) { GeglPad *output_pad = gegl_node_get_pad (node, "output"); GList *targets = gegl_graph_get_connected_output_contexts (path, output_pad); GList *targets_iter; GEGL_NOTE (GEGL_DEBUG_PROCESS, "Will deliver the results of %s:%s to %d targets", gegl_node_get_debug_name (node), "output", g_list_length (targets)); if (g_list_length (targets) > 1) gegl_object_set_has_forked (G_OBJECT (operation_result)); for (targets_iter = targets; targets_iter; targets_iter = g_list_next (targets_iter)) { ContextConnection *target_con = targets_iter->data; gegl_operation_context_set_object (target_con->context, target_con->name, G_OBJECT (operation_result)); } g_list_free_full (targets, free_context_connection); } last_context = context; GEGL_INSTRUMENT_END ("process", gegl_node_get_operation (node)); } if (last_context) { if (operation_result) result = g_object_ref (operation_result); else if (gegl_node_has_pad (last_context->operation->node, "output")) result = g_object_ref (gegl_graph_get_shared_empty (path)); gegl_operation_context_purge (last_context); } return result; }