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 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 gimp_blend_tool_create_graph (GimpBlendTool *blend_tool) { GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); GimpContext *context = GIMP_CONTEXT (options); GeglNode *graph, *output, *render; /* render_node is not supposed to be recreated */ g_return_if_fail (blend_tool->graph == NULL); graph = gegl_node_new (); output = gegl_node_get_output_proxy (graph, "output"); render = gegl_node_new_child (graph, "operation", "gimp:blend", NULL); gegl_node_link (render, output); blend_tool->graph = graph; blend_tool->render_node = render; gegl_node_set (render, "context", context, NULL); }
void dt_dev_pixelpipe_create_nodes(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev) { // gegl_node_disconnect(pipe->output, "input"); // gegl_node_disconnect(pipe->scale, "input"); // for all modules in dev: GList *modules = dev->iop; GeglNode *input = pipe->input; // GeglNode *input = pipe->scale; while(modules) { // TODO: if enabled. dt_iop_module_t *module = (dt_iop_module_t *)modules->data; printf("connecting %s\n", module->op); dt_dev_pixelpipe_iop_t *piece = (dt_dev_pixelpipe_iop_t *)malloc(sizeof(dt_dev_pixelpipe_iop_t)); piece->module = module; piece->data = NULL; piece->module->init_pipe(piece->module, pipe, piece); gegl_node_link(input, piece->input); input = piece->output; pipe->nodes = g_list_append(pipe->nodes, piece); modules = g_list_next(modules); } pipe->output = input; // gegl_node_link(input, pipe->scale); // gegl_node_link(input, pipe->output); }
static void standard_output (const gchar *op_name) { GeglNode *composition, *input, *aux, *operation, *crop, *output; gchar *input_path = g_build_path (G_DIR_SEPARATOR_S, data_dir, "standard-input.png", NULL); gchar *aux_path = g_build_path (G_DIR_SEPARATOR_S, data_dir, "standard-aux.png", NULL); gchar *output_path = operation_to_path (op_name, FALSE); composition = gegl_node_new (); operation = gegl_node_create_child (composition, op_name); if (gegl_node_has_pad (operation, "output")) { input = gegl_node_new_child (composition, "operation", "gegl:load", "path", input_path, NULL); aux = gegl_node_new_child (composition, "operation", "gegl:load", "path", aux_path, NULL); crop = gegl_node_new_child (composition, "operation", "gegl:crop", "width", 200.0, "height", 200.0, NULL); output = gegl_node_new_child (composition, "operation", "gegl:png-save", "compression", 9, "path", output_path, NULL); gegl_node_link_many (operation, crop, output, NULL); if (gegl_node_has_pad (operation, "input")) gegl_node_link (input, operation); if (gegl_node_has_pad (operation, "aux")) gegl_node_connect_to (aux, "output", operation, "aux"); gegl_node_process (output); } g_free (input_path); g_free (aux_path); g_free (output_path); g_object_unref (composition); }
void save_png(MyPaintSurface *surface, const char *path, int x, int y, int width, int height) { MyPaintGeglTiledSurface *self = (MyPaintGeglTiledSurface *)surface; GeglNode *graph, *save, *source; graph = gegl_node_new(); source = gegl_node_new_child(graph, "operation", "gegl:buffer-source", "buffer", mypaint_gegl_tiled_surface_get_buffer(self), NULL); save = gegl_node_new_child(graph, "operation", "gegl:png-save", "path", path, NULL); gegl_node_link(source, save); gegl_node_process(save); g_object_unref(graph); }
static void photos_thumbnailer_generate_thumbnail_pixbuf (GObject *source_object, GAsyncResult *res, gpointer user_data) { GCancellable *cancellable; g_autoptr (GTask) task = G_TASK (user_data); g_autoptr (GdkPixbuf) pixbuf = NULL; g_autoptr (GeglBuffer) buffer = NULL; g_autoptr (GeglBuffer) buffer_oriented = NULL; GeglNode *buffer_source; GeglNode *pipeline_node; g_autoptr (GeglProcessor) processor = NULL; PhotosThumbnailerGenerateData *data; cancellable = g_task_get_cancellable (task); data = g_task_get_task_data (task); { g_autoptr (GError) error = NULL; pixbuf = photos_pixbuf_new_from_file_at_size_finish (res, &error); if (error != NULL) { g_task_return_error (task, g_steal_pointer (&error)); goto out; } } buffer = photos_gegl_buffer_new_from_pixbuf (pixbuf); buffer_oriented = photos_gegl_buffer_apply_orientation (buffer, data->orientation); buffer_source = gegl_node_new_child (data->graph, "operation", "gegl:buffer-source", "buffer", buffer_oriented, NULL); pipeline_node = photos_pipeline_get_graph (data->pipeline); gegl_node_link (buffer_source, pipeline_node); processor = gegl_node_new_processor (pipeline_node, NULL); photos_gegl_processor_process_async (processor, cancellable, photos_thumbnailer_generate_thumbnail_process, g_object_ref (task)); out: return; }
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"); } }
static gboolean test_operation (const gchar *op_name, const gchar *image, gchar *output_path) { gchar *ref_path; GeglNode *img, *ref_img, *gegl; GeglRectangle ref_bounds, comp_bounds; gint ref_pixels; gboolean result = TRUE; gegl = gegl_node_new (); ref_path = g_build_path (G_DIR_SEPARATOR_S, reference_dir, image, NULL); ref_img = gegl_node_new_child (gegl, "operation", "gegl:load", "path", ref_path, NULL); g_free (ref_path); img = gegl_node_new_child (gegl, "operation", "gegl:load", "path", output_path, NULL); ref_bounds = gegl_node_get_bounding_box (ref_img); comp_bounds = gegl_node_get_bounding_box (img); ref_pixels = ref_bounds.width * ref_bounds.height; if (ref_bounds.width != comp_bounds.width || ref_bounds.height != comp_bounds.height) { g_printf ("FAIL\n Reference and composition differ in size\n"); result = FALSE; } else { GeglNode *comparison; gdouble max_diff; comparison = gegl_node_create_child (gegl, "gegl:image-compare"); gegl_node_link (img, comparison); gegl_node_connect_to (ref_img, "output", comparison, "aux"); gegl_node_process (comparison); gegl_node_get (comparison, "max diff", &max_diff, NULL); if (max_diff < 1.0) { g_printf ("PASS\n"); result = TRUE; } else { GeglNode *output; gchar *diff_path; gdouble avg_diff_wrong, avg_diff_total; gint wrong_pixels; gegl_node_get (comparison, "avg_diff_wrong", &avg_diff_wrong, "avg_diff_total", &avg_diff_total, "wrong_pixels", &wrong_pixels, NULL); g_printf ("FAIL\n Reference image and composition differ\n" " wrong pixels : %i/%i (%2.2f%%)\n" " max Δe : %2.3f\n" " avg Δe : %2.3f (wrong) %2.3f (total)\n", wrong_pixels, ref_pixels, (wrong_pixels * 100.0 / ref_pixels), max_diff, avg_diff_wrong, avg_diff_total); diff_path = operation_to_path (op_name, TRUE); output = gegl_node_new_child (gegl, "operation", "gegl:png-save", "path", diff_path, NULL); gegl_node_link (comparison, output); gegl_node_process (output); g_free (diff_path); result = FALSE; } } g_object_unref (gegl); return result; }
static gboolean process_operations (GType type) { GType *operations; gboolean result = TRUE; guint count; gint i; operations = g_type_children (type, &count); if (!operations) { g_free (operations); return TRUE; } for (i = 0; i < count; i++) { GeglOperationClass *operation_class; const gchar *image, *xml, *name; gboolean matches; operation_class = g_type_class_ref (operations[i]); image = gegl_operation_class_get_key (operation_class, "reference-image"); xml = gegl_operation_class_get_key (operation_class, "reference-composition"); name = gegl_operation_class_get_key (operation_class, "name"); if (name == NULL) { result = result && process_operations (operations[i]); continue; } matches = g_regex_match (regex, name, 0, NULL) && !g_regex_match (exc_regex, name, 0, NULL); if (xml && matches) { GeglNode *composition; if (output_all) g_printf ("%s\n", name); else if (image) g_printf ("%s: ", name); /* more information will follow if we're testing */ composition = gegl_node_new_from_xml (xml, data_dir); if (!composition) { g_printf ("FAIL\n Composition graph is flawed\n"); result = FALSE; } else if (image || output_all) { gchar *output_path = operation_to_path (name, FALSE); GeglNode *output = gegl_node_new_child (composition, "operation", "gegl:png-save", "compression", 9, "path", output_path, NULL); gegl_node_link (composition, output); gegl_node_process (output); g_object_unref (composition); /* don't test if run with --all */ if (!output_all && image) result = test_operation (name, image, output_path) && result; g_free (output_path); } } /* if we are running with --all and the operation doesn't have a composition, use standard composition and images, don't test */ else if (output_all && matches && !(g_type_is_a (operations[i], GEGL_TYPE_OPERATION_SINK) || g_type_is_a (operations[i], GEGL_TYPE_OPERATION_TEMPORAL))) { g_printf ("%s\n", name); standard_output (name); } result = process_operations (operations[i]) && result; } g_free (operations); return result; }
static void standard_output (const gchar *op_name) { GeglNode *composition, *input, *aux, *operation, *crop, *output, *translate; GeglNode *background, *over; gchar *input_path = g_build_path (G_DIR_SEPARATOR_S, data_dir, "standard-input.png", NULL); gchar *aux_path = g_build_path (G_DIR_SEPARATOR_S, data_dir, "standard-aux.png", NULL); gchar *output_path = operation_to_path (op_name, FALSE); composition = gegl_node_new (); operation = gegl_node_create_child (composition, op_name); if (gegl_node_has_pad (operation, "output")) { input = gegl_node_new_child (composition, "operation", "gegl:load", "path", input_path, NULL); translate = gegl_node_new_child (composition, "operation", "gegl:translate", "x", 0.0, "y", 80.0, NULL); aux = gegl_node_new_child (composition, "operation", "gegl:load", "path", aux_path, NULL); crop = gegl_node_new_child (composition, "operation", "gegl:crop", "width", 200.0, "height", 200.0, NULL); output = gegl_node_new_child (composition, "operation", "gegl:png-save", "compression", 9, "path", output_path, NULL); background = gegl_node_new_child (composition, "operation", "gegl:checkerboard", "color1", gegl_color_new ("rgb(0.75,0.75,0.75)"), "color2", gegl_color_new ("rgb(0.25,0.25,0.25)"), NULL); over = gegl_node_new_child (composition, "operation", "gegl:over", NULL); if (gegl_node_has_pad (operation, "input")) gegl_node_link (input, operation); if (gegl_node_has_pad (operation, "aux")) { gegl_node_connect_to (aux, "output", translate, "input"); gegl_node_connect_to (translate, "output", operation, "aux"); } gegl_node_connect_to (background, "output", over, "input"); gegl_node_connect_to (operation, "output", over, "aux"); gegl_node_connect_to (over, "output", crop, "input"); gegl_node_connect_to (crop, "output", output, "input"); gegl_node_process (output); } g_free (input_path); g_free (aux_path); g_free (output_path); g_object_unref (composition); }
gint main (gint argc, gchar **argv) { GeglNode *gegl, *imgA, *imgB, *comparison; GeglRectangle boundsA, boundsB; gdouble max_diff, avg_diff_wrong, avg_diff_total; gint wrong_pixels, total_pixels; gegl_init (&argc, &argv); if (argc != 3) { g_print ("This is simple image difference detection tool for use in regression testing.\n" "Exit code is non zero if images are different, if they are equal" "the output will contain the string identical.\n"); g_print ("Usage: %s <imageA> <imageB>\n", argv[0]); return ERROR_WRONG_ARGUMENTS; } gegl = gegl_node_new (); imgA = gegl_node_new_child (gegl, "operation", "gegl:load", "path", argv[1], NULL); imgB = gegl_node_new_child (gegl, "operation", "gegl:load", "path", argv[2], NULL); boundsA = gegl_node_get_bounding_box (imgA); boundsB = gegl_node_get_bounding_box (imgB); total_pixels = boundsA.width * boundsA.height; if (boundsA.width != boundsB.width || boundsA.height != boundsB.height) { g_printerr ("%s and %s differ in size\n", argv[1], argv[2]); g_printerr (" %ix%i vs %ix%i\n", boundsA.width, boundsA.height, boundsB.width, boundsB.height); return ERROR_WRONG_SIZE; } comparison = gegl_node_create_child (gegl, "gegl:image-compare"); gegl_node_link (imgA, comparison); gegl_node_connect_to (imgB, "output", comparison, "aux"); gegl_node_process (comparison); gegl_node_get (comparison, "max diff", &max_diff, "avg-diff-wrong", &avg_diff_wrong, "avg-diff-total", &avg_diff_total, "wrong-pixels", &wrong_pixels, NULL); if (max_diff >= 0.1) { g_printerr ("%s and %s differ\n" " wrong pixels : %i/%i (%2.2f%%)\n" " max Δe : %2.3f\n" " avg Δe (wrong) : %2.3f(wrong) %2.3f(total)\n", argv[1], argv[2], wrong_pixels, total_pixels, (wrong_pixels*100.0/total_pixels), max_diff, avg_diff_wrong, avg_diff_total); if (!strstr (argv[2], "broken")) { GeglNode *save; gchar *debug_path = g_malloc (strlen (argv[2])+16); memcpy (debug_path, argv[2], strlen (argv[2])+1); memcpy (debug_path + strlen(argv[2])-4, "-diff.png", 11); save = gegl_node_new_child (gegl, "operation", "gegl:png-save", "path", debug_path, NULL); gegl_node_link (comparison, save); gegl_node_process (save); /*gegl_graph (sink=gegl_node ("gegl:png-save", "path", debug_path, NULL, gegl_node ("gegl:buffer-source", "buffer", debug_buf, NULL)));*/ if (max_diff > 1.5) return ERROR_PIXELS_DIFFERENT; } if (strstr (argv[2], "broken")) g_print ("because the test is expected to fail "); else g_print ("because the error is small "); g_print ("we'll say "); } g_print ("%s and %s are identical\n", argv[1], argv[2]); g_object_unref (gegl); gegl_exit (); return SUCCESS; }