GeglBuffer *
gegl_graph_get_shared_empty (GeglGraphTraversal *path)
{
  if (!path->shared_empty)
    {
      path->shared_empty = gegl_buffer_new_ram (GEGL_RECTANGLE (0, 0, 0, 0),
                                                gegl_babl_rgba_linear_float ());
      gegl_object_set_has_forked (G_OBJECT (path->shared_empty));
    }
  return path->shared_empty;
}
Esempio n. 2
0
static void prepare (GeglOperation *operation)
{
  const Babl *format = gegl_babl_rgba_linear_float ();
  gegl_operation_set_format (operation, "input", format);
  gegl_operation_set_format (operation, "output", format);
}
Esempio n. 3
0
GeglBuffer *
gegl_operation_context_get_target (GeglOperationContext *context,
                                   const gchar          *padname)
{
  GeglBuffer          *output;
  const GeglRectangle *result;
  const Babl          *format;
  GeglNode            *node;
  GeglOperation       *operation;
  static gint          linear_buffers = -1;

#if 0
  g_return_val_if_fail (GEGL_IS_OPERATION_CONTEXT (context), NULL);
#endif

  if (linear_buffers == -1)
    linear_buffers = g_getenv ("GEGL_LINEAR_BUFFERS")?1:0;

  operation = context->operation;
  node = operation->node; /* <ick */
  format = gegl_operation_get_format (operation, padname);

  if (format == NULL)
    {
      g_warning ("no format for %s presuming RGBA float\n",
                 gegl_node_get_debug_name (node));
      format = gegl_babl_rgba_linear_float ();
    }
  g_assert (format != NULL);
  g_assert (!strcmp (padname, "output"));

  result = &context->result_rect;

  if (result->width == 0 ||
      result->height == 0)
    {
      if (linear_buffers)
        output = gegl_buffer_linear_new (GEGL_RECTANGLE(0, 0, 0, 0), format);
      else
        output = gegl_buffer_new (GEGL_RECTANGLE (0, 0, 0, 0), format);
    }
  else if (node->dont_cache == FALSE &&
      ! GEGL_OPERATION_CLASS (G_OBJECT_GET_CLASS (operation))->no_cache)
    {
      GeglBuffer    *cache;
      cache = GEGL_BUFFER (gegl_node_get_cache (node));

      /* Only use the cache if the result is within the cache
       * extent. This is certainly not optimal. My gut feeling is that
       * the current caching mechanism needs to be redesigned
       */
      if (gegl_rectangle_contains (gegl_buffer_get_extent (cache), result))
        {
          output = g_object_ref (cache);
        }
      else
        {
          if (linear_buffers)
            output = gegl_buffer_linear_new (result, format);
          else
            output = gegl_buffer_new (result, format);
        }
    }
  else
    {
      if (linear_buffers)
        output = gegl_buffer_linear_new (result, format);
      else
        output = gegl_buffer_new (result, format);
    }

  gegl_operation_context_take_object (context, padname, G_OBJECT (output));

  return output;
}
Esempio n. 4
0
static void inline
gegl_sampler_get_pixel (GeglSampler    *sampler,
                        gint            x,
                        gint            y,
                        gpointer        data,
                        GeglAbyssPolicy repeat_mode)
{
  GeglSamplerNearest *nearest_sampler = (GeglSamplerNearest*)(sampler);
  GeglBuffer *buffer = sampler->buffer;
  const GeglRectangle *abyss = &buffer->abyss;
  guchar              *buf   = data;

  if (y <  abyss->y ||
      x <  abyss->x ||
      y >= abyss->y + abyss->height ||
      x >= abyss->x + abyss->width)
    {
      switch (repeat_mode)
      {
        case GEGL_ABYSS_CLAMP:
          x = CLAMP (x, abyss->x, abyss->x+abyss->width-1);
          y = CLAMP (y, abyss->y, abyss->y+abyss->height-1);
          break;

        case GEGL_ABYSS_LOOP:
          x = abyss->x + GEGL_REMAINDER (x - abyss->x, abyss->width);
          y = abyss->y + GEGL_REMAINDER (y - abyss->y, abyss->height);
          break;

        case GEGL_ABYSS_BLACK:
          {
            gfloat color[4] = {0.0, 0.0, 0.0, 1.0};
            babl_process (babl_fish (gegl_babl_rgba_linear_float (), sampler->format),
                          color,
                          buf,
                          1);
            return;
          }

        case GEGL_ABYSS_WHITE:
          {
            gfloat color[4] = {1.0, 1.0, 1.0, 1.0};
            babl_process (babl_fish (gegl_babl_rgba_linear_float (),
                                     sampler->format),
                          color,
                          buf,
                          1);
            return;
          }

        default:
        case GEGL_ABYSS_NONE:
          memset (buf, 0x00, babl_format_get_bytes_per_pixel (sampler->format));
          return;
      }
    }

  gegl_buffer_lock (sampler->buffer);

  {
    gint tile_width  = buffer->tile_width;
    gint tile_height = buffer->tile_height;
    gint tiledy      = y + buffer->shift_y;
    gint tiledx      = x + buffer->shift_x;
    gint indice_x    = gegl_tile_indice (tiledx, tile_width);
    gint indice_y    = gegl_tile_indice (tiledy, tile_height);

    GeglTile *tile = nearest_sampler->hot_tile;

    if (!(tile &&
          tile->x == indice_x &&
          tile->y == indice_y))
      {
        if (gegl_config_threads()>1)
          g_rec_mutex_lock (&buffer->tile_storage->mutex);

        if (tile)
          gegl_tile_unref (tile);

        tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
                                          indice_x, indice_y,
                                          0);
        nearest_sampler->hot_tile = tile;

        if (gegl_config_threads()>1)
          g_rec_mutex_unlock (&buffer->tile_storage->mutex);
      }

    if (tile)
      {
        gint tile_origin_x = indice_x * tile_width;
        gint tile_origin_y = indice_y * tile_height;
        gint       offsetx = tiledx - tile_origin_x;
        gint       offsety = tiledy - tile_origin_y;

        guchar *tp = gegl_tile_get_data (tile) + (offsety * tile_width + offsetx) * nearest_sampler->buffer_bpp;

        babl_process (sampler->fish, tp, buf, 1);
      }
  }

  gegl_buffer_unlock (sampler->buffer);
}