/* gcc gegl-example-00.c $(pkg-config --cflags --libs gegl-0.4 glib-2.0) */ #include #include #include #include static const gdouble FONT_SIZE = 30.0; static const gdouble TEXT_HEIGHT = 45.0; static const gdouble MARGIN = 30.0; static const gdouble N_TILES_X = 2.0; static const gdouble N_TILES_Y = 3.0; static GeglNode * create_text_node (GeglNode *graph, const gchar *string) { GeglColor *color = NULL; GeglNode *text; color = gegl_color_new ("white"); text = gegl_node_new_child (graph, "operation", "gegl:text", "color", color, "font", "Cantarell", "string", string, "size", FONT_SIZE, NULL); g_object_unref (color); return text; } gint main (gint argc, gchar *argv[]) { g_autoptr (GeglBuffer) scaled_buffer = NULL; g_autoptr (GeglBuffer) source_buffer = NULL; GeglConfig *config; const GeglRectangle *scaled_extent; const GeglRectangle *source_extent; if (argc != 3) { g_printf ("%s: \n", argv[0]); return EXIT_FAILURE; } gegl_init (NULL, NULL); config = gegl_config (); g_object_set (config, "application-license", "GPL3", NULL); g_object_set (config, "use-opencl", FALSE, NULL); { g_autoptr (GeglNode) graph = NULL; GeglNode *buffer_sink; GeglNode *load; graph = gegl_node_new (); load = gegl_node_new_child (graph, "operation", "gegl:load", "path", argv[1], NULL); buffer_sink = gegl_node_new_child (graph, "operation", "gegl:buffer-sink", "buffer", &source_buffer, NULL); gegl_node_link_many (load, buffer_sink, NULL); gegl_node_process (buffer_sink); } source_extent = gegl_buffer_get_extent (source_buffer); { g_autoptr (GeglNode) graph = NULL; GeglNode *buffer_sink; GeglNode *buffer_source; GeglNode *scale_ratio; GeglNode *translate; gdouble ratio; gdouble translate_y = TEXT_HEIGHT; gint max_dimension; max_dimension = MAX (source_extent->height, source_extent->width); ratio = max_dimension > 600.0 ? 600.0 / (gdouble) max_dimension : 1.0; graph = gegl_node_new (); buffer_source = gegl_node_new_child (graph, "operation", "gegl:buffer-source", "buffer", source_buffer, NULL); scale_ratio = gegl_node_new_child (graph, "operation", "gegl:scale-ratio", "x", ratio, "y", ratio, NULL); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "y", translate_y, NULL); buffer_sink = gegl_node_new_child (graph, "operation", "gegl:buffer-sink", "buffer", &scaled_buffer, NULL); gegl_node_link_many (buffer_source, scale_ratio, translate, buffer_sink, NULL); gegl_node_process (buffer_sink); } scaled_extent = gegl_buffer_get_extent (scaled_buffer); { GeglColor *bg_color = NULL; g_autoptr (GeglNode) graph = NULL; GeglNode *buffer_source; GeglNode *over_cartoon; GeglNode *over_exposure; GeglNode *over_mosaic; GeglNode *over_original; GeglNode *over_posterize; GeglNode *over_saturation; GeglNode *rectangle; GeglNode *save; gdouble canvas_height; gdouble canvas_width; gdouble x_offset = MARGIN; gdouble y_offset = MARGIN; bg_color = gegl_color_new ("black"); canvas_height = (gdouble) scaled_extent->height * N_TILES_Y + MARGIN * (N_TILES_Y + 1) + TEXT_HEIGHT * N_TILES_Y; canvas_width = (gdouble) scaled_extent->width * N_TILES_X + MARGIN * (N_TILES_X + 1); graph = gegl_node_new (); rectangle = gegl_node_new_child (graph, "operation", "gegl:rectangle", "color", bg_color, "height", canvas_height, "width", canvas_width, "x", 0.0, "y", 0.0, NULL); buffer_source = gegl_node_new_child (graph, "operation", "gegl:buffer-source", "buffer", scaled_buffer, NULL); save = gegl_node_new_child (graph, "operation", "gegl:png-save", "bitdepth", 8, "path", argv[2], NULL); over_original = gegl_node_new_child (graph, "operation", "gegl:over", NULL); { GeglNode *over; GeglNode *text; GeglNode *translate; over = gegl_node_new_child (graph, "operation", "gegl:over", NULL); text = create_text_node (graph, "original:"); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "x", x_offset, "y", y_offset, NULL); gegl_node_connect_to (text, "output", over, "aux"); gegl_node_link_many (buffer_source, over, translate, NULL); gegl_node_connect_to (translate, "output", over_original, "aux"); } over_cartoon = gegl_node_new_child (graph, "operation", "gegl:over", NULL); x_offset += scaled_extent->width + MARGIN; { GeglNode *cartoon; GeglNode *over; GeglNode *text; GeglNode *translate; cartoon = gegl_node_new_child (graph, "operation", "gegl:cartoon", "mask-radius", 10.0, "pct-black", 0.3, NULL); over = gegl_node_new_child (graph, "operation", "gegl:over", NULL); text = create_text_node (graph, "cartoon:"); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "x", x_offset, "y", y_offset, NULL); gegl_node_connect_to (text, "output", over, "aux"); gegl_node_link_many (buffer_source, cartoon, over, translate, NULL); gegl_node_connect_to (translate, "output", over_cartoon, "aux"); } over_exposure = gegl_node_new_child (graph, "operation", "gegl:over", NULL); x_offset = MARGIN; y_offset += scaled_extent->height + MARGIN + TEXT_HEIGHT; { GeglNode *exposure; GeglNode *over; GeglNode *text; GeglNode *translate; exposure = gegl_node_new_child (graph, "operation", "gegl:exposure", "black-level", 0.04, NULL); over = gegl_node_new_child (graph, "operation", "gegl:over", NULL); text = create_text_node (graph, "blacks:"); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "x", x_offset, "y", y_offset, NULL); gegl_node_connect_to (text, "output", over, "aux"); gegl_node_link_many (buffer_source, exposure, over, translate, NULL); gegl_node_connect_to (translate, "output", over_exposure, "aux"); } over_mosaic = gegl_node_new_child (graph, "operation", "gegl:over", NULL); x_offset += scaled_extent->width + MARGIN; { GeglNode *mosaic; GeglNode *over; GeglNode *text; GeglNode *translate; mosaic = gegl_node_new_child (graph, "operation", "gegl:mosaic", "tile-size", 20.0, NULL); over = gegl_node_new_child (graph, "operation", "gegl:over", NULL); text = create_text_node (graph, "mosaic:"); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "x", x_offset, "y", y_offset, NULL); gegl_node_connect_to (text, "output", over, "aux"); gegl_node_link_many (buffer_source, mosaic, over, translate, NULL); gegl_node_connect_to (translate, "output", over_mosaic, "aux"); } over_posterize = gegl_node_new_child (graph, "operation", "gegl:over", NULL); x_offset = MARGIN; y_offset += scaled_extent->height + MARGIN + TEXT_HEIGHT; { GeglNode *over; GeglNode *posterize; GeglNode *text; GeglNode *translate; over = gegl_node_new_child (graph, "operation", "gegl:over", NULL); posterize = gegl_node_new_child (graph, "operation", "gegl:posterize", "levels", 8, NULL); text = create_text_node (graph, "posterize:"); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "x", x_offset, "y", y_offset, NULL); gegl_node_connect_to (text, "output", over, "aux"); gegl_node_link_many (buffer_source, posterize, over, translate, NULL); gegl_node_connect_to (translate, "output", over_posterize, "aux"); } over_saturation = gegl_node_new_child (graph, "operation", "gegl:over", NULL); x_offset += scaled_extent->width + MARGIN; { GeglNode *over; GeglNode *saturation; GeglNode *text; GeglNode *translate; over = gegl_node_new_child (graph, "operation", "gegl:over", NULL); saturation = gegl_node_new_child (graph, "operation", "gegl:saturation", "scale", 1.8, NULL); text = create_text_node (graph, "saturation:"); translate = gegl_node_new_child (graph, "operation", "gegl:translate", "x", x_offset, "y", y_offset, NULL); gegl_node_connect_to (text, "output", over, "aux"); gegl_node_link_many (buffer_source, saturation, over, translate, NULL); gegl_node_connect_to (translate, "output", over_saturation, "aux"); } gegl_node_link_many (rectangle, over_original, over_cartoon, over_exposure, over_mosaic, over_posterize, over_saturation, save, NULL); gegl_node_process (save); g_clear_object (&bg_color); } return EXIT_SUCCESS; }