static void grey_blur_buffer (GeglBuffer *input, gdouble sharpness, gdouble mask_radius, GeglBuffer **dest1, GeglBuffer **dest2) { GeglNode *gegl, *image, *write1, *write2, *blur1, *blur2; gdouble radius, std_dev1, std_dev2; gegl = gegl_node_new (); image = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", input, NULL); radius = MAX (1.0, 10 * (1.0 - sharpness)); radius = fabs (radius) + 1.0; std_dev1 = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0))); radius = fabs (mask_radius) + 1.0; std_dev2 = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0))); blur1 = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", "std_dev_x", std_dev1, "std_dev_y", std_dev1, NULL); blur2 = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", "std_dev_x", std_dev2, "std_dev_y", std_dev2, NULL); write1 = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", dest1, NULL); write2 = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", dest2, NULL); gegl_node_link_many (image, blur1, write1, NULL); gegl_node_process (write1); gegl_node_link_many (image, blur2, write2, NULL); gegl_node_process (write2); g_object_unref (gegl); }
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 *output; /* render_node is not supposed to be recreated */ g_return_if_fail (blend_tool->graph == NULL); blend_tool->graph = gegl_node_new (); blend_tool->dist_node = gegl_node_new_child (blend_tool->graph, "operation", "gegl:buffer-source", "buffer", blend_tool->dist_buffer, NULL); #if 0 blend_tool->subtract_node = gegl_node_new_child (blend_tool->graph, "operation", "gegl:subtract", NULL); blend_tool->divide_node = gegl_node_new_child (blend_tool->graph, "operation", "gegl:divide", NULL); #endif blend_tool->render_node = gegl_node_new_child (blend_tool->graph, "operation", "gimp:blend", "context", context, NULL); output = gegl_node_get_output_proxy (blend_tool->graph, "output"); gegl_node_link_many (blend_tool->dist_node, #if 0 blend_tool->subtract_node, blend_tool->divide_node, #endif blend_tool->render_node, output, NULL); gimp_blend_tool_update_graph (blend_tool); }
/* Saving an empty graph should result in a valid UTF-8 encoded XML document, * with the same basic structure as if the graph was non-empty. * * Kind-of a sanity test, should run before other tests. */ static void test_save_empty_graph (void) { const gchar * const expected_result = "<?xml version='1.0' encoding='UTF-8'?>\n<gegl>\n</gegl>\n"; GeglNode *graph; gchar *xml; graph = gegl_node_new(); xml = gegl_node_to_xml(graph, ""); assert_equivalent_xml(xml, expected_result); g_object_unref(graph); g_free(xml); }
void saturation(GeglBuffer *buffer) { GeglBuffer *buffer2; GeglNode *gegl, *source, *saturation, *sink; gegl = gegl_node_new (); source = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", buffer, NULL); saturation = gegl_node_new_child (gegl, "operation", "gegl:saturation", "scale", 1.25, NULL); sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer2, NULL); gegl_node_link_many (source, saturation, sink, NULL); gegl_node_process (sink); g_object_unref (gegl); g_object_unref (buffer2); }
void blur(GeglBuffer *buffer) { GeglBuffer *buffer2; GeglNode *gegl, *source, *node, *sink; gegl = gegl_node_new (); source = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", buffer, NULL); node = gegl_node_new_child (gegl, "operation", "gegl:brightness-contrast", "contrast", 0.2, NULL); sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer2, NULL); gegl_node_link_many (source, node, sink, NULL); gegl_node_process (sink); g_object_unref (gegl); g_object_unref (buffer2); }
static void photos_thumbnailer_generate_thumbnail_async (PhotosThumbnailer *self, const gchar *uri, const gchar *mime_type, const gchar *orientation, gint64 original_height, gint64 original_width, const gchar *const *pipeline_uris, const gchar *thumbnail_path, gint thumbnail_size, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_autoptr (GFile) file = NULL; g_autoptr (GTask) task = NULL; GQuark orientation_quark; g_autoptr (GeglNode) graph = NULL; PhotosThumbnailerGenerateData *data; g_return_if_fail (PHOTOS_IS_THUMBNAILER (self)); g_return_if_fail (uri != NULL && uri[0] != '\0'); g_return_if_fail (mime_type != NULL && mime_type[0] != '\0'); g_return_if_fail (orientation != NULL && orientation[0] != '\0'); g_return_if_fail (thumbnail_path != NULL && thumbnail_path[0] != '\0'); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); file = g_file_new_for_uri (uri); orientation_quark = g_quark_from_string (orientation); graph = gegl_node_new (); data = photos_thumbnailer_generate_data_new (file, orientation_quark, original_height, original_width, thumbnail_path, thumbnail_size, graph); task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, photos_thumbnailer_generate_thumbnail_async); g_task_set_task_data (task, data, (GDestroyNotify) photos_thumbnailer_generate_data_free); photos_pipeline_new_async (graph, pipeline_uris, cancellable, photos_thumbnailer_generate_thumbnail_pipeline, g_object_ref (task)); }
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); }
void blur(GeglBuffer *buffer) { GeglBuffer *buffer2; GeglNode *gegl, *source, *node, *sink; gegl = gegl_node_new (); source = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", buffer, NULL); node = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", "std-dev-x", 10.0, "std-dev-y", 10.0, NULL); sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer2, NULL); gegl_node_link_many (source, node, sink, NULL); gegl_node_process (sink); g_object_unref (gegl); g_object_unref (buffer2); }
static GeglBuffer * grey_blur_buffer (GeglBuffer *input, gdouble glow_radius, const GeglRectangle *result) { GeglNode *gegl, *image, *write, *blur, *crop; GeglBuffer *dest; gdouble radius, std_dev; gegl = gegl_node_new (); image = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", input, NULL); radius = fabs (glow_radius) + 1.0; std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0))); blur = gegl_node_new_child (gegl, "operation", "gegl:gaussian-blur", "std_dev_x", std_dev, "std_dev_y", std_dev, "abyss-policy", 0, NULL); crop = gegl_node_new_child (gegl, "operation", "gegl:crop", "x", (gdouble) result->x, "y", (gdouble) result->y, "width", (gdouble) result->width, "height", (gdouble) result->height, NULL); write = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &dest, NULL); gegl_node_link_many (image, blur, crop, write, NULL); gegl_node_process (write); g_object_unref (gegl); return dest; }
/* gegl:nop nodes should be discarded when saving the graph */ static void test_save_nop_nodes (void) { const gchar * const expected_result = "<?xml version='1.0' encoding='UTF-8'?>\n<gegl>\n</gegl>\n"; GeglNode *graph, *op1, *op2; gchar *xml; graph = gegl_node_new(); op1 = gegl_node_new_child(graph, "operation", "gegl:nop", NULL); op2 = gegl_node_new_child(graph, "operation", "gegl:nop", NULL); gegl_node_link_many(op1, op2, NULL); xml = gegl_node_to_xml(op2, ""); assert_equivalent_xml(xml, expected_result); g_object_unref(graph); g_free(xml); }
static gboolean test_buffer_sink_001 (void) { /* Validate that gegl:buffer-sink doesn't modify the format of its input */ gboolean result = TRUE; GeglNode *ptn, *src, *sink; GeglBuffer *src_buffer; GeglBuffer *sink_buffer = NULL; src_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, 10, 10), babl_format ("RGB u8")); ptn = gegl_node_new (); src = gegl_node_new_child (ptn, "operation", "gegl:buffer-source", "buffer", src_buffer, NULL); sink = gegl_node_new_child (ptn, "operation", "gegl:buffer-sink", "buffer", &sink_buffer, "format", NULL, NULL); gegl_node_link_many (src, sink, NULL); gegl_node_blit_buffer (sink, NULL, NULL, 0, GEGL_ABYSS_NONE); if (gegl_buffer_get_format (src_buffer) != gegl_buffer_get_format (sink_buffer)) result = FALSE; if (!gegl_rectangle_equal (gegl_buffer_get_extent (src_buffer), gegl_buffer_get_extent (sink_buffer))) result = FALSE; g_object_unref (ptn); g_object_unref (src_buffer); g_object_unref (sink_buffer); return result; }
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; }
static GraphData *create_graph(void) { GraphData *graphData = g_new(GraphData,1); graphData->graph = gegl_node_new(); graphData->node_image = gegl_node_new_child(graphData->graph, "operation","gegl:load", "path","001.png",NULL); graphData->pixbuf=NULL; graphData->node_pixbuf = gegl_node_new_child(graphData->graph, "operation","gegl:save-pixbuf", "pixbuf",&graphData->pixbuf,NULL); gegl_node_connect_to(graphData->node_image,"output",graphData->node_pixbuf,"input"); gegl_node_process (graphData->node_pixbuf); return graphData; }
void dt_dev_pixelpipe_init(dt_dev_pixelpipe_t *pipe) { pipe->changed = DT_DEV_PIPE_UNCHANGED; pipe->iwidth = 0; pipe->iheight = 0; pipe->nodes = NULL; pipe->gegl = gegl_node_new(); pipe->input_buffer = NULL; pipe->input = gegl_node_new_child(pipe->gegl, "operation", "gegl:load-buffer", NULL); // pipe->scale = gegl_node_new_child(pipe->gegl, "operation", "gegl:scale", "filter", "nearest", "x", .5, "y", .5, NULL); // pipe->output = gegl_node_new_child(pipe->gegl, "operation", "gegl:nop", NULL); pipe->output = pipe->input; // gegl_node_link(pipe->input, pipe->output); // gegl_node_link(pipe->input, pipe->scale); // gegl_node_link(pipe->scale, pipe->output); pipe->backbuf = NULL; pipe->backbuf_size = 0; pipe->processing = 0; pthread_mutex_init(&(pipe->backbuf_mutex), NULL); }
static void dump_to_png (const char *filename, GeglBuffer *buffer) { GeglNode *ptn, *src, *dst; ptn = gegl_node_new(); src = gegl_node_new_child(ptn, "operation", "gegl:buffer-source", "buffer", buffer, NULL); dst = gegl_node_new_child(ptn, "operation", "gegl:png-save", "path", filename, "compression", 6, NULL); gegl_node_connect_to (src, "output", dst, "input"); gegl_node_process(dst); g_object_unref(ptn); }
/* Test that saving a subgraph works */ static void test_save_toplevel_graph (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, *op1, *op2; GeglNode *input, *output; gchar *xml; graph = gegl_node_new(); input = gegl_node_get_input_proxy(graph, "input"); output = gegl_node_get_output_proxy(graph, "output"); op1 = gegl_node_new_child(graph, "operation", "gegl:crop", "x", 0.0, "y", 0.0, "width", 0.0, "height", 0.0, NULL); op2 = gegl_node_new_child(graph, "operation", "gegl:invert-linear", NULL); gegl_node_link_many(input, op1, op2, output, NULL); xml = gegl_node_to_xml(graph, ""); assert_equivalent_xml(xml, expected_result); g_object_unref(graph); g_free(xml); }
/* Test that saving a segment works */ static void test_save_segment (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, *op1, *op2, *src; gchar *xml; graph = gegl_node_new(); src = gegl_node_new_child(graph, "operation", "gegl:checkerboard", NULL); op1 = gegl_node_new_child(graph, "operation", "gegl:crop", "x", 0.0, "y", 0.0, "width", 0.0, "height", 0.0, NULL); op2 = gegl_node_new_child(graph, "operation", "gegl:invert-linear", NULL); gegl_node_link_many(src, op1, op2, NULL); xml = gegl_node_to_xml_full(op2, op1, ""); assert_equivalent_xml(xml, expected_result); g_object_unref(graph); g_free(xml); }
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 setup_helper_test(ViewHelperTest *test) { gpointer buf; GeglRectangle rect = {0, 0, 512, 512}; /* Create a buffer, fill it with white */ test->buffer = gegl_buffer_new(&rect, babl_format("R'G'B' u8")); buf = gegl_buffer_linear_open(test->buffer, NULL, NULL, babl_format("Y' u8")); memset(buf, 255, rect.width * rect.height); gegl_buffer_linear_close(test->buffer, buf); /* Setup a graph with two nodes, one sourcing the buffer and a no-op */ test->graph = gegl_node_new(); test->loadbuf = gegl_node_new_child(test->graph, "operation", "gegl:buffer-source", "buffer", test->buffer, NULL); test->out = gegl_node_new_child(test->graph, "operation", "gegl:nop", NULL); gegl_node_link_many(test->loadbuf, test->out, NULL); /* Setup the GeglView helper, hook up the output node to it */ test->helper = view_helper_new(); view_helper_set_node(test->helper, test->out); }
int main(int argc , char **argv) { GeglNode *load, *laplace, *gegl, *write; gegl_init (&argc, &argv); if(argv[1]==NULL || argv[2]==NULL) { g_print ("\nEdge Detection using GEGL Operation."); g_print ("\nUsage: %s <input-image> <output-image>\n", argv[0]); return 1; } gegl = gegl_node_new (); load = gegl_node_new_child (gegl, "operation", "gegl:load", "path", argv[1], NULL); laplace = gegl_node_new_child (gegl, "operation", "gegl:edge-laplace", NULL); write = gegl_node_new_child (gegl, "operation", "gegl:save", "path", argv[2], NULL); gegl_node_link_many (load, laplace, write, NULL); gegl_node_process (write); g_object_unref (gegl); gegl_exit(); return 0; }
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; }
static void load_cache (GeglProperties *op_magick_load) { if (!op_magick_load->user_data) { gchar *filename; gchar *cmd; GeglNode *graph, *sink, *loader; GeglBuffer *newbuf = NULL; /* ImageMagick backed fallback FIXME: make this robust. * maybe use pipes in a manner similar to the raw loader, * or at least use a properly unique filename */ filename = g_build_filename (g_get_tmp_dir (), "gegl-magick.png", NULL); cmd = g_strdup_printf ("convert \"%s\"'[0]' \"%s\"", op_magick_load->path, filename); if (system (cmd) == -1) g_warning ("Error executing ImageMagick convert program"); graph = gegl_node_new (); sink = gegl_node_new_child (graph, "operation", "gegl:buffer-sink", "buffer", &newbuf, NULL); loader = gegl_node_new_child (graph, "operation", "gegl:png-load", "path", filename, NULL); gegl_node_link_many (loader, sink, NULL); gegl_node_process (sink); op_magick_load->user_data = (gpointer) newbuf; g_object_unref (graph); g_free (cmd); g_free (filename); } }
/** * gimp_drawable_get_line_art_fill_buffer: * @drawable: the #GimpDrawable to edit. * @line_art: the #GimpLineArt computed as fill source. * @options: the #GimpFillOptions. * @sample_merged: * @seed_x: X coordinate to start the fill. * @seed_y: Y coordinate to start the fill. * @mask_buffer: mask of the fill in-progress when in an interactive * filling process. Set to NULL if you need a one-time * fill. * @mask_x: returned x bound of @mask_buffer. * @mask_y: returned x bound of @mask_buffer. * @mask_width: returned width bound of @mask_buffer. * @mask_height: returned height bound of @mask_buffer. * * Creates the fill buffer for a bucket fill operation on @drawable * based on @line_art and @options, without actually applying it. * If @mask_buffer is not NULL, the intermediate fill mask will also be * returned. This fill mask can later be reused in successive calls to * gimp_drawable_get_bucket_fill_buffer() for interactive filling. * * Returns: a fill buffer which can be directly applied to @drawable, or * used in a drawable filter as preview. */ GeglBuffer * gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawable, GimpLineArt *line_art, GimpFillOptions *options, gboolean sample_merged, gdouble seed_x, gdouble seed_y, GeglBuffer **mask_buffer, gdouble *mask_x, gdouble *mask_y, gint *mask_width, gint *mask_height) { GimpImage *image; GeglBuffer *buffer; GeglBuffer *new_mask; gint x, y, width, height; gint mask_offset_x = 0; gint mask_offset_y = 0; gint sel_x, sel_y, sel_width, sel_height; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL); g_return_val_if_fail (GIMP_IS_FILL_OPTIONS (options), NULL); image = gimp_item_get_image (GIMP_ITEM (drawable)); if (! gimp_item_mask_intersect (GIMP_ITEM (drawable), &sel_x, &sel_y, &sel_width, &sel_height)) return NULL; if (mask_buffer && *mask_buffer) { gfloat pixel; gegl_buffer_sample (*mask_buffer, seed_x, seed_y, NULL, &pixel, babl_format ("Y float"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); if (pixel != 0.0) /* Already selected. This seed won't change the selection. */ return NULL; } gimp_set_busy (image->gimp); /* Do a seed bucket fill...To do this, calculate a new * contiguous region. */ new_mask = gimp_pickable_contiguous_region_by_line_art (NULL, line_art, (gint) seed_x, (gint) seed_y); if (mask_buffer && *mask_buffer) { gimp_gegl_mask_combine_buffer (new_mask, *mask_buffer, GIMP_CHANNEL_OP_ADD, 0, 0); g_object_unref (*mask_buffer); } if (mask_buffer) *mask_buffer = new_mask; gimp_gegl_mask_bounds (new_mask, &x, &y, &width, &height); width -= x; height -= y; /* If there is a selection, intersect the region bounds * with the selection bounds, to avoid processing areas * that are going to be masked out anyway. The actual * intersection of the fill region with the mask data * happens when combining the fill buffer, in * gimp_drawable_apply_buffer(). */ if (! gimp_channel_is_empty (gimp_image_get_mask (image))) { gint off_x = 0; gint off_y = 0; if (sample_merged) gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); if (! gimp_rectangle_intersect (x, y, width, height, sel_x + off_x, sel_y + off_y, sel_width, sel_height, &x, &y, &width, &height)) { if (! mask_buffer) g_object_unref (new_mask); /* The fill region and the selection are disjoint; bail. */ gimp_unset_busy (image->gimp); return NULL; } } /* make sure we handle the mask correctly if it was sample-merged */ if (sample_merged) { GimpItem *item = GIMP_ITEM (drawable); gint off_x, off_y; /* Limit the channel bounds to the drawable's extents */ gimp_item_get_offset (item, &off_x, &off_y); gimp_rectangle_intersect (x, y, width, height, off_x, off_y, gimp_item_get_width (item), gimp_item_get_height (item), &x, &y, &width, &height); mask_offset_x = x; mask_offset_y = y; /* translate mask bounds to drawable coords */ x -= off_x; y -= off_y; } else { mask_offset_x = x; mask_offset_y = y; } buffer = gimp_fill_options_create_buffer (options, drawable, GEGL_RECTANGLE (0, 0, width, height), -x, -y); gimp_gegl_apply_opacity (buffer, NULL, NULL, buffer, new_mask, -mask_offset_x, -mask_offset_y, 1.0); if (gimp_fill_options_get_antialias (options)) { /* Antialias for the line art algorithm is not applied during mask * creation because it is not based on individual pixel colors. * Instead we just want to apply it on the borders of the mask at * the end (since the mask can evolve, we don't want to actually * touch it, but only the intermediate results). */ GeglNode *graph; GeglNode *input; GeglNode *op; graph = gegl_node_new (); input = gegl_node_new_child (graph, "operation", "gegl:buffer-source", "buffer", buffer, NULL); op = gegl_node_new_child (graph, "operation", "gegl:gaussian-blur", "std-dev-x", 0.5, "std-dev-y", 0.5, NULL); gegl_node_connect_to (input, "output", op, "input"); gegl_node_blit_buffer (op, buffer, NULL, 0, GEGL_ABYSS_NONE); g_object_unref (graph); } if (mask_x) *mask_x = x; if (mask_y) *mask_y = y; if (mask_width) *mask_width = width; if (mask_height) *mask_height = height; if (! mask_buffer) g_object_unref (new_mask); gimp_unset_busy (image->gimp); return buffer; }
gint main (gint argc, gchar **argv) { GeglRectangle terrain_rect; if (argc < 2) usage(); gegl_init (&argc, &argv); parse_args (argc, argv); gegl_decode = gegl_node_new (); store = gegl_node_new_child (gegl_decode, "operation", "gegl:buffer-sink", "buffer", &video_frame, NULL); load = gegl_node_new_child (gegl_decode, "operation", "gegl:ff-load", "frame", 0, "path", video_path, NULL); gegl_node_link_many (load, store, NULL); decode_frame_no (0); /* we issue a processing/decoding of a frame - to get metadata */ { gegl_node_get (load, "frame-rate", &frame_rate, NULL); total_frames = 0; gegl_node_get (load, "frames", &total_frames, NULL); if (frame_end == 0) frame_end = total_frames; } if (horizontal) terrain_rect = (GeglRectangle){0, 0, frame_end - frame_start + 1, 1024}; else terrain_rect = (GeglRectangle){0, 0, 1024, frame_end - frame_start + 1}; if (input_analysis_path && g_file_test (input_analysis_path, G_FILE_TEST_IS_REGULAR)) { GeglNode *load_graph = gegl_node_new (); GeglNode *load = gegl_node_new_child (load_graph, "operation", "gegl:load", "path", input_analysis_path, NULL); GeglNode *store = gegl_node_new_child (load_graph, "operation", "gegl:buffer-sink", "buffer", &terrain, NULL); gegl_node_link_many (load, store, NULL); gegl_node_process (store); g_object_unref (load_graph); frame_end = frame_start + gegl_buffer_get_extent (terrain)->height; /* the last frame aavilavle for analysis is the last one loaded rom cache,.. perhaps with some timeout */ } else { terrain = gegl_buffer_new (&terrain_rect, babl_format ("RGBA u8")); { gint frame; gint max_buf_pos = 0; for (frame = frame_start; frame <= frame_end; frame++) { FrameInfo info = {{0}}; uint8_t buffer[4096] = {0,}; int buffer_pos = 0; GeglRectangle terrain_row; char *p = format; GString *word = g_string_new (""); if (show_progress) { double percent_full = 100.0 * (frame-frame_start) / (frame_end-frame_start); double percent_time = time_out?100.0 * babl_ticks()/1000.0/1000.0 / time_out:0.0; fprintf (stdout, "\r%2.1f%% %i/%i (%i)", percent_full>percent_time?percent_full:percent_time, frame-frame_start, frame_end-frame_start, frame); fflush (stdout); } if (horizontal) terrain_row = (GeglRectangle){frame-frame_start, 0, 1, 1024}; else terrain_row = (GeglRectangle){0, frame-frame_start, 1024, 1}; decode_frame_no (frame); //for (int i=0;i<(signed)sizeof(buffer);i++)buffer[i]=0; while (*p == ' ') p++; for (p= format;p==format || p[-1]!='\0';p++) { if (*p != '\0' && *p != ' ') { g_string_append_c (word, *p); } else { if (!strcmp (word->str, "histogram")) { record_pix_stats (video_frame, previous_video_frame, &(info.rgb_hist[0]), &(info.rgb_square_diff)[0]); for (int i = 0; i < NEGL_RGB_HIST_SLOTS; i++) { buffer[buffer_pos] = info.rgb_hist[i]; buffer_pos++; } for (int i = 0; i < 3; i++) { buffer[buffer_pos] = info.rgb_square_diff[i]; buffer_pos++; } } else if (!strcmp (word->str, "mid-row")) { int samples = NEGL_RGB_HEIGHT; if (p[1] >= '0' && p[1] <= '9') { samples = g_strtod (&p[1], &p); } buffer_pos += extract_mid_row (video_frame, &(buffer)[buffer_pos], samples); } else if (!strcmp (word->str, "mid-col")) { int samples = NEGL_RGB_HEIGHT; if (p[1] >= '0' && p[1] <= '9') { samples = g_strtod (&p[1], &p); } buffer_pos += extract_mid_col (video_frame, &(buffer)[buffer_pos], samples); } else if (!strcmp (word->str, "thumb")) { int samples = NEGL_RGB_THEIGHT; int samples2; if (p[1] >= '0' && p[1] <= '9') { samples = g_strtod (&p[1], &p); } if (horizontal) samples2 = samples * gegl_buffer_get_width (video_frame)/gegl_buffer_get_height(video_frame); else samples2 = samples * gegl_buffer_get_height (video_frame)/gegl_buffer_get_width(video_frame); buffer_pos += extract_thumb (video_frame, &(buffer)[buffer_pos], samples, samples2); } else if (!strcmp (word->str, "audio")) { int dups = 1; GeglAudioFragment *audio = NULL; if (p[1] >= '0' && p[1] <= '9') { dups = g_strtod (&p[1], &p); } gegl_node_get (load, "audio", &audio, NULL); if (audio) { extract_audio_energy (audio, &buffer[buffer_pos], dups); g_object_unref (audio); } buffer_pos+=3 * dups; } g_string_assign (word, ""); } } max_buf_pos = buffer_pos; g_string_free (word, TRUE); gegl_buffer_set (terrain, &terrain_row, 0, babl_format("RGB u8"), buffer, GEGL_AUTO_ROWSTRIDE); if (time_out > 1.0 && babl_ticks()/1000.0/1000.0 > time_out) { frame_end = frame; if (horizontal) terrain_rect.width = frame_end - frame_start + 1; else terrain_rect.height = frame_end - frame_start + 1; // gegl_buffer_set_extent (terrain, &terrain_rect); } if (horizontal) terrain_rect.height = max_buf_pos/3; else terrain_rect.width = max_buf_pos/3; gegl_buffer_set_extent (terrain, &terrain_rect); } if (show_progress) { fprintf (stdout, "\n"); fflush (stdout); } } if (output_analysis_path) { GeglNode *save_graph = gegl_node_new (); GeglNode *readbuf = gegl_node_new_child (save_graph, "operation", "gegl:buffer-source", "buffer", terrain, NULL); GeglNode *save = gegl_node_new_child (save_graph, "operation", "gegl:png-save", "path", output_analysis_path, NULL); gegl_node_link_many (readbuf, save, NULL); gegl_node_process (save); g_object_unref (save_graph); } } if (thumb_path) { GeglNode *save_graph = gegl_node_new (); find_best_thumb (); if (frame_thumb != 0) decode_frame_no (frame_thumb-1); decode_frame_no (frame_thumb); { GeglNode *readbuf = gegl_node_new_child (save_graph, "operation", "gegl:buffer-source", "buffer", video_frame, NULL); GeglNode *save = gegl_node_new_child (save_graph, "operation", "gegl:png-save", "path", thumb_path, NULL); gegl_node_link_many (readbuf, save, NULL); gegl_node_process (save); g_object_unref (save_graph); } } if (video_frame) g_object_unref (video_frame); video_frame = NULL; if (previous_video_frame) g_object_unref (previous_video_frame); previous_video_frame = NULL; if (terrain) g_object_unref (terrain); terrain = NULL; g_object_unref (gegl_decode); gegl_exit (); return 0; }
static void gimp_n_point_deformation_tool_start (GimpNPointDeformationTool *npd_tool, GimpDisplay *display) { GimpTool *tool = GIMP_TOOL (npd_tool); GimpNPointDeformationOptions *npd_options; GimpImage *image; GeglBuffer *source_buffer; GeglBuffer *preview_buffer; NPDModel *model; npd_options = GIMP_N_POINT_DEFORMATION_TOOL_GET_OPTIONS (npd_tool); gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); image = gimp_display_get_image (display); tool->display = display; tool->drawable = gimp_image_get_active_drawable (image); npd_tool->active = TRUE; /* create GEGL graph */ source_buffer = gimp_drawable_get_buffer (tool->drawable); preview_buffer = gegl_buffer_new (gegl_buffer_get_extent (source_buffer), babl_format ("cairo-ARGB32")); npd_tool->graph = gegl_node_new (); npd_tool->source = gegl_node_new_child (npd_tool->graph, "operation", "gegl:buffer-source", "buffer", source_buffer, NULL); npd_tool->npd_node = gegl_node_new_child (npd_tool->graph, "operation", "gegl:npd", NULL); npd_tool->sink = gegl_node_new_child (npd_tool->graph, "operation", "gegl:write-buffer", "buffer", preview_buffer, NULL); gegl_node_link_many (npd_tool->source, npd_tool->npd_node, npd_tool->sink, NULL); /* initialize some options */ g_object_set (G_OBJECT (npd_options), "mesh-visible", TRUE, NULL); gimp_n_point_deformation_options_set_sensitivity (npd_options, TRUE); /* compute and get model */ gegl_node_process (npd_tool->npd_node); gegl_node_get (npd_tool->npd_node, "model", &model, NULL); npd_tool->model = model; npd_tool->preview_buffer = preview_buffer; npd_tool->selected_cp = NULL; npd_tool->hovering_cp = NULL; npd_tool->selected_cps = NULL; npd_tool->rubber_band = FALSE; npd_tool->lattice_points = g_new (GimpVector2, 5 * model->hidden_model->num_of_bones); gimp_item_get_offset (GIMP_ITEM (tool->drawable), &npd_tool->offset_x, &npd_tool->offset_y); gimp_npd_debug (("offset: %f %f\n", npd_tool->offset_x, npd_tool->offset_y)); gimp_draw_tool_start (GIMP_DRAW_TOOL (npd_tool), display); gimp_n_point_deformation_tool_perform_deformation (npd_tool); /* hide original image */ gimp_item_set_visible (GIMP_ITEM (tool->drawable), FALSE, FALSE); gimp_image_flush (image); /* create and start a deformation thread */ npd_tool->deform_thread = g_thread_new ("deform thread", (GThreadFunc) gimp_n_point_deformation_tool_deform_thread_func, npd_tool); /* create and start canvas update timeout */ npd_tool->draw_timeout_id = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT_IDLE, GIMP_NPD_DRAW_INTERVAL, (GSourceFunc) gimp_n_point_deformation_tool_canvas_update_timeout, npd_tool, NULL); }
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; }
gint main (gint argc, gchar **argv) { g_thread_init (NULL); gtk_init (&argc, &argv); gegl_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "GEGL destructive painter"); if (argv[1] == NULL) { GeglRectangle rect = {0, 0, 512, 512}; gpointer buf; /* XXX: for best overall performance, this format should probably * be RaGaBaA float, overeager in-place processing code makes that fail though. */ buffer = gegl_buffer_new (&rect, babl_format("R'G'B' u8")); /* it would be useful to have a programmatic way of doing this, filling * with a given pixel value */ buf = gegl_buffer_linear_open (buffer, NULL, NULL, babl_format ("Y' u8")); memset (buf, 255, 512 * 512); gegl_buffer_linear_close (buffer, buf); } else { buffer = gegl_buffer_open (argv[1]); } gegl = gegl_node_new (); { GeglNode *loadbuf = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", buffer, NULL); out = gegl_node_new_child (gegl, "operation", "gegl:nop", NULL); gegl_node_link_many (loadbuf, out, NULL); view = g_object_new (GEGL_TYPE_VIEW, "node", out, NULL); top = loadbuf; } g_signal_connect (GTK_OBJECT (view), "motion-notify-event", (GCallback) paint_motion, NULL); g_signal_connect (GTK_OBJECT (view), "button-press-event", (GCallback) paint_press, NULL); g_signal_connect (GTK_OBJECT (view), "button-release-event", (GCallback) paint_release, NULL); gtk_widget_add_events (view, GDK_BUTTON_RELEASE_MASK); gtk_container_add (GTK_CONTAINER (window), view); gtk_widget_set_size_request (view, 512, 512); g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (gtk_main_quit), window); gtk_widget_show_all (window); gtk_main (); g_object_unref (gegl); gegl_buffer_destroy (buffer); gegl_exit (); return 0; }
int main(int argc, char *argv[]) { gint result = SUCCESS; GeglRectangle rect1 = { 0, 0, 1, 1 }; GeglRectangle rect2 = { 1, 0, 1, 1 }; GeglRectangle rect3 = { 1, 1, 1, 1 }; GeglRectangle rect4 = { 0, 1, 1, 1 }; GeglColor *color_white = NULL; GeglColor *color_black = NULL; GeglNode *gegl = NULL; GeglNode *white = NULL; GeglNode *translate = NULL; GeglNode *over = NULL; GeglNode *black = NULL; GeglNode *crop = NULL; GeglNode *sink = NULL; GeglProcessor *processor = NULL; /* Convenient line to keep around: g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); */ gegl_init (&argc, &argv); color_white = gegl_color_new ("rgb(1.0, 1.0, 1.0)"); color_black = gegl_color_new ("rgb(0.0, 0.0, 0.0)"); gegl = gegl_node_new (); white = gegl_node_new_child (gegl, "operation", "gegl:color", "value", color_white, NULL); translate = gegl_node_new_child (gegl, "operation", "gegl:translate", "x", -50.0, "y", -20.0, NULL); over = gegl_node_new_child (gegl, "operation", "gegl:over", NULL); black = gegl_node_new_child (gegl, "operation", "gegl:color", "value", color_black, NULL); crop = gegl_node_new_child (gegl, "operation", "gegl:crop", "x", 10.0, "y", 10.0, "width", 100.0, "height", 100.0, NULL); sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", NULL); /* We build our graph for processing complexity, not for compositing * complexity */ gegl_node_link_many (black, over, sink, NULL); gegl_node_link_many (white, crop, translate, NULL); gegl_node_connect_to (translate, "output", over, "aux"); /* Create a processor */ processor = gegl_node_new_processor (sink, NULL); /* Do the tests */ if (!test_change_processor_rect_do_test (processor, &rect1, sink)) { g_printerr ("test-change-processor-rect: First compare failed\n"); result = FAILURE; goto abort; } if (!test_change_processor_rect_do_test (processor, &rect2, sink)) { g_printerr ("test-change-processor-rect: Second compare failed\n"); result = FAILURE; goto abort; } if (!test_change_processor_rect_do_test (processor, &rect3, sink)) { g_printerr ("test-change-processor-rect: Third compare failed\n"); result = FAILURE; goto abort; } if (!test_change_processor_rect_do_test (processor, &rect4, sink)) { g_printerr ("test-change-processor-rect: Fourth compare failed\n"); result = FAILURE; goto abort; } /* Cleanup */ abort: g_object_unref (processor); g_object_unref (color_white); g_object_unref (color_black); g_object_unref (gegl); gegl_exit (); return result; }
/** * 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; }