Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
/* 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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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));
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
/* 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);
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
/* 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);
}
Esempio n. 17
0
/* 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);
}
Esempio n. 18
0
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;
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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);
}
Esempio n. 21
0
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;
}
Esempio n. 22
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;
}
Esempio n. 23
0
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);
    }
}
Esempio n. 24
0
/**
 * 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;
}
Esempio n. 25
0
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);
}
Esempio n. 27
0
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;
}
Esempio n. 28
0
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;
}
Esempio n. 30
0
/**
 * 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;
}