static void attach (GeglOperation *operation) { GeglNode *gegl, *input, *output, *add, *multiply, *subtract, *blur; gegl = operation->node; input = gegl_node_get_input_proxy (gegl, "input"); output = gegl_node_get_output_proxy (gegl, "output"); add = gegl_node_new_child (gegl, "operation", "gegl:add", NULL); multiply = gegl_node_new_child (gegl, "operation", "gegl:multiply", NULL); subtract = gegl_node_new_child (gegl, "operation", "gegl:subtract", NULL); blur = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", NULL); gegl_node_link_many (input, subtract, multiply, NULL); gegl_node_link (input, blur); gegl_node_link_many (multiply, add, output, NULL); gegl_node_connect_from (subtract, "aux", blur, "output"); gegl_node_connect_from (add, "aux", input, "output"); gegl_operation_meta_redirect (operation, "scale", multiply, "value"); gegl_operation_meta_redirect (operation, "std-dev", blur, "std-dev-x"); gegl_operation_meta_redirect (operation, "std-dev", blur, "std-dev-y"); gegl_operation_meta_watch_nodes (operation, add, multiply, subtract, blur, NULL); }
static void prepare (GeglOperation *operation) { GeglProperties *o = GEGL_PROPERTIES (operation); GeglNode *gegl, *input, *output; GError *error = NULL; gegl = operation->node; if (!o->user_data || !g_str_equal (o->user_data, o->string)) { g_free (o->user_data); o->user_data = g_strdup (o->string); input = gegl_node_get_input_proxy (gegl, "input"); output = gegl_node_get_output_proxy (gegl, "output"); gegl_node_link_many (input, output, NULL); { gchar cwd[81920]; // XXX: should do better getcwd (cwd, sizeof(cwd)); gegl_create_chain (o->string, input, output, 0.0, gegl_node_get_bounding_box (input).height, cwd, &error); } if (error) { gegl_node_set (gegl, "error", error->message, NULL); g_clear_error (&error); } else g_object_set (operation, "error", "", NULL); } }
static void attach (GeglOperation *operation) { GeglNode *gegl = operation->node; GeglNode *input, *output, *subtract, *blur1, *blur2; input = gegl_node_get_input_proxy (gegl, "input"); output = gegl_node_get_output_proxy (gegl, "output"); subtract = gegl_node_new_child (gegl, "operation", "gegl:subtract", NULL); blur1 = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", NULL); blur2 = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", NULL); gegl_node_link_many (input, blur1, subtract, output, NULL); gegl_node_link (input, blur2); gegl_node_connect_from (subtract, "aux", blur2, "output"); gegl_operation_meta_redirect (operation, "radius1", blur1, "std-dev-x"); gegl_operation_meta_redirect (operation, "radius1", blur1, "std-dev-y"); gegl_operation_meta_redirect (operation, "radius2", blur2, "std-dev-x"); gegl_operation_meta_redirect (operation, "radius2", blur2, "std-dev-y"); gegl_operation_meta_watch_nodes (operation, subtract, blur1, blur2, NULL); }
static void attach (GeglOperation *operation) { GeglNode *gegl, *input, *output, *invert, *blur, *opacity, *over, *contrast; gegl = operation->node; input = gegl_node_get_input_proxy (gegl, "input"); output = gegl_node_get_output_proxy (gegl, "output"); invert = gegl_node_new_child (gegl, "operation", "gegl:invert-linear", NULL); blur = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", NULL); opacity = gegl_node_new_child (gegl, "operation", "gegl:opacity", "value", 0.5, NULL); over = gegl_node_new_child (gegl, "operation", "gegl:over", NULL); contrast = gegl_node_new_child (gegl, "operation", "gegl:brightness-contrast", NULL); gegl_node_link_many (input, invert, blur, opacity, NULL); gegl_node_connect_to (opacity, "output", over, "aux"); gegl_node_link_many (input, over, contrast, output, NULL); gegl_operation_meta_redirect (operation, "std-dev", blur, "std-dev-x"); gegl_operation_meta_redirect (operation, "std-dev", blur, "std-dev-y"); gegl_operation_meta_redirect (operation, "contrast", contrast, "contrast"); gegl_operation_meta_watch_nodes (operation, invert, blur, opacity, over, contrast, NULL); }
static void gimp_cage_tool_create_render_node (GimpCageTool *ct) { GimpCageOptions *options = GIMP_CAGE_TOOL_GET_OPTIONS (ct); GeglNode *coef, *cage, *render; /* Render nodes */ GeglNode *input, *output; /* Proxy nodes*/ GeglNode *node; /* wraper to be returned */ GObject *transform; g_return_if_fail (ct->render_node == NULL); /* render_node is not supposed to be recreated */ node = gegl_node_new (); input = gegl_node_get_input_proxy (node, "input"); output = gegl_node_get_output_proxy (node, "output"); coef = gegl_node_new_child (node, "operation", "gegl:buffer-source", "buffer", ct->coef, NULL); cage = gegl_node_new_child (node, "operation", "gimp:cage-transform", "config", ct->config, "fill_plain_color", options->fill_plain_color, NULL); render = gegl_node_new_child (node, "operation", "gegl:map-absolute", NULL); gegl_node_connect_to (input, "output", cage, "input"); gegl_node_connect_to (coef, "output", cage, "aux"); gegl_node_connect_to (input, "output", render, "input"); gegl_node_connect_to (cage, "output", render, "aux"); gegl_node_connect_to (render, "output", output, "input"); ct->render_node = node; ct->cage_node = cage; ct->coef_node = coef; g_object_get (cage, "gegl-operation", &transform, NULL); g_signal_connect (transform, "notify::progress", G_CALLBACK (gimp_cage_tool_transform_progress), ct); g_object_unref (transform); }
static void attach (GeglOperation *operation) { /** * <input (BG)> <aux (FG)> * |"output" "output"| * | | * | "input" "aux" | * +-----> <seamless-clone> <----+ * | "output"| * | | * | "input" "aux" | * +---> <overlay> <---+ * |"output" * v * <output> */ GeglNode *gegl = operation->node; GeglNode *input, *aux, *seamless, *overlay, *output; input = gegl_node_get_input_proxy (gegl, "input"); aux = gegl_node_get_input_proxy (gegl, "aux"); seamless = gegl_node_new_child (gegl, "operation", "gegl:seamless-clone", NULL); /* Don't use a regular gegl:over, since we want the alpha to be set * by the background buffer - we need this for area which had opacity * which was more than half but not fulll. */ overlay = gegl_node_new_child (gegl, "operation", "svg:src-atop", NULL); output = gegl_node_get_output_proxy (gegl, "output"); gegl_node_connect_to (input, "output", seamless, "input"); gegl_node_connect_to (aux, "output", seamless, "aux"); gegl_node_connect_to (input, "output", overlay, "input"); gegl_node_connect_to (seamless, "output", overlay, "aux"); gegl_node_connect_to (overlay, "output", output, "input"); gegl_operation_meta_redirect (operation, "max-refine-scale", seamless, "max-refine-scale"); gegl_operation_meta_redirect (operation, "xoff", seamless, "xoff"); gegl_operation_meta_redirect (operation, "yoff", seamless, "yoff"); gegl_operation_meta_redirect (operation, "error-msg", seamless, "error-msg"); gegl_operation_meta_watch_nodes (operation, seamless, overlay, NULL); }
static void attach (GeglOperation *operation) { GeglNode *gegl, *input, *output; gegl = operation->node; input = gegl_node_get_input_proxy (gegl, "input"); output = gegl_node_get_output_proxy (gegl, "output"); gegl_node_link_many (input, output, NULL); }
GeglNode * gimp_filter_stack_get_graph (GimpFilterStack *stack) { GList *list; GeglNode *first = NULL; GeglNode *previous = NULL; GeglNode *input; GeglNode *output; g_return_val_if_fail (GIMP_IS_FILTER_STACK (stack), NULL); if (stack->graph) return stack->graph; stack->graph = gegl_node_new (); for (list = GIMP_LIST (stack)->queue->tail; list; list = g_list_previous (list)) { GimpFilter *filter = list->data; GeglNode *node = gimp_filter_get_node (filter); if (! first) first = node; gegl_node_add_child (stack->graph, node); if (previous) gegl_node_connect_to (previous, "output", node, "input"); previous = node; } input = gegl_node_get_input_proxy (stack->graph, "input"); output = gegl_node_get_output_proxy (stack->graph, "output"); if (first && previous) { gegl_node_connect_to (input, "output", first, "input"); gegl_node_connect_to (previous, "output", output, "input"); } else { gegl_node_connect_to (input, "output", output, "input"); } return stack->graph; }
/* Test that saving a segment that is a subgraph works */ static void test_save_segment_subgraph (void) { const gchar * const expected_result = \ "<?xml version='1.0' encoding='UTF-8'?>\n\ <gegl>\n\ <node operation='gegl:invert-linear'>\n\ </node>\n\ <node operation='gegl:crop'>\n\ <params>\n\ <param name='x'>0</param>\n\ <param name='y'>0</param>\n\ <param name='width'>0</param>\n\ <param name='height'>0</param>\n\ <param name='reset-origin'>false</param>\n\ </params>\n\ </node>\n\ </gegl>\n"; GeglNode *graph, *src, *subgraph; GeglNode *input, *op1, *op2, *output; gchar *xml; graph = gegl_node_new(); src = gegl_node_new_child(graph, "operation", "gegl:checkerboard", NULL); subgraph = gegl_node_new(); gegl_node_add_child(graph, subgraph); g_object_unref(subgraph); input = gegl_node_get_input_proxy(subgraph, "input"); output = gegl_node_get_output_proxy(subgraph, "output"); op1 = gegl_node_new_child(subgraph, "operation", "gegl:crop", "x", 0.0, "y", 0.0, "width", 0.0, "height", 0.0, NULL); op2 = gegl_node_new_child(subgraph, "operation", "gegl:invert-linear", NULL); gegl_node_link_many(src, subgraph, NULL); gegl_node_link_many(input, op1, op2, output, NULL); xml = gegl_node_to_xml_full(subgraph, subgraph, ""); assert_equivalent_xml(xml, expected_result); g_object_unref(graph); g_free(xml); }
static void gimp_filter_stack_add_node (GimpFilterStack *stack, GimpFilter *filter) { GimpFilter *filter_below; GeglNode *node_above; GeglNode *node_below; GeglNode *node; gint index; node = gimp_filter_get_node (filter); index = gimp_container_get_child_index (GIMP_CONTAINER (stack), GIMP_OBJECT (filter)); if (index == 0) { node_above = gegl_node_get_output_proxy (stack->graph, "output"); } else { GimpFilter *filter_above = (GimpFilter *) gimp_container_get_child_by_index (GIMP_CONTAINER (stack), index - 1); node_above = gimp_filter_get_node (filter_above); } gegl_node_connect_to (node, "output", node_above, "input"); filter_below = (GimpFilter *) gimp_container_get_child_by_index (GIMP_CONTAINER (stack), index + 1); if (filter_below) { node_below = gimp_filter_get_node (filter_below); } else { node_below = gegl_node_get_input_proxy (stack->graph, "input"); } gegl_node_connect_to (node_below, "output", node, "input"); }
static gpointer test (gpointer data) { GeglNode *node; GeglNode *input; GeglNode *last; gint i; node = gegl_node_new (); input = gegl_node_get_input_proxy (node, "input"); last = input; for (i = 0; i < 64; i++) { GeglNode *over; over = gegl_node_new_child (node, "operation", "gegl:over", NULL); gegl_node_connect_to (last, "output", over, "input"); gegl_node_connect_to (last, "output", over, "aux"); last = over; } gegl_node_invalidated (input, NULL, FALSE); g_object_unref (node); g_mutex_lock (&mutex); finished = TRUE; g_cond_signal (&cond); g_mutex_unlock (&mutex); return NULL; }
/* in attach we hook into graph adding the needed nodes */ static void attach (GeglOperation *operation) { GeglNode *gegl = operation->node; GeglNode *input, *output, *over, *translate, *opacity, *blur, *darken, *color; GeglColor *black_color = gegl_color_new ("rgb(0.0,0.0,0.0)"); input = gegl_node_get_input_proxy (gegl, "input"); output = gegl_node_get_output_proxy (gegl, "output"); over = gegl_node_new_child (gegl, "operation", "gegl:over", NULL); translate = gegl_node_new_child (gegl, "operation", "gegl:translate", NULL); opacity = gegl_node_new_child (gegl, "operation", "gegl:opacity", NULL); blur = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", "clip-extent", FALSE, "abyss-policy", 0, NULL); darken = gegl_node_new_child (gegl, "operation", "gegl:src-in", NULL); color = gegl_node_new_child (gegl, "operation", "gegl:color", "value", black_color, NULL); g_object_unref (black_color); gegl_node_link_many (input, darken, blur, opacity, translate, over, output, NULL); gegl_node_connect_from (over, "aux", input, "output"); gegl_node_connect_from (darken, "aux", color, "output"); gegl_operation_meta_redirect (operation, "radius", blur, "std-dev-x"); gegl_operation_meta_redirect (operation, "radius", blur, "std-dev-y"); gegl_operation_meta_redirect (operation, "x", translate, "x"); gegl_operation_meta_redirect (operation, "y", translate, "y"); gegl_operation_meta_redirect (operation, "color", color, "value"); gegl_operation_meta_redirect (operation, "opacity", opacity, "value"); gegl_operation_meta_watch_nodes (operation, over, translate, opacity, blur, darken, color, NULL); }
static void attach (GeglOperation *operation) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); Priv *priv = g_new0 (Priv, 1); o->chant_data = (void*) priv; if (!priv->blur1) { GeglNode *gegl; gegl = operation->node; priv->input = gegl_node_get_input_proxy (gegl, "input"); priv->output = gegl_node_get_output_proxy (gegl, "output"); priv->subtract = gegl_node_new_child (gegl, "operation", "gegl:subtract", NULL); priv->blur1 = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", NULL); priv->blur2 = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", NULL); gegl_node_link_many (priv->input, priv->blur1, priv->subtract, priv->output, NULL); gegl_node_link (priv->input, priv->blur2); gegl_node_connect_from (priv->subtract, "aux", priv->blur2, "output"); gegl_operation_meta_redirect (operation, "radius1", priv->blur1, "std-dev-x"); gegl_operation_meta_redirect (operation, "radius1", priv->blur1, "std-dev-y"); gegl_operation_meta_redirect (operation, "radius2", priv->blur2, "std-dev-x"); gegl_operation_meta_redirect (operation, "radius2", priv->blur2, "std-dev-y"); } }
GeglNode * gimp_gegl_create_apply_opacity_node (GeglBuffer *mask, gint mask_offset_x, gint mask_offset_y, gdouble opacity) { GeglNode *node; GeglNode *input; GeglNode *output; GeglNode *opacity_node; GeglNode *mask_source; g_return_val_if_fail (GEGL_IS_BUFFER (mask), NULL); node = gegl_node_new (); input = gegl_node_get_input_proxy (node, "input"); output = gegl_node_get_output_proxy (node, "output"); opacity_node = gegl_node_new_child (node, "operation", "gegl:opacity", "value", opacity, NULL); mask_source = gimp_gegl_add_buffer_source (node, mask, mask_offset_x, mask_offset_y); gegl_node_connect_to (input, "output", opacity_node, "input"); gegl_node_connect_to (mask_source, "output", opacity_node, "aux"); gegl_node_connect_to (opacity_node, "output", output, "input"); return node; }
GeglNode * gimp_gegl_create_flatten_node (const GimpRGB *background) { GeglNode *node; GeglNode *input; GeglNode *output; GeglNode *color; GeglNode *over; GeglColor *c; g_return_val_if_fail (background != NULL, NULL); node = gegl_node_new (); input = gegl_node_get_input_proxy (node, "input"); output = gegl_node_get_output_proxy (node, "output"); c = gimp_gegl_color_new (background); color = gegl_node_new_child (node, "operation", "gegl:color", "value", c, NULL); g_object_unref (c); over = gegl_node_new_child (node, "operation", "gegl:over", NULL); gegl_node_connect_to (input, "output", over, "aux"); gegl_node_connect_to (color, "output", over, "input"); gegl_node_connect_to (over, "output", output, "input"); return node; }
static void gimp_warp_tool_create_graph (GimpWarpTool *wt) { GeglNode *graph; /* Wraper to be returned */ GeglNode *input, *output; /* Proxy nodes */ GeglNode *coords, *render; /* Render nodes */ /* render_node is not supposed to be recreated */ g_return_if_fail (wt->graph == NULL); graph = gegl_node_new (); input = gegl_node_get_input_proxy (graph, "input"); output = gegl_node_get_output_proxy (graph, "output"); coords = gegl_node_new_child (graph, "operation", "gegl:buffer-source", "buffer", wt->coords_buffer, NULL); render = gegl_node_new_child (graph, "operation", "gegl:map-relative", NULL); gegl_node_connect_to (input, "output", render, "input"); gegl_node_connect_to (coords, "output", render, "aux"); gegl_node_connect_to (render, "output", output, "input"); wt->graph = graph; wt->render_node = render; }
GimpApplicator * gimp_applicator_new (GeglNode *parent, gboolean linear, gboolean use_split_preview, gboolean use_result_cache) { GimpApplicator *applicator; g_return_val_if_fail (parent == NULL || GEGL_IS_NODE (parent), NULL); applicator = g_object_new (GIMP_TYPE_APPLICATOR, NULL); applicator->linear = linear; if (parent) applicator->node = g_object_ref (parent); else applicator->node = gegl_node_new (); applicator->input_node = gegl_node_get_input_proxy (applicator->node, "input"); applicator->aux_node = gegl_node_get_input_proxy (applicator->node, "aux"); applicator->output_node = gegl_node_get_output_proxy (applicator->node, "output"); applicator->mode_node = gegl_node_new_child (applicator->node, "operation", "gimp:normal-mode", NULL); gimp_gegl_mode_node_set_mode (applicator->mode_node, applicator->paint_mode, applicator->linear); gimp_gegl_mode_node_set_opacity (applicator->mode_node, applicator->opacity); gegl_node_connect_to (applicator->input_node, "output", applicator->mode_node, "input"); applicator->apply_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); applicator->dup_apply_buffer_node = gegl_node_new_child (applicator->node, "operation", "gegl:copy-buffer", NULL); gegl_node_link_many (applicator->aux_node, applicator->apply_offset_node, applicator->dup_apply_buffer_node, NULL); if (use_split_preview) { applicator->preview_cache_node = gegl_node_new_child (applicator->node, "operation", "gegl:cache", NULL); applicator->preview_crop_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); gegl_node_link_many (applicator->dup_apply_buffer_node, applicator->preview_cache_node, applicator->preview_crop_node, NULL); gegl_node_connect_to (applicator->preview_crop_node, "output", applicator->mode_node, "aux"); } else { gegl_node_connect_to (applicator->dup_apply_buffer_node, "output", applicator->mode_node, "aux"); } applicator->mask_node = gegl_node_new_child (applicator->node, "operation", "gegl:buffer-source", NULL); applicator->mask_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); gegl_node_connect_to (applicator->mask_node, "output", applicator->mask_offset_node, "input"); /* don't connect the the mask offset node to mode's aux2 yet */ applicator->affect_node = gegl_node_new_child (applicator->node, "operation", "gimp:mask-components", "mask", applicator->affect, NULL); if (use_result_cache) { applicator->output_cache_node = gegl_node_new_child (applicator->node, "operation", "gegl:cache", NULL); gegl_node_link_many (applicator->input_node, applicator->affect_node, applicator->output_cache_node, applicator->output_node, NULL); } else { gegl_node_link_many (applicator->input_node, applicator->affect_node, applicator->output_node, NULL); } gegl_node_connect_to (applicator->mode_node, "output", applicator->affect_node, "aux"); return applicator; }
/** * gimp_seamless_clone_tool_create_render_node: * @sc: The GimpSeamlessCloneTool to initialize * * This function creates a Gegl node graph of the composition which is * needed to render the drawable. The graph should have an "input" pad * which will receive the drawable on which the preview is applied, and * it should also have an "output" pad to which the final result will be * rendered */ static void gimp_seamless_clone_tool_create_render_node (GimpSeamlessCloneTool *sc) { /* Here is a textual description of the graph we are going to create: * * <input> <- drawable * +--+--------------------------+ * | |output | * | | | * | | <buffer-source> <- paste | * | | |output | * | | | | * | |input |aux | * |<seamless-paste-render> | * | |output | * | | | * | |input | * +----+------------------------+ * <output> */ GimpSeamlessCloneOptions *options = GIMP_SEAMLESS_CLONE_TOOL_GET_OPTIONS (sc); GeglNode *node; GeglNode *op, *paste, *overlay; GeglNode *input, *output; node = gegl_node_new (); input = gegl_node_get_input_proxy (node, "input"); output = gegl_node_get_output_proxy (node, "output"); paste = gegl_node_new_child (node, "operation", "gegl:buffer-source", "buffer", sc->paste, NULL); op = gegl_node_new_child (node, "operation", "gegl:seamless-clone", "max-refine-scale", options->max_refine_scale, NULL); overlay = gegl_node_new_child (node, "operation", "svg:dst-over", NULL); gegl_node_connect_to (input, "output", op, "input"); gegl_node_connect_to (paste, "output", op, "aux"); gegl_node_connect_to (op, "output", overlay, "input"); gegl_node_connect_to (input, "output", overlay, "aux"); gegl_node_connect_to (overlay, "output", output, "input"); sc->render_node = node; sc->sc_node = op; }
static void attach (GeglOperation *operation) { JsonOp *self = (JsonOp *)operation; GeglNode *gegl = operation->node; JsonArray *connections; GList *l; // Processes JsonObject *root = self->json_root; JsonObject *processes = json_object_get_object_member(root, "processes"); GList *process_names = json_object_get_members(processes); for (l = process_names; l != NULL; l = l->next) { const gchar *name = l->data; JsonObject *proc = json_object_get_object_member(processes, name); const gchar *component = json_object_get_string_member(proc, "component"); gchar *opname = component2geglop(component); GeglNode *node = gegl_node_new_child (gegl, "operation", opname, NULL); gegl_operation_meta_watch_node (operation, node); g_assert(node); g_hash_table_insert(self->nodes, (gpointer)g_strdup(name), (gpointer)node); g_free(opname); } g_list_free(process_names); // Connections connections = json_object_get_array_member(root, "connections"); g_assert(connections); for (int i=0; i<json_array_get_length(connections); i++) { JsonObject *conn = json_array_get_object_element(connections, i); JsonObject *tgt = json_object_get_object_member(conn, "tgt"); const gchar *tgt_proc = json_object_get_string_member(tgt, "process"); const gchar *tgt_port = json_object_get_string_member(tgt, "port"); GeglNode *tgt_node = g_hash_table_lookup(self->nodes, tgt_proc); JsonNode *srcnode; g_assert(tgt_node); srcnode = json_object_get_member(conn, "src"); if (srcnode) { // Connection JsonObject *src = json_object_get_object_member(conn, "src"); const gchar *src_proc = json_object_get_string_member(src, "process"); const gchar *src_port = json_object_get_string_member(src, "port"); GeglNode *src_node = g_hash_table_lookup(self->nodes, src_proc); g_assert(src_node); gegl_node_connect_to (src_node, src_port, tgt_node, tgt_port); } else { // IIP JsonNode *datanode = json_object_get_member(conn, "data"); GValue value = G_VALUE_INIT; GParamSpec *paramspec; g_assert(JSON_NODE_HOLDS_VALUE(datanode)); json_node_get_value(datanode, &value); paramspec = gegl_node_find_property(tgt_node, tgt_port); set_prop(tgt_node, tgt_port, paramspec, &value); g_value_unset(&value); } } // Exported ports if (json_object_has_member(root, "inports")) { JsonObject *inports = json_object_get_object_member(root, "inports"); GList *inport_names = json_object_get_members(inports); for (l = inport_names; l != NULL; l = l->next) { const gchar *name = l->data; JsonObject *conn = json_object_get_object_member(inports, name); const gchar *proc = json_object_get_string_member(conn, "process"); const gchar *port = json_object_get_string_member(conn, "port"); GeglNode *node = g_hash_table_lookup(self->nodes, proc); g_assert(node); if (g_strcmp0(name, "input") == 0) { GeglNode *input = gegl_node_get_input_proxy (gegl, "input"); gegl_node_connect_to (input, "output", node, "input"); } else { gegl_operation_meta_redirect (operation, name, node, port); } } g_list_free(inport_names); } if (json_object_has_member(root, "outports")) { JsonObject *outports = json_object_get_object_member(root, "outports"); GList *outport_names = json_object_get_members(outports); for (l = outport_names; l != NULL; l = l->next) { const gchar *name = l->data; JsonObject *conn = json_object_get_object_member(outports, name); const gchar *proc = json_object_get_string_member(conn, "process"); const gchar *port = json_object_get_string_member(conn, "port"); GeglNode *node = g_hash_table_lookup(self->nodes, proc); g_assert(node); if (g_strcmp0(name, "output") == 0) { GeglNode *proxy = gegl_node_get_output_proxy (gegl, "output"); gegl_node_connect_to (node, port, proxy, "input"); } else { g_warning("Unsupported output '%s' exported in .json file", name); } } g_list_free(outport_names); } }
GimpApplicator * gimp_applicator_new (GeglNode *parent) { GimpApplicator *applicator; g_return_val_if_fail (parent == NULL || GEGL_IS_NODE (parent), NULL); applicator = g_object_new (GIMP_TYPE_APPLICATOR, NULL); if (parent) applicator->node = g_object_ref (parent); else applicator->node = gegl_node_new (); applicator->input_node = gegl_node_get_input_proxy (applicator->node, "input"); applicator->aux_node = gegl_node_get_input_proxy (applicator->node, "aux"); applicator->output_node = gegl_node_get_output_proxy (applicator->node, "output"); applicator->mode_node = gegl_node_new_child (applicator->node, "operation", "gimp:normal", NULL); gimp_gegl_mode_node_set_mode (applicator->mode_node, applicator->paint_mode, applicator->blend_space, applicator->composite_space, applicator->composite_mode); gimp_gegl_mode_node_set_opacity (applicator->mode_node, applicator->opacity); gegl_node_connect_to (applicator->input_node, "output", applicator->mode_node, "input"); applicator->apply_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); gegl_node_link_many (applicator->aux_node, applicator->apply_offset_node, NULL); gegl_node_connect_to (applicator->apply_offset_node, "output", applicator->mode_node, "aux"); applicator->mask_node = gegl_node_new_child (applicator->node, "operation", "gegl:buffer-source", NULL); applicator->mask_offset_node = gegl_node_new_child (applicator->node, "operation", "gegl:translate", NULL); gegl_node_connect_to (applicator->mask_node, "output", applicator->mask_offset_node, "input"); /* don't connect the the mask offset node to mode's aux2 yet */ applicator->affect_node = gegl_node_new_child (applicator->node, "operation", "gimp:mask-components", "mask", applicator->affect, NULL); applicator->convert_format_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); applicator->cache_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); applicator->crop_node = gegl_node_new_child (applicator->node, "operation", "gegl:nop", NULL); gegl_node_link_many (applicator->input_node, applicator->affect_node, applicator->convert_format_node, applicator->cache_node, applicator->crop_node, applicator->output_node, NULL); gegl_node_connect_to (applicator->mode_node, "output", applicator->affect_node, "aux"); return applicator; }