Ejemplo n.º 1
0
static void
tile_request_end(MyPaintTiledSurface *tiled_surface, MyPaintTileRequest *request)
{
    MyPaintGeglTiledSurface *self = (MyPaintGeglTiledSurface *)tiled_surface;

    if (buffer_is_native(self)) {
        GeglBufferIterator *iterator = (GeglBufferIterator *)request->context;

        if (iterator) {
            gegl_buffer_iterator_next(iterator);
            request->context = NULL;
        }
    } else {
        // Push our linear buffer back into the GeglBuffer
        const int tile_size = tiled_surface->tile_size;
        GeglRectangle tile_bbox;

        g_assert(request->buffer);
        gegl_rectangle_set(&tile_bbox, request->tx*tile_size, request->ty*tile_size, tile_size, tile_size);
        gegl_buffer_set(self->buffer, &tile_bbox, 0, self->format,
                        request->buffer, GEGL_AUTO_ROWSTRIDE);
        gegl_free(request->buffer);
    }

}
Ejemplo n.º 2
0
void
gegl_random_cleanup (void)
{
  if (random_data_inited)
    {
      gegl_free (gegl_random_data);
      gegl_random_data = NULL;
      random_data_inited = FALSE;
    }
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
  GeglTile *tile;
  GeglBuffer *buf_a, *buf_b, *buf_small_lin, *buf_big_lin;
  gpointer shared_data = NULL;
  gboolean result = TRUE;
  gpointer scratch_data;
  GeglRectangle buffer_rect = *GEGL_RECTANGLE(0, 0, 128, 128);

  gegl_init (&argc, &argv);

  buf_a = gegl_buffer_new (&buffer_rect, babl_format("RGBA u8"));
  buf_b = gegl_buffer_new (&buffer_rect, babl_format("RGBA u8"));
  buf_small_lin = gegl_buffer_linear_new (&buffer_rect, babl_format("RGBA float"));
  buf_big_lin = gegl_buffer_linear_new (GEGL_RECTANGLE(0, 0, 1024, 1024), babl_format("RGBA float"));

  tile = gegl_tile_source_get_tile (GEGL_TILE_SOURCE (buf_a), 0, 0, 0);
  shared_data = gegl_tile_get_data(tile);
  gegl_tile_unref (tile);

  if (!assert_is_empty (buf_a, 0, 0, shared_data))
    result = FALSE;
  if (!assert_is_empty (buf_b, 0, 1, shared_data))
    result = FALSE;

  if (!assert_is_empty (buf_a, 0, 0, shared_data))
    result = FALSE;
  if (!assert_is_empty (buf_b, 0, 1, shared_data))
    result = FALSE;

  if (!assert_is_empty (buf_small_lin, 0, 0, shared_data))
    result = FALSE;

  if (!assert_is_unshared (buf_big_lin, 0, 0, shared_data))
    result = FALSE;

  scratch_data = gegl_malloc(4 * buffer_rect.width * buffer_rect.height);
  gegl_buffer_get (buf_a, &buffer_rect, 1.0, babl_format("RGBA u8"), scratch_data, 0, GEGL_ABYSS_NONE);
  gegl_buffer_get (buf_b, &buffer_rect, 1.0, babl_format("RGBA u8"), scratch_data, 0, GEGL_ABYSS_NONE);
  gegl_buffer_get (buf_small_lin, &buffer_rect, 1.0, babl_format("RGBA u8"), scratch_data, 0, GEGL_ABYSS_NONE);
  gegl_buffer_get (buf_big_lin, &buffer_rect, 1.0, babl_format("RGBA u8"), scratch_data, 0, GEGL_ABYSS_NONE);
  gegl_free (scratch_data);

  g_object_unref(buf_a);
  g_object_unref(buf_b);
  g_object_unref(buf_small_lin);
  g_object_unref(buf_big_lin);

  gegl_exit();

  if (result)
    return SUCCESS;
  return FAILURE;
}
Ejemplo n.º 4
0
static void
wav_hor_blur (GeglBuffer          *src,
              GeglBuffer          *dst,
              const GeglRectangle *dst_rect,
              gint                 radius,
              const Babl          *format)
{
  gint x, y;

  GeglRectangle write_rect = {dst_rect->x, dst_rect->y, dst_rect->width, 1};

  GeglRectangle read_rect = {dst_rect->x - radius, dst_rect->y,
                             dst_rect->width + 2 * radius, 1};

  gfloat *src_buf = gegl_malloc (read_rect.width * sizeof (gfloat) * 3);
  gfloat *dst_buf = gegl_malloc (write_rect.width * sizeof (gfloat) * 3);

  for (y = 0; y < dst_rect->height; y++)
    {
      gint offset     = 0;
      read_rect.y     = dst_rect->y + y;
      write_rect.y    = dst_rect->y + y;

      gegl_buffer_get (src, &read_rect, 1.0, format, src_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

      for (x = 0; x < dst_rect->width; x++)
        {
          wav_get_mean_pixel_1D (src_buf + offset,
                                 dst_buf + offset,
                                 radius);
          offset += 3;
        }

      gegl_buffer_set (dst, &write_rect, 0, format, dst_buf,
                       GEGL_AUTO_ROWSTRIDE);
    }

  gegl_free (src_buf);
  gegl_free (dst_buf);
}
Ejemplo n.º 5
0
void
gegl_buffer_linear_close (GeglBuffer *buffer,
                          gpointer    linear)
{
  GeglTile *tile;
  tile = g_object_get_data (G_OBJECT (buffer), "linear-tile");
  if (tile)
    {
      gegl_tile_unlock (tile);
      gegl_tile_unref (tile);
      g_object_set_data (G_OBJECT (buffer), "linear-tile", NULL);
    }
  else
    {
      GList *linear_buffers;
      GList *iter;
      linear_buffers = g_object_get_data (G_OBJECT (buffer), "linear-buffers");

      for (iter = linear_buffers; iter; iter=iter->next)
        {
          BufferInfo *info = iter->data;

          if (info->buf == linear)
            {
              info->refs--;

              if (info->refs>0)
                {
                  g_print ("EEeeek! %s\n", G_STRLOC);
                return; /* there are still others holding a reference to
                         * this linear buffer
                         */
                }

              linear_buffers = g_list_remove (linear_buffers, info);
              g_object_set_data (G_OBJECT (buffer), "linear-buffers", linear_buffers);

              g_rec_mutex_unlock (&buffer->tile_storage->mutex);
              /* XXX: potential race */
              gegl_buffer_set (buffer, &info->extent, 0, info->format, info->buf, 0);

              gegl_free (info->buf);
              g_free (info);

              g_rec_mutex_lock (&buffer->tile_storage->mutex);
              break;
            }
        }
    }
  /*gegl_buffer_unlock (buffer);*/
  g_rec_mutex_unlock (&buffer->tile_storage->mutex);
  return;
}
Ejemplo n.º 6
0
static void
release_tile (GeglBufferIterator *iter,
              int index)
{
  GeglBufferIteratorPriv *priv = iter->priv;
  SubIterState           *sub  = &priv->sub_iter[index];

  if (sub->current_tile_mode == GeglIteratorTileMode_DirectTile)
    {
      if (sub->access_mode & GEGL_ACCESS_WRITE)
        gegl_tile_unlock (sub->current_tile);
      gegl_tile_unref (sub->current_tile);

      sub->current_tile = NULL;
      iter->data[index] = NULL;

      sub->current_tile_mode = GeglIteratorTileMode_Empty;
    }
  else if (sub->current_tile_mode == GeglIteratorTileMode_LinearTile)
    {
      sub->current_tile = NULL;
      iter->data[index] = NULL;

      sub->current_tile_mode = GeglIteratorTileMode_Empty;
    }
  else if (sub->current_tile_mode == GeglIteratorTileMode_GetBuffer)
    {
      if (sub->access_mode & GEGL_ACCESS_WRITE)
        {
          gegl_buffer_set_unlocked_no_notify (sub->buffer,
                                              &sub->real_roi,
                                              sub->level,
                                              sub->format,
                                              sub->real_data,
                                              GEGL_AUTO_ROWSTRIDE);
        }

      gegl_free (sub->real_data);
      sub->real_data = NULL;
      iter->data[index] = NULL;

      sub->current_tile_mode = GeglIteratorTileMode_Empty;
    }
  else if (sub->current_tile_mode == GeglIteratorTileMode_Empty)
    {
      return;
    }
  else
    {
      g_warn_if_reached ();
    }
}
Ejemplo n.º 7
0
static void
fir_ver_blur (GeglBuffer          *src,
              const GeglRectangle *rect,
              GeglBuffer          *dst,
              gfloat              *cmatrix,
              gint                 clen,
              GeglAbyssPolicy      policy,
              const Babl          *format)
{
  GeglRectangle  cur_col = *rect;
  GeglRectangle  in_col;
  const gint     nc = babl_format_get_n_components (format);
  gfloat        *col;
  gfloat        *out;
  gint           v;

  cur_col.width = 1;

  in_col         = cur_col;
  in_col.height += clen - 1;
  in_col.y      -= clen / 2;

  col = gegl_malloc (sizeof (gfloat) * in_col.height  * nc);
  out = gegl_malloc (sizeof (gfloat) * cur_col.height * nc);

  for (v = 0; v < rect->width; v++)
    {
      cur_col.x = in_col.x = rect->x + v;

      gegl_buffer_get (src, &in_col, 1.0, format, col, GEGL_AUTO_ROWSTRIDE, policy);

      fir_blur_1D (col, out, cmatrix, clen, rect->height, nc);

      gegl_buffer_set (dst, &cur_col, 0, format, out, GEGL_AUTO_ROWSTRIDE);
    }

  gegl_free (out);
  gegl_free (col);
}
Ejemplo n.º 8
0
static void
fir_hor_blur (GeglBuffer          *src,
              const GeglRectangle *rect,
              GeglBuffer          *dst,
              gfloat              *cmatrix,
              gint                 clen,
              GeglAbyssPolicy      policy,
              const Babl          *format)
{
  GeglRectangle  cur_row = *rect;
  GeglRectangle  in_row;
  const gint     nc = babl_format_get_n_components (format);
  gfloat        *row;
  gfloat        *out;
  gint           v;

  cur_row.height = 1;

  in_row         = cur_row;
  in_row.width  += clen - 1;
  in_row.x      -= clen / 2;

  row = gegl_malloc (sizeof (gfloat) * in_row.width  * nc);
  out = gegl_malloc (sizeof (gfloat) * cur_row.width * nc);

  for (v = 0; v < rect->height; v++)
    {
      cur_row.y = in_row.y = rect->y + v;

      gegl_buffer_get (src, &in_row, 1.0, format, row, GEGL_AUTO_ROWSTRIDE, policy);

      fir_blur_1D (row, out, cmatrix, clen, rect->width, nc);

      gegl_buffer_set (dst, &cur_row, 0, format, out, GEGL_AUTO_ROWSTRIDE);
    }

  gegl_free (out);
  gegl_free (row);
}
Ejemplo n.º 9
0
static gboolean
gegl_gblur_1d_process (GeglOperation       *operation,
                       GeglBuffer          *input,
                       GeglBuffer          *output,
                       const GeglRectangle *result,
                       gint                 level)
{
  GeglProperties *o      = GEGL_PROPERTIES (operation);
  const Babl *format = gegl_operation_get_format (operation, "output");

  GeglGblur1dFilter filter;
  GeglAbyssPolicy   abyss_policy = to_gegl_policy (o->abyss_policy);

  filter = filter_disambiguation (o->filter, o->std_dev);

  if (filter == GEGL_GBLUR_1D_IIR)
    {
      gdouble b[4], m[3][3];

      iir_young_find_constants (o->std_dev, b, m);

      if (o->orientation == GEGL_ORIENTATION_HORIZONTAL)
        iir_young_hor_blur (input, result, output, b, m, abyss_policy, format);
      else
        iir_young_ver_blur (input, result, output, b, m, abyss_policy, format);
    }
  else
    {
      gfloat *cmatrix;
      gint    clen;

      clen = fir_gen_convolve_matrix (o->std_dev, &cmatrix);

      /* FIXME: implement others format cases */
      if (gegl_operation_use_opencl (operation) &&
          format == babl_format ("RaGaBaA float"))
        if (fir_cl_process(input, output, result, format,
                           cmatrix, clen, o->orientation, abyss_policy))
          return TRUE;

      if (o->orientation == GEGL_ORIENTATION_HORIZONTAL)
        fir_hor_blur (input, result, output, cmatrix, clen, abyss_policy, format);
      else
        fir_ver_blur (input, result, output, cmatrix, clen, abyss_policy, format);

      gegl_free (cmatrix);
    }

  return  TRUE;
}
Ejemplo n.º 10
0
void gegl_tile_unref (GeglTile *tile)
{
  if (!g_atomic_int_dec_and_test (&tile->ref_count))
    return;

  /* In the case of a file store for example, we must make sure that
   * the in-memory tile is written to disk before we free the memory,
   * otherwise this data will be lost.
   */
  if (!gegl_tile_is_stored (tile))
    gegl_tile_store (tile);

  if (tile->data)
    {
      if (tile->next_shared == tile)
        { /* no clones */
          if (tile->destroy_notify)
            {
              if (tile->destroy_notify == (void*)&free_data_directly)
                gegl_free (tile->data);
              else
                tile->destroy_notify (tile->destroy_notify_data);
            }
          tile->data = NULL;
        }
      else
        {
          tile->prev_shared->next_shared = tile->next_shared;
          tile->next_shared->prev_shared = tile->prev_shared;
        }
    }

#ifdef GEGL_USE_TILE_MUTEX
  if (tile->mutex)
    {
      g_mutex_free (tile->mutex);
      tile->mutex = NULL;
    }
#endif
  g_slice_free (GeglTile, tile);
}
Ejemplo n.º 11
0
static gboolean
test_scale (const gdouble scale, const gint x, const gint y, const Babl *format)
{
  GeglNode *checkerboard;
  GeglBuffer *tmp_buffer;
  gboolean result = FALSE;

  const gint bpp = babl_format_get_bytes_per_pixel (format);
  const gint scaled_width  = 32;
  const gint scaled_height = 32;
  gint pad = 32;

  guchar *output_buffer_scaled = gegl_malloc (scaled_width * scaled_height * bpp);
  guchar *output_node_scaled   = gegl_malloc (scaled_width * scaled_height * bpp);

  if (2 / scale > pad)
    pad = 2 / scale + 2;

  tmp_buffer = gegl_buffer_new (GEGL_RECTANGLE ((x / scale) - pad,
                                                (y / scale) - pad,
                                                (scaled_width / scale) + (2 * pad),
                                                (scaled_height / scale) + (2 * pad)),
                                babl_format ("RGBA float"));

  checkerboard = gegl_node_new_child(NULL,
                                     "operation", "gegl:checkerboard",
                                     "x", 16,
                                     "y", 16,
                                     NULL);

  gegl_node_blit_buffer (checkerboard,
                         tmp_buffer,
                         NULL,
                         0,
                         GEGL_ABYSS_NONE);

  gegl_buffer_get (tmp_buffer,
                   GEGL_RECTANGLE (x, y, scaled_width, scaled_height),
                   scale,
                   format,
                   output_buffer_scaled,
                   GEGL_AUTO_ROWSTRIDE,
                   GEGL_ABYSS_NONE);

  g_object_unref (checkerboard);
  g_object_unref (tmp_buffer);

  /* Re-create the node so we don't hit its cache */
  checkerboard = gegl_node_new_child(NULL,
                                     "operation", "gegl:checkerboard",
                                     "x", 16,
                                     "y", 16,
                                     NULL);

  gegl_node_blit (checkerboard,
                  scale,
                  GEGL_RECTANGLE (x, y, scaled_width, scaled_height),
                  format,
                  output_node_scaled,
                  GEGL_AUTO_ROWSTRIDE,
                  0);

  g_object_unref (checkerboard);

  if (0 == memcmp (output_buffer_scaled, output_node_scaled, scaled_width * scaled_height * bpp))
    {
      printf (".");
      fflush(stdout);
      result = TRUE;
    }
  else
    {
      printf ("\n scale=%.4f at %d, %d in \"%s\" ... FAIL\n", scale, x, y, babl_get_name (format));
      result = FALSE;
    }

  gegl_free (output_buffer_scaled);
  gegl_free (output_node_scaled);

  return result;
}
Ejemplo n.º 12
0
/**
 * Process the gegl filter
 * @param operation the given Gegl operation
 * @param input the input buffer.
 * @param output the output buffer.
 * @param result the region of interest.
 * @param level the level of detail
 * @return True, if the filter was successfull applied.
 */
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties         *o = GEGL_PROPERTIES (operation);
  const Babl  *input_format = gegl_buffer_get_format (input);
  const int bytes_per_pixel = babl_format_get_bytes_per_pixel (input_format);

  /**
   * src_buf, dst_buf:
   * Input- and output-buffers, containing the whole selection,
   * the filter should be applied on.
   *
   * src_pixel, dst_pixel:
   * pointers to the current source- and destination-pixel.
   * Using these pointers, the reading and writing can be delayed till the
   * end of the loop. Hence src_pixel can also point to background_color if
   * necessary.
   */
  guint8    *src_buf, *dst_buf, *src_pixel, *dst_pixel, background_color[bytes_per_pixel];

  /**
   * (x, y): Position of the pixel we compute at the moment.
   * (width, height): Dimensions of the lens
   * pixel_offset: For calculating the pixels position in src_buf / dst_buf.
   */
  gint         x, y,
               width, height,
               pixel_offset, projected_pixel_offset;

  /**
   * Further parameters that are needed to calculate the position of a projected
   * further pixel at (x, y).
   */
  gfloat       a, b, c,
               asqr, bsqr, csqr,
               dx, dy, dysqr,
               projected_x, projected_y,
               refraction_index;

  gboolean     keep_surroundings;

  width = result->width;
  height = result->height;

  refraction_index = o->refraction_index;
  keep_surroundings = o->keep_surroundings;
  gegl_color_get_pixel (o->background_color, input_format, background_color);

  a = 0.5 * width;
  b = 0.5 * height;
  c = MIN (a, b);
  asqr = a * a;
  bsqr = b * b;
  csqr = c * c;

  /**
   * Todo: We might want to change the buffers sizes, as the memory consumption
   * could be rather large.However, due to the lens, it might happen, that one pixel from the
   * images center gets stretched to the whole image, so we will still need
   * at least a src_buf of size (width/2) * (height/2) * 4 to be able to
   * process one quarter of the image.
   */
  src_buf = gegl_malloc (width * height * bytes_per_pixel);
  dst_buf = gegl_malloc (width * height * bytes_per_pixel);

  gegl_buffer_get (input, result, 1.0, input_format, src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  for (y = 0; y < height; y++)
    {
      /* dy is the current pixels distance (in y-direction) of the lenses center */
      dy = -((gfloat)y - b + 0.5);

      /**
       * To determine, whether the pixel is within the elliptical region affected
       * by the lens, we furthermore need the squared distance. So we calculate it
       * once for each row.
       */
      dysqr = dy * dy;
      for (x = 0; x < width; x++)
        {
          /* Again we need to calculate the pixels distance from the lens dx. */
          dx = (gfloat)x - a + 0.5;

          /* Given x and y we can now determine the pixels offset in our buffer. */
          pixel_offset = (x + y * width) * bytes_per_pixel;

          /* As described above, we only read and write image data once. */
          dst_pixel = &dst_buf[pixel_offset];

          if (dysqr < (bsqr - (bsqr * dx * dx) / asqr))
            {
              /**
               * If (x, y) is inside the affected region, we can find its projected
               * position, calculate the projected_pixel_offset and set the src_pixel
               * to where we want to copy the pixel-data from.
               */
              find_projected_pos (asqr, bsqr, csqr, dx, dy, refraction_index,
                                  &projected_x, &projected_y);

              projected_pixel_offset = ( (gint)(-projected_y + b) * width +
                                         (gint)( projected_x + a) ) * bytes_per_pixel;

              src_pixel = &src_buf[projected_pixel_offset];
            }
          else
            {
              /**
               * Otherwise (that is for pixels outside the lens), we could either leave
               * the image data unchanged, or set it to a specified 'background_color',
               * depending on the user input.
               */
              if (keep_surroundings)
                src_pixel = &src_buf[pixel_offset];
              else
                src_pixel = background_color;
            }

          /**
           * At the end, we can copy the src_pixel (which was determined above), to
           * dst_pixel.
           */
          memcpy (dst_pixel, src_pixel, bytes_per_pixel);
        }
  }

  gegl_buffer_set (output, result, 0, gegl_buffer_get_format (output), dst_buf,
                   GEGL_AUTO_ROWSTRIDE);

  gegl_free (dst_buf);
  gegl_free (src_buf);

  return TRUE;
}
Ejemplo n.º 13
0
static gboolean
test_operation (const char *operation_name)
{
  gboolean result = FALSE;

  const Babl *format = babl_format ("RGBA u8");
  const gint bpp = babl_format_get_bytes_per_pixel (format);
  const gint out_width = 5 + 10;
  const gint out_height = 5 + 10;

  guchar *output_with_abyss = gegl_malloc (out_width * out_height * bpp);
  guchar *output_no_abyss   = gegl_malloc (out_width * out_height * bpp);

  GeglColor *upper_color = gegl_color_new ("rgb(0.2, 0.8, 0.2)");
  GeglColor *lower_color = gegl_color_new ("rgb(0.0, 0.0, 0.0)");
  GeglColor *transparent = gegl_color_new ("rgba(0.0, 0.0, 0.0, 0.0)");

  {
    /* Using abyss */
    GeglNode *ptn = gegl_node_new();

    GeglNode *test_op, *upper_rect, *lower_rect;

    test_op = gegl_node_new_child (ptn,
                                   "operation", operation_name,
                                   NULL);

    upper_rect = gegl_node_new_child (ptn,
                                   "operation", "gegl:rectangle",
                                   "color", upper_color,
                                   "x", 5.0,
                                   "y", 5.0,
                                   "width", 10.0,
                                   "height", 10.0,
                                   NULL);

    lower_rect = gegl_node_new_child (ptn,
                                   "operation", "gegl:rectangle",
                                   "color", lower_color,
                                   "x", 0.0,
                                   "y", 0.0,
                                   "width", 10.0,
                                   "height", 10.0,
                                   NULL);

    gegl_node_connect_to (lower_rect, "output", test_op, "input");
    gegl_node_connect_to (upper_rect, "output", test_op, "aux");

    {
      int i;
      guchar *out = output_with_abyss;
      for (i = 0; i < out_height; i++)
        {
          gegl_node_blit (test_op,
                          1.0,
                          GEGL_RECTANGLE (0, i, out_width, 1),
                          format,
                          out,
                          GEGL_AUTO_ROWSTRIDE,
                          0);
          out += out_width * bpp;
        }
    }

    g_object_unref (ptn);
  }

  {
    /* Explicit transparency */
    GeglNode *ptn = gegl_node_new();

    GeglNode *test_op, *upper_rect, *lower_rect;
    GeglNode *upper_over, *lower_over;
    GeglNode *background;

    test_op = gegl_node_new_child (ptn,
                                   "operation", operation_name,
                                   NULL);

    background = gegl_node_new_child (ptn,
                                   "operation", "gegl:rectangle",
                                   "color", transparent,
                                   "x", 0.0,
                                   "y", 0.0,
                                   "width", 10.0 + 5.0,
                                   "height", 10.0 + 5.0,
                                   NULL);

    upper_rect = gegl_node_new_child (ptn,
                                   "operation", "gegl:rectangle",
                                   "color", upper_color,
                                   "x", 5.0,
                                   "y", 5.0,
                                   "width", 10.0,
                                   "height", 10.0,
                                   NULL);

    upper_over = gegl_node_new_child (ptn,
                                   "operation", "gegl:over",
                                   NULL);

    lower_rect = gegl_node_new_child (ptn,
                                   "operation", "gegl:rectangle",
                                   "color", lower_color,
                                   "x", 0.0,
                                   "y", 0.0,
                                   "width", 10.0,
                                   "height", 10.0,
                                   NULL);

    lower_over = gegl_node_new_child (ptn,
                                   "operation", "gegl:over",
                                   NULL);

    gegl_node_connect_to (lower_rect, "output", lower_over, "aux");
    gegl_node_connect_to (upper_rect, "output", upper_over, "aux");

    gegl_node_connect_to (background, "output", lower_over, "input");
    gegl_node_connect_to (background, "output", upper_over, "input");

    gegl_node_connect_to (lower_over, "output", test_op, "input");
    gegl_node_connect_to (upper_over, "output", test_op, "aux");

    {
      int i;
      guchar *out = output_no_abyss;
      for (i = 0; i < out_height; i++)
        {
          gegl_node_blit (test_op,
                          1.0,
                          GEGL_RECTANGLE (0, i, out_width, 1),
                          format,
                          out,
                          GEGL_AUTO_ROWSTRIDE,
                          0);
          out += out_width * bpp;
        }
    }

    g_object_unref (ptn);
  }

  if (0 == memcmp (output_with_abyss, output_no_abyss, out_width * out_height * bpp))
    {
      printf (".");
      fflush(stdout);
      result = TRUE;
    }
  else
    {
      printf ("\n %s ... FAIL\n", operation_name);
      result = FALSE;
    }

  if (!result)
    {
      GeglBuffer *linear;
      gchar *filename;

      filename = g_strconcat (operation_name, " - with abyss.png", NULL);
      linear = gegl_buffer_linear_new_from_data (output_with_abyss,
                                                format,
                                                GEGL_RECTANGLE (0, 0, out_width, out_height),
                                                GEGL_AUTO_ROWSTRIDE,
                                                NULL,
                                                NULL);
      dump_to_png (filename, linear);
      g_free (filename);
      g_object_unref (linear);

      filename = g_strconcat (operation_name, " - no abyss.png", NULL);
      linear = gegl_buffer_linear_new_from_data (output_no_abyss,
                                                 format,
                                                 GEGL_RECTANGLE (0, 0, out_width, out_height),
                                                 GEGL_AUTO_ROWSTRIDE,
                                                 NULL,
                                                 NULL);
      dump_to_png (filename, linear);
      g_free (filename);
      g_object_unref (linear);
    }

  gegl_free (output_with_abyss);
  gegl_free (output_no_abyss);

  return result;
}
Ejemplo n.º 14
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);

  gfloat *src_buf;
  gfloat *dst_buf;

  gint n_pixels = result->width * result->height;
  GeglRectangle src_rect;

  gfloat *current_pix;
  gfloat *target_pix;
  gfloat *dst_pix;

  gint x, y;
  gint total_src_pixels;
  gint total_dst_pixels;

  gint bleed_max;
  gint bleed_index;
  gfloat blend_coefficient;

  GHashTable *bleed_table;

  static GMutex mutex = { 0, };

  g_mutex_lock (&mutex);
  if (!o->chant_data)
    {
      o->chant_data = g_hash_table_new_full (tuple_hash, tuple_equal, g_free, g_free);
      calculate_bleed (operation, input);
    }
  g_mutex_unlock (&mutex);

  bleed_table = (GHashTable*) o->chant_data;

  src_rect.x      = result->x - op_area->left;
  src_rect.width  = result->width + op_area->left + op_area->right;
  src_rect.y      = result->y - op_area->top;
  src_rect.height = result->height + op_area->top + op_area->bottom;

  total_src_pixels = src_rect.width * src_rect.height;
  total_dst_pixels = result->width * result->height;

  src_buf = gegl_malloc (4 * total_src_pixels * sizeof (gfloat));
  dst_buf = gegl_malloc (4 * total_dst_pixels * sizeof (gfloat));

  gegl_buffer_get (input,
                   &src_rect,
                   1.0,
                   babl_format ("RGBA float"),
                   src_buf,
                   GEGL_AUTO_ROWSTRIDE,
                   GEGL_ABYSS_NONE);

  current_pix = src_buf + 4*(o->strength + src_rect.width * o->strength);
  dst_pix = dst_buf;
  x = 0;
  y = 0;
  n_pixels = result->width * result->height;
  bleed_max = 0;
  bleed_index = 0;
  while (n_pixels--)
    {
      gint i;
      pair key = {x + result->x, y + result->y};
      gint *bleed = g_hash_table_lookup (bleed_table, &key);

      if (x == 0) {
        for (i = 0; i < o->strength; i++)
          {
            pair key = {result->x - i, y + result->y};
            gint *bleed = g_hash_table_lookup (bleed_table, &key);
            if (bleed) {
              bleed_max = *bleed;
              bleed_index = *bleed - i;
              break;
            }
          }
      }

      for (i = 0; i < 4; i++)
        dst_pix[i] = current_pix[i];

      if (bleed)
        {
          gfloat blend_color[4];
          gfloat blend_amount[4];
          gfloat *blend_pix;

          bleed_max = *bleed;
          bleed_index = *bleed;
          target_pix = current_pix;
          blend_pix = current_pix - 12;
          for (i = 0; i < 4; i++)
            {
              blend_amount[i] = target_pix[i] - blend_pix[i];
              blend_color[i] = blend_pix[i] + blend_amount[i];
              dst_pix[i] = (2.0 * blend_color[i] + dst_pix[i])/3.0;
            }
        }
      else if (bleed_index > 0)
        {
          gfloat blend_color[4];
          gfloat blend_amount[4];
          gfloat *blend_pix;
          bleed_index--;
          blend_coefficient = 1.0 - ((gfloat) bleed_index)/(gfloat) bleed_max;
          blend_pix = current_pix - 4 * (bleed_max - bleed_index) - 12;
          target_pix = current_pix;
          for (i = 0; i < 4; i++)
            {
              blend_amount[i] = target_pix[i] - blend_pix[i];
              blend_color[i] = blend_pix[i] + blend_amount[i] * blend_coefficient;
              dst_pix[i] = (2.0 * blend_color[i] + dst_pix[i])/3.0;
            }
        }

      x++;
      current_pix += 4;
      dst_pix += 4;
      if (x >= result->width)
        {
          bleed_max = 0;
          bleed_index = 0;
          x = 0;
          y++;
          current_pix += 8 * o->strength;
        }
    }
  gegl_buffer_set (output,
                   result,
                   1,
                   babl_format ("RGBA float"),
                   dst_buf,
                   GEGL_AUTO_ROWSTRIDE);

  gegl_free (src_buf);
  gegl_free (dst_buf);

  return TRUE;
}
Ejemplo n.º 15
0
/**
 * Process the gegl filter
 * @param operation the given Gegl operation
 * @param input the input buffer.
 * @param output the output buffer.
 * @param result the region of interest.
 * @param level the level of detail
 * @return True, if the filter was successfull applied.
 */
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties         *o = GEGL_PROPERTIES (operation);
  const Babl  *input_format = babl_format ("Y float");
  const int bytes_per_pixel = babl_format_get_bytes_per_pixel (input_format);

  GeglDTMetric metric;
  gint     width, height, averaging, i;
  gfloat   threshold_lo, threshold_hi, maxval, *src_buf, *dst_buf;
  gboolean normalize;

  width  = result->width;
  height = result->height;

  threshold_lo = o->threshold_lo;
  threshold_hi = o->threshold_hi;
  normalize    = o->normalize;
  metric       = o->metric;
  averaging    = o->averaging;

  src_buf = gegl_malloc (width * height * bytes_per_pixel);
  dst_buf = gegl_calloc (width * height, bytes_per_pixel);

  gegl_operation_progress (operation, 0.0, "");

  gegl_buffer_get (input, result, 1.0, input_format, src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  if (!averaging)
    {
      binary_dt_1st_pass (operation, width, height, threshold_lo,
                          src_buf, dst_buf);
      binary_dt_2nd_pass (operation, width, height, threshold_lo, metric,
                          src_buf, dst_buf);
    }
  else
    {
      gfloat *tmp_buf;
      gint i, j;

      tmp_buf = gegl_malloc (width * height * bytes_per_pixel);

      for (i = 0; i < averaging; i++)
        {
          gfloat thres;

          thres = (i+1) * (threshold_hi - threshold_lo) / (averaging + 1);
          thres += threshold_lo;

          binary_dt_1st_pass (operation, width, height, thres,
                              src_buf, tmp_buf);
          binary_dt_2nd_pass (operation, width, height, thres, metric,
                              src_buf, tmp_buf);

          for (j = 0; j < width * height; j++)
            dst_buf[j] += tmp_buf[j];
        }

      gegl_free (tmp_buf);
    }

  if (normalize)
    {
      maxval = EPSILON;

      for (i = 0; i < width * height; i++)
        maxval = MAX (dst_buf[i], maxval);
    }
  else
    {
      maxval = averaging;
    }

  if (averaging > 0 || normalize)
    {
      for (i = 0; i < width * height; i++)
        dst_buf[i] = dst_buf[i] * threshold_hi / maxval;
    }

  gegl_buffer_set (output, result, 0, input_format, dst_buf,
                   GEGL_AUTO_ROWSTRIDE);

  gegl_operation_progress (operation, 1.0, "");

  gegl_free (dst_buf);
  gegl_free (src_buf);

  return TRUE;
}
Ejemplo n.º 16
0
static void
binary_dt_2nd_pass (GeglOperation *operation,
                    gint           width,
                    gint           height,
                    gfloat         thres_lo,
                    GeglDTMetric   metric,
                    gfloat        *src,
                    gfloat        *dest)
{
  gint u, y;
  gint q, w, *t, *s;
  gfloat *g, *row_copy;

  gfloat (*dt_f)   (gfloat, gfloat, gfloat);
  gint   (*dt_sep) (gint, gint, gfloat, gfloat);

  switch (metric)
    {
      case GEGL_DT_METRIC_CHESSBOARD:
        dt_f   = cdt_f;
        dt_sep = cdt_sep;
        break;
      case GEGL_DT_METRIC_MANHATTAN:
        dt_f   = mdt_f;
        dt_sep = mdt_sep;
        break;
      default: /* GEGL_DT_METRIC_EUCLIDEAN */
        dt_f   = edt_f;
        dt_sep = edt_sep;
        break;
    }

  /* sorry for the variable naming, they are taken from the paper */

  s = gegl_calloc (sizeof (gint), width);
  t = gegl_calloc (sizeof (gint), width);
  row_copy = gegl_calloc (sizeof (gfloat), width);

  /* this could be parallelized */
  for (y = 0; y < height; y++)
    {
      q = 0;
      s[0] = 0;
      t[0] = 0;
      g = dest + y * width;

      dest[0 + y * width] = MIN (dest[0 + y * width], 1.0);
      dest[width - 1 + y * width] = MIN (dest[width - 1 + y * width], 1.0);

      for (u = 1; u < width; u++)
        {
          while (q >= 0 &&
                 dt_f (t[q], s[q], g[s[q]]) >= dt_f (t[q], u, g[u]) + EPSILON)
            {
              q --;
            }

          if (q < 0)
            {
              q = 0;
              s[0] = u;
            }
          else
            {
              /* function Sep from paper */
              w = dt_sep (s[q], u, g[s[q]], g[u]);
              w += 1;

              if (w < width)
                {
                  q ++;
                  s[q] = u;
                  t[q] = w;
                }
            }
        }

      memcpy (row_copy, g, width * sizeof (gfloat));

      for (u = width - 1; u >= 0; u--)
        {
          if (u == s[q])
            g[u] = row_copy[u];
          else
            g[u] = dt_f (u, s[q], row_copy[s[q]]);

          if (q > 0 && u == t[q])
            {
              q--;
            }
        }

      gegl_operation_progress (operation,
                               (gdouble) y / (gdouble) height / 2.0 + 0.5, "");
    }

  gegl_free (t);
  gegl_free (s);
  gegl_free (row_copy);
}