/* gcc gegl-buffer.c $(pkg-config --cflags --libs gegl-0.3 babl cairo
   glib-2.0) */

#include <babl/babl.h>
#include <cairo.h>
#include <gegl.h>
#include <glib.h>

static const gchar *FILE_PATH = "white.png";

gint
main (void)
{
  const Babl *format;
  GeglBuffer *buffer;
  GeglNode *graph;
  GeglNode *src, *sink;
  GeglProcessor *processor;
  GeglRectangle roi;
  cairo_surface_t *surface;
  static const cairo_user_data_key_t key;
  const gchar *format_name;
  gdouble progress;
  gint stride;
  gint64 end;
  gint64 start;
  guchar *buf;

  g_setenv ("GEGL_MIPMAP_RENDERING", "1", TRUE);

  gegl_init (NULL, NULL);

  graph = gegl_node_new ();
  src = gegl_node_new_child (graph,
                             "operation", "gegl:load",
                             "path", FILE_PATH,
                             NULL);
  sink = gegl_node_new_child (graph,
                              "operation", "gegl:buffer-sink",
                              NULL);

  gegl_node_link_many (src, sink, NULL);
  gegl_node_set (sink, "buffer", &buffer, NULL);

  gegl_node_process (sink);
  g_object_unref (graph);

  format = gegl_buffer_get_format (buffer);
  format_name = babl_get_name (format);
  g_message ("%s", format_name);

  graph = gegl_node_new ();
  src = gegl_node_new_child (graph,
                             "operation", "gegl:buffer-source",
                             NULL);
  sink = gegl_node_new_child (graph,
                              "operation", "gegl:sepia",
                              NULL);

  gegl_node_link_many (src, sink, NULL);
  gegl_node_set (src, "buffer", buffer, NULL);

  processor = gegl_node_new_processor (sink, NULL);
  gegl_processor_set_level (processor, 3);

  start = g_get_monotonic_time ();
  while (gegl_processor_work (processor, &progress));
    //g_message ("%lf", progress);
  end = g_get_monotonic_time ();
  g_message ("%" G_GINT64_FORMAT, end - start);

  roi.height = 1280;
  roi.width = 1280;
  roi.x = 0;
  roi.y = 0;
  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, roi.width);
  buf = g_malloc0 (stride * roi.height);
  format = babl_format ("cairo-ARGB32");

  start = g_get_monotonic_time ();
  gegl_node_blit (sink,
                  0.125,
                  &roi,
                  format,
                  buf,
                  GEGL_AUTO_ROWSTRIDE,
                  GEGL_BLIT_DEFAULT);
  end = g_get_monotonic_time ();
  g_message ("%" G_GINT64_FORMAT, end - start);

  surface = cairo_image_surface_create_for_data (buf,
                                                 CAIRO_FORMAT_ARGB32,
                                                 roi.width,
                                                 roi.height,
                                                 stride);
  cairo_surface_set_device_scale (surface, 2.0, 2.0);
  cairo_surface_set_user_data (surface,
                               &key,
                               buf,
                               (cairo_destroy_func_t) g_free);
  cairo_surface_write_to_png (surface, "white-1.png");

  cairo_surface_destroy (surface);
  g_object_unref (processor);
  g_object_unref (graph);
  g_object_unref (buffer);
  gegl_exit ();

  return 0;
}
