Blame operations/common/map-absolute.c

Packit bc1512
/* This file is an image processing operation for GEGL
Packit bc1512
 *
Packit bc1512
 * GEGL is free software; you can redistribute it and/or
Packit bc1512
 * modify it under the terms of the GNU Lesser General Public
Packit bc1512
 * License as published by the Free Software Foundation; either
Packit bc1512
 * version 3 of the License, or (at your option) any later version.
Packit bc1512
 *
Packit bc1512
 * GEGL is distributed in the hope that it will be useful,
Packit bc1512
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bc1512
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit bc1512
 * Lesser General Public License for more details.
Packit bc1512
 *
Packit bc1512
 * You should have received a copy of the GNU Lesser General Public
Packit bc1512
 * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
Packit bc1512
 *
Packit bc1512
 * Copyright 2010 Michael Muré <batolettre@gmail.com>
Packit bc1512
 *
Packit bc1512
 */
Packit bc1512
Packit bc1512
#ifdef GEGL_CHANT_PROPERTIES
Packit bc1512
Packit bc1512
gegl_chant_enum (sampler_type, _("Sampler"), GeglSamplerType, GEGL_TYPE_SAMPLER_TYPE,
Packit bc1512
                 GEGL_SAMPLER_CUBIC, _("Sampler used internaly"))
Packit bc1512
Packit bc1512
#else
Packit bc1512
Packit bc1512
#define GEGL_CHANT_TYPE_COMPOSER
Packit bc1512
#define GEGL_CHANT_C_FILE       "map-absolute.c"
Packit bc1512
Packit bc1512
#include "config.h"
Packit bc1512
#include <glib/gi18n-lib.h>
Packit bc1512
#include "gegl-chant.h"
Packit bc1512
Packit bc1512
Packit bc1512
static void
Packit bc1512
prepare (GeglOperation *operation)
Packit bc1512
{
Packit bc1512
  const Babl *format = babl_format ("RGBA float");
Packit bc1512
Packit bc1512
  gegl_operation_set_format (operation, "input", format);
Packit bc1512
  gegl_operation_set_format (operation, "aux", babl_format_n (babl_type ("float"), 2));
Packit bc1512
  gegl_operation_set_format (operation, "output", format);
Packit bc1512
}
Packit bc1512
Packit bc1512
static GeglRectangle
Packit bc1512
get_required_for_output (GeglOperation       *operation,
Packit bc1512
                         const gchar         *input_pad,
Packit bc1512
                         const GeglRectangle *region)
Packit bc1512
{
Packit bc1512
  GeglRectangle result = *gegl_operation_source_get_bounding_box (operation, "input");
Packit bc1512
Packit bc1512
  return result;
Packit bc1512
}
Packit bc1512
Packit bc1512
static gboolean
Packit bc1512
process (GeglOperation       *operation,
Packit bc1512
         GeglBuffer          *input,
Packit bc1512
         GeglBuffer          *aux,
Packit bc1512
         GeglBuffer          *output,
Packit bc1512
         const GeglRectangle *result,
Packit bc1512
         gint                 level)
Packit bc1512
{
Packit bc1512
  GeglChantO           *o = GEGL_CHANT_PROPERTIES (operation);
Packit bc1512
  const Babl           *format_io, *format_coords;
Packit bc1512
  GeglSampler          *sampler;
Packit bc1512
  GeglBufferIterator   *it;
Packit bc1512
  gint                  index_in, index_out, index_coords;
Packit bc1512
Packit bc1512
  format_io = babl_format ("RGBA float");
Packit bc1512
  format_coords = babl_format_n (babl_type ("float"), 2);
Packit bc1512
Packit bc1512
  sampler = gegl_buffer_sampler_new (input, format_io, o->sampler_type);
Packit bc1512
Packit bc1512
  if (aux != NULL)
Packit bc1512
    {
Packit bc1512
      it = gegl_buffer_iterator_new (output, result, level, format_io, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
Packit bc1512
      index_out = 0;
Packit bc1512
Packit bc1512
      index_coords = gegl_buffer_iterator_add (it, aux, result, level, format_coords, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
Packit bc1512
      index_in = gegl_buffer_iterator_add (it, input, result, level, format_io, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
Packit bc1512
Packit bc1512
      while (gegl_buffer_iterator_next (it))
Packit bc1512
        {
Packit bc1512
          gint        i;
Packit bc1512
          gint        n_pixels = it->length;
Packit bc1512
          gint        x = it->roi->x; /* initial x                   */
Packit bc1512
          gint        y = it->roi->y; /*           and y coordinates */
Packit bc1512
          gfloat     *in = it->data[index_in];
Packit bc1512
          gfloat     *out = it->data[index_out];
Packit bc1512
          gfloat     *coords = it->data[index_coords];
Packit bc1512
Packit bc1512
          for (i=0; i
Packit bc1512
            {
Packit bc1512
              /* if the coordinate asked is an exact pixel, we fetch it directly, to avoid the blur of sampling */
Packit bc1512
              if (coords[0] == x && coords[1] == y)
Packit bc1512
                {
Packit bc1512
                  out[0] = in[0];
Packit bc1512
                  out[1] = in[1];
Packit bc1512
                  out[2] = in[2];
Packit bc1512
                  out[3] = in[3];
Packit bc1512
                }
Packit bc1512
              else
Packit bc1512
                {
Packit bc1512
                  gegl_sampler_get (sampler, coords[0], coords[1], NULL, out);
Packit bc1512
                }
Packit bc1512
Packit bc1512
              coords += 2;
Packit bc1512
              in += 4;
Packit bc1512
              out += 4;
Packit bc1512
Packit bc1512
              /* update x and y coordinates */
Packit bc1512
              x++;
Packit bc1512
              if (x >= (it->roi->x + it->roi->width))
Packit bc1512
                {
Packit bc1512
                  x = it->roi->x;
Packit bc1512
                  y++;
Packit bc1512
                }
Packit bc1512
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
  else
Packit bc1512
    {
Packit bc1512
      gegl_buffer_copy (input, result, output, result);
Packit bc1512
    }
Packit bc1512
Packit bc1512
  g_object_unref (sampler);
Packit bc1512
Packit bc1512
  return TRUE;
Packit bc1512
}
Packit bc1512
Packit bc1512
static void
Packit bc1512
gegl_chant_class_init (GeglChantClass *klass)
Packit bc1512
{
Packit bc1512
  GeglOperationClass         *operation_class;
Packit bc1512
  GeglOperationComposerClass *composer_class;
Packit bc1512
Packit bc1512
  operation_class = GEGL_OPERATION_CLASS (klass);
Packit bc1512
  composer_class  = GEGL_OPERATION_COMPOSER_CLASS (klass);
Packit bc1512
Packit bc1512
  composer_class->process = process;
Packit bc1512
  operation_class->prepare = prepare;
Packit bc1512
  operation_class->get_required_for_output = get_required_for_output;
Packit bc1512
Packit bc1512
  gegl_operation_class_set_keys (operation_class,
Packit bc1512
    "name"       , "gegl:map-absolute",
Packit bc1512
    "categories" , "transform",
Packit bc1512
    "description", _("sample input with an auxiliary buffer that contain absolute source coordinates"),
Packit bc1512
    NULL);
Packit bc1512
}
Packit bc1512
#endif