Beispiel #1
0
static void
gegl_buffer_dispose (GObject *object)
{
  GeglBuffer  *buffer  = GEGL_BUFFER (object);
  GeglTileHandler *handler = GEGL_TILE_HANDLER (object);

  gegl_buffer_sample_cleanup (buffer);

  if (gegl_cl_is_accelerated ())
    gegl_buffer_cl_cache_invalidate (GEGL_BUFFER (object), NULL);

  if (handler->source &&
      GEGL_IS_TILE_STORAGE (handler->source))
    {
      GeglTileBackend *backend = gegl_buffer_backend (buffer);

      /* only flush non-internal backends,. */
      if (!(GEGL_IS_TILE_BACKEND_FILE (backend) ||
            GEGL_IS_TILE_BACKEND_RAM (backend) ||
            GEGL_IS_TILE_BACKEND_TILE_DIR (backend)))
        gegl_buffer_flush (buffer);

      gegl_tile_source_reinit (GEGL_TILE_SOURCE (handler->source));

#if 0
      g_object_unref (handler->source);
      handler->source = NULL; /* this might be a dangerous way of marking that we have already voided */
#endif
    }

  _gegl_buffer_drop_hot_tile (buffer);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
Beispiel #2
0
static void
apply_whirl_pinch (gdouble whirl, gdouble pinch, gdouble radius,
                   gdouble cen_x, gdouble cen_y,
                   Babl    *format,
                   GeglBuffer *src,
                   GeglRectangle *in_boundary,
                   GeglBuffer *dst,
                   GeglRectangle *boundary,
                   const GeglRectangle *roi)
{
  gfloat *dst_buf;
  gint row, col;
  gdouble scale_x, scale_y;
  gdouble cx, cy;

  /* Get buffer in which to place dst pixels. */
  dst_buf = g_new0 (gfloat, roi->width * roi->height * 4);

  whirl = whirl * G_PI / 180;

  scale_x = 1.0;
  scale_y = roi->width / (gdouble) roi->height;

  for (row = 0; row < roi->height; row++) {
    for (col = 0; col < roi->width; col++) {

        calc_undistorted_coords (roi->x + col, roi->y + row,
                                 cen_x, cen_y,
                                 scale_x, scale_y,
                                 whirl, pinch, radius,
                                 &cx, &cy);

        gegl_buffer_sample (src, cx, cy, 1.0, &dst_buf[(row * roi->width + col) * 4], format,  GEGL_INTERPOLATION_LINEAR);
    } /* for */
  } /* for */

  gegl_buffer_sample_cleanup (src);

  /* Store dst pixels. */
  gegl_buffer_set (dst, roi, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

  gegl_buffer_flush(dst);

  g_free (dst_buf);

}
Beispiel #3
0
/* Apply the actual transform */
static void
apply_spread (gint                 x_amount,
              gint                 y_amount,
              gint                 img_width,
              gint                 img_height,
              const Babl          *format,
              GeglBuffer          *src,
              GeglBuffer          *dst,
              const GeglRectangle *roi)
{
  gfloat *dst_buf;
  gint x1, y1; // Noise image
  gdouble x, y;   // Source Image

  GRand    *gr = g_rand_new ();

  /* Get buffer in which to place dst pixels. */
  dst_buf = g_new0 (gfloat, roi->width * roi->height * 4);

  for (y1 = 0; y1 < roi->height; y1++) {
    for (x1 = 0; x1 < roi->width; x1++) {

      calc_sample_coords (x1, y1, x_amount, y_amount, gr, &x, &y);
      /* Only displace the pixel if it's within the bounds of the image. */
      if (x >= 0 && x < img_width && y >= 0 && y < img_height)
        gegl_buffer_sample (src, x, y, NULL, &dst_buf[(y1 * roi->width + x1) * 4], format,
                            GEGL_SAMPLER_LINEAR, GEGL_ABYSS_NONE);
      else /* Else just copy it */
        gegl_buffer_sample (src, x1, y1, NULL, &dst_buf[(y1 * roi->width + x1) * 4], format,
                            GEGL_SAMPLER_LINEAR, GEGL_ABYSS_NONE);
    } /* for */
  } /* for */

  gegl_buffer_sample_cleanup (src);

  /* Store dst pixels. */
  gegl_buffer_set (dst, roi, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

  gegl_buffer_flush(dst);

  g_free (dst_buf);
  g_rand_free (gr);
}
Beispiel #4
0
/* Create a layer with the provided image data and add it to the image */
gboolean create_layer(gint32   image_ID,
                      uint8_t *layer_data,
                      gint32   position,
                      gchar   *name,
                      gint     width,
                      gint     height,
                      gint32   offsetx,
                      gint32   offsety)
{
    gint32        layer_ID;
#ifdef GIMP_2_9
    GeglBuffer   *geglbuffer;
    GeglRectangle extent;
#else
    GimpDrawable *drawable;
    GimpPixelRgn  region;
#endif

    layer_ID = gimp_layer_new(image_ID,
                              name,
                              width, height,
	                          GIMP_RGBA_IMAGE,
	                          100,
                              GIMP_NORMAL_MODE);

#ifdef GIMP_2_9
	/* Retrieve the buffer for the layer */
	geglbuffer = gimp_drawable_get_buffer(layer_ID);

	/* Copy the image data to the region */
    gegl_rectangle_set(&extent, 0, 0, width, height);
    gegl_buffer_set(geglbuffer, &extent, 0, NULL, layer_data, GEGL_AUTO_ROWSTRIDE);

	/* Flush the drawable and detach */
    gegl_buffer_flush(geglbuffer);

	g_object_unref(geglbuffer);
#else
    /* Retrieve the drawable for the layer */
    drawable = gimp_drawable_get(layer_ID);

    /* Get a pixel region from the layer */
    gimp_pixel_rgn_init(&region,
                        drawable,
                        0, 0,
                        width, height,
                        FALSE, FALSE);

    /* Copy the image data to the region */
    gimp_pixel_rgn_set_rect(&region,
                            layer_data,
                            0, 0,
                            width, height);

    /* Flush the drawable and detach */
    gimp_drawable_flush(drawable);
    gimp_drawable_detach(drawable);
#endif

    /* Add the new layer to the image */
    gimp_image_insert_layer(image_ID, layer_ID, -1, position);

    /* If layer offsets were provided, use them to position the image */
    if (offsetx || offsety) {
        gimp_layer_set_offsets(layer_ID, offsetx, offsety);
    }

    /* TODO: fix this */
    return TRUE;
}
Beispiel #5
0
static void
do_zcrop (gint32  drawable_id,
          gint32  image_id)
{
  GeglBuffer  *drawable_buffer;
  GeglBuffer  *shadow_buffer;
  gfloat      *linear_buf;
  const Babl  *format;

  gint         x, y, width, height;
  gint         components;
  gint8       *killrows;
  gint8       *killcols;
  gint32       livingrows, livingcols, destrow, destcol;
  gint32       selection_copy_id;
  gboolean     has_alpha;

  drawable_buffer = gimp_drawable_get_buffer (drawable_id);
  shadow_buffer   = gimp_drawable_get_shadow_buffer (drawable_id);

  width  = gegl_buffer_get_width (drawable_buffer);
  height = gegl_buffer_get_height (drawable_buffer);
  has_alpha = gimp_drawable_has_alpha (drawable_id);

  if (has_alpha)
    format = babl_format ("R'G'B'A float");
  else
    format = babl_format ("R'G'B' float");

  components = babl_format_get_n_components (format);

  killrows = g_new (gint8, height);
  killcols = g_new (gint8, width);

  linear_buf = g_new (gfloat, (width > height ? width : height) * components);

  /* search which rows to remove */

  livingrows = 0;
  for (y = 0; y < height; y++)
    {
      gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (0, y, width, 1),
                       1.0, format, linear_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      killrows[y] = TRUE;

      for (x = components; x < width * components; x += components)
        {
          if (! colors_equal (linear_buf, &linear_buf[x], components, has_alpha))
            {
              livingrows++;
              killrows[y] = FALSE;
              break;
            }
        }
    }

  gimp_progress_update (0.25);

  /* search which columns to remove */

  livingcols = 0;
  for (x = 0; x < width; x++)
    {
      gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (x, 0, 1, height),
                       1.0, format, linear_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      killcols[x] = TRUE;

      for (y = components; y < height * components; y += components)
        {
          if (! colors_equal (linear_buf, &linear_buf[y], components, has_alpha))
            {
              livingcols++;
              killcols[x] = FALSE;
              break;
            }
        }
    }

  gimp_progress_update (0.5);

  if ((livingcols == 0 || livingrows == 0) ||
      (livingcols == width && livingrows == height))
    {
      g_message (_("Nothing to crop."));
      g_free (linear_buf);
      g_free (killrows);
      g_free (killcols);
      return;
    }

  /* restitute living rows */

  destrow = 0;
  for (y = 0; y < height; y++)
    {
      if (!killrows[y])
        {
          gegl_buffer_copy (drawable_buffer,
                            GEGL_RECTANGLE (0, y, width, 1),
                            GEGL_ABYSS_NONE,
                            shadow_buffer,
                            GEGL_RECTANGLE (0, destrow, width, 1));

          destrow++;
        }
    }

  gimp_progress_update (0.75);

  /* restitute living columns */

  destcol = 0;
  for (x = 0; x < width; x++)
    {
      if (!killcols[x])
        {
          gegl_buffer_copy (shadow_buffer,
                            GEGL_RECTANGLE (x, 0, 1, height),
                            GEGL_ABYSS_NONE,
                            shadow_buffer,
                            GEGL_RECTANGLE (destcol, 0, 1, height));

          destcol++;
        }
    }

  gimp_progress_update (1.00);

  gimp_image_undo_group_start (image_id);

  selection_copy_id = gimp_selection_save (image_id);
  gimp_selection_none (image_id);

  gegl_buffer_flush (shadow_buffer);
  gimp_drawable_merge_shadow (drawable_id, TRUE);
  gegl_buffer_flush (drawable_buffer);

  gimp_image_select_item (image_id, GIMP_CHANNEL_OP_REPLACE, selection_copy_id);
  gimp_image_remove_channel (image_id, selection_copy_id);

  gimp_image_crop (image_id, livingcols, livingrows, 0, 0);

  gimp_image_undo_group_end (image_id);

  g_object_unref (shadow_buffer);
  g_object_unref (drawable_buffer);

  g_free (linear_buf);
  g_free (killrows);
  g_free (killcols);
}
Beispiel #6
0
static gboolean
test_buffer_change_extent (void)
{
  gboolean         result = TRUE;
  gchar           *tmpdir = NULL;
  gchar           *buf_a_path = NULL;
  GeglBuffer      *buf_a = NULL;
  const Babl      *format = babl_format ("R'G'B'A u8");
  GeglRectangle    roi = {0, 0, 128, 128};
  GeglRectangle    roi2 = {0, 0, 64, 64};

  tmpdir = g_dir_make_tmp ("test-backend-file-XXXXXX", NULL);
  g_return_val_if_fail (tmpdir, FALSE);

  buf_a_path = g_build_filename (tmpdir, "buf_a.gegl", NULL);

  buf_a = g_object_new (GEGL_TYPE_BUFFER,
                        "format", format,
                        "path", buf_a_path,
                        "x", roi.x,
                        "y", roi.y,
                        "width", roi.width,
                        "height", roi.height,
                        NULL);

  gegl_buffer_flush (buf_a);
  g_object_unref (buf_a);

  buf_a = g_object_new (GEGL_TYPE_BUFFER,
                        "format", babl_format ("RGBA u16"),
                        "path", buf_a_path,
                        NULL);

  if (!gegl_rectangle_equal (gegl_buffer_get_extent (buf_a), &roi))
    {
      printf ("Extent does not match:\n");
      gegl_rectangle_dump (gegl_buffer_get_extent (buf_a));
      gegl_rectangle_dump (&roi);
      result = FALSE;
    }

  gegl_buffer_set_extent (buf_a, &roi2);

  gegl_buffer_flush (buf_a);
  g_object_unref (buf_a);

  buf_a = g_object_new (GEGL_TYPE_BUFFER,
                        "format", babl_format ("RGBA u16"),
                        "path", buf_a_path,
                        NULL);

  if (!gegl_rectangle_equal (gegl_buffer_get_extent (buf_a), &roi2))
    {
      printf ("Extent does not match:\n");
      gegl_rectangle_dump (gegl_buffer_get_extent (buf_a));
      gegl_rectangle_dump (&roi2);
      result = FALSE;
    }

  g_object_unref (buf_a);

  g_unlink (buf_a_path);
  g_remove (tmpdir);

  g_free (tmpdir);
  g_free (buf_a_path);

  return result;
}
Beispiel #7
0
static gboolean
test_buffer_same_path (void)
{
  gboolean         result = TRUE;
  gchar           *tmpdir = NULL;
  gchar           *buf_a_path = NULL;
  GeglBuffer      *buf_a = NULL;
  const Babl      *format = babl_format ("R'G'B'A u8");
  GeglRectangle    roi = {0, 0, 128, 128};

  tmpdir = g_dir_make_tmp ("test-backend-file-XXXXXX", NULL);
  g_return_val_if_fail (tmpdir, FALSE);

  buf_a_path = g_build_filename (tmpdir, "buf_a.gegl", NULL);

  buf_a = g_object_new (GEGL_TYPE_BUFFER,
                        "format", format,
                        "path", buf_a_path,
                        "x", roi.x,
                        "y", roi.y,
                        "width", roi.width,
                        "height", roi.height,
                        NULL);

  gegl_buffer_flush (buf_a);
  g_object_unref (buf_a);

  buf_a = g_object_new (GEGL_TYPE_BUFFER,
                        /* FIXME: Currently the buffer must always have a format specified */
                        "format", babl_format ("RGBA u16"),
                        "path", buf_a_path,
                        NULL);

  if (!GEGL_IS_BUFFER (buf_a))
    {
      printf ("Failed to load file:%s\n",
              buf_a_path);
      result = FALSE;
    }

  if (!gegl_rectangle_equal (gegl_buffer_get_extent (buf_a), &roi))
    {
      printf ("Extent does not match:\n");
      gegl_rectangle_dump (gegl_buffer_get_extent (buf_a));
      gegl_rectangle_dump (&roi);
      result = FALSE;
    }

  if (gegl_buffer_get_format (buf_a) != format)
    {
      printf ("Formats do not match:\n%s\n%s\n",
        babl_get_name (gegl_buffer_get_format (buf_a)),
        babl_get_name (format));
      result = FALSE;
    }

  g_object_unref (buf_a);

  g_unlink (buf_a_path);
  g_remove (tmpdir);

  g_free (tmpdir);
  g_free (buf_a_path);

  return result;
}
Beispiel #8
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  if (o->buffer)
    {
      GeglBuffer *output = GEGL_BUFFER (o->buffer);
      const Babl *in_format = gegl_buffer_get_format (input);
      const Babl *out_format = gegl_buffer_get_format (output);

      if (gegl_operation_use_opencl (operation)
          && gegl_cl_color_supported (in_format, out_format) == GEGL_CL_COLOR_CONVERT)
        {
          size_t size;
          gboolean err;
          cl_int cl_err = 0;

          GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,
                                                                 result,
                                                                 out_format,
                                                                 GEGL_CL_BUFFER_WRITE);

          gint read = gegl_buffer_cl_iterator_add (i,
                                                   input,
                                                   result,
                                                   out_format,
                                                   GEGL_CL_BUFFER_READ,
                                                   GEGL_ABYSS_NONE);

          gegl_cl_color_babl (out_format, &size);

          GEGL_NOTE (GEGL_DEBUG_OPENCL,
                     "write-buffer: "
                     "%p %p %s %s {%d %d %d %d}",
                     input,
                     output,
                     babl_get_name (in_format),
                     babl_get_name (out_format),
                     result->x,
                     result->y,
                     result->width,
                     result->height);

          while (gegl_buffer_cl_iterator_next (i, &err))
            {
              if (err) break;

              cl_err = gegl_clEnqueueCopyBuffer (gegl_cl_get_command_queue (),
                                                 i->tex[read],
                                                 i->tex[0],
                                                 0,
                                                 0,
                                                 i->size[0] * size,
                                                 0,
                                                 NULL,
                                                 NULL);

              if (cl_err != CL_SUCCESS)
                {
                  GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", gegl_cl_errstring (cl_err));
                  break;
                }
            }

          if (cl_err || err)
            gegl_buffer_copy (input, result, output, result);
        }
      else
        gegl_buffer_copy (input, result, output, result);

      gegl_buffer_flush (output);
    }

  return TRUE;
}