Пример #1
0
static GeglRectangle
gegl_affine_get_bounding_box (GeglOperation *op)
{
  OpAffine      *affine  = OP_AFFINE (op);
  GeglMatrix3    matrix;
  GeglRectangle  in_rect = {0,0,0,0},
                 have_rect;
  gdouble        have_points [8];
  gint           i;

  GeglRectangle  context_rect;
  GeglSampler   *sampler;

  sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
      gegl_sampler_type_from_string (affine->filter));
  context_rect = *gegl_sampler_get_context_rect (sampler);
  g_object_unref (sampler);

  if (gegl_operation_source_get_bounding_box (op, "input"))
    in_rect = *gegl_operation_source_get_bounding_box (op, "input");

  gegl_affine_create_composite_matrix (affine, &matrix);

  if (gegl_affine_is_intermediate_node (affine) ||
      gegl_matrix3_is_identity (&matrix))
    {
      return in_rect;
    }

  in_rect.x      += context_rect.x;
  in_rect.y      += context_rect.y;
  in_rect.width  += context_rect.width;
  in_rect.height += context_rect.height;

  have_points [0] = in_rect.x;
  have_points [1] = in_rect.y;

  have_points [2] = in_rect.x + in_rect.width ;
  have_points [3] = in_rect.y;

  have_points [4] = in_rect.x + in_rect.width ;
  have_points [5] = in_rect.y + in_rect.height ;

  have_points [6] = in_rect.x;
  have_points [7] = in_rect.y + in_rect.height ;

  for (i = 0; i < 8; i += 2)
    gegl_matrix3_transform_point (&matrix,
                             have_points + i, have_points + i + 1);

  gegl_affine_bounding_box (have_points, 4, &have_rect);
  return have_rect;
}
Пример #2
0
static GeglRectangle
gegl_affine_get_required_for_output (GeglOperation       *op,
                                     const gchar         *input_pad,
                                     const GeglRectangle *region)
{
  OpAffine      *affine = OP_AFFINE (op);
  GeglMatrix3    inverse;
  GeglRectangle  requested_rect,
                 need_rect;
  GeglRectangle  context_rect;
  GeglSampler   *sampler;
  gdouble        need_points [8];
  gint           i;

  requested_rect = *region;
  sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
      gegl_sampler_type_from_string (affine->filter));
  context_rect = *gegl_sampler_get_context_rect (sampler);
  g_object_unref (sampler);

  gegl_affine_create_composite_matrix (affine, &inverse);
  gegl_matrix3_invert (&inverse);

  if (gegl_affine_is_intermediate_node (affine) ||
      gegl_matrix3_is_identity (&inverse))
    {
      return requested_rect;
    }

  need_points [0] = requested_rect.x;
  need_points [1] = requested_rect.y;

  need_points [2] = requested_rect.x + requested_rect.width ;
  need_points [3] = requested_rect.y;

  need_points [4] = requested_rect.x + requested_rect.width ;
  need_points [5] = requested_rect.y + requested_rect.height ;

  need_points [6] = requested_rect.x;
  need_points [7] = requested_rect.y + requested_rect.height ;

  for (i = 0; i < 8; i += 2)
    gegl_matrix3_transform_point (&inverse,
                             need_points + i, need_points + i + 1);
  gegl_affine_bounding_box (need_points, 4, &need_rect);

  need_rect.x      += context_rect.x;
  need_rect.y      += context_rect.y;
  need_rect.width  += context_rect.width;
  need_rect.height += context_rect.height;
  return need_rect;
}
Пример #3
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  gint x = result->x; /* initial x                   */
  gint y = result->y; /*           and y coordinates */

  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof (float));
  gfloat *out_pixel = dst_buf;

  GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                  babl_format ("RGBA float"),
                                                  o->sampler_type);

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

  while (n_pixels--)
    {
      gegl_sampler_get (sampler,
                        x,
                        y,
                        NULL,
                        out_pixel,
                        GEGL_ABYSS_NONE);

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=result->x + result->width)
        {
          x=result->x;
          y++;
        }
    }

  gegl_buffer_set (output, result, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);

  g_object_unref (sampler);

  return  TRUE;
}
Пример #4
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);

  gint x = result->x; /* initial x                   */
  gint y = result->y; /*           and y coordinates */

  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat));

  gfloat *out_pixel = dst_buf;

  GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                  babl_format ("RGBA float"),
                                                  o->sampler_type);

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

  while (n_pixels--)
    {
      gdouble shift;
      gdouble coordsx;
      gdouble coordsy;
      gdouble lambda;

      gdouble angle_rad = o->angle / 180.0 * G_PI;
      gdouble nx = x * cos (angle_rad) + y * sin (angle_rad);

      switch (o->wave_type)
        {
          case GEGl_RIPPLE_WAVE_TYPE_SAWTOOTH:
            lambda = div (nx,o->period).rem - o->phi * o->period;
            if (lambda < 0)
              lambda += o->period;
            shift = o->amplitude * (fabs (((lambda / o->period) * 4) - 2) - 1);
            break;
          case GEGl_RIPPLE_WAVE_TYPE_SINE:
          default:
            shift = o->amplitude * sin (2.0 * G_PI * nx / o->period + 2.0 * G_PI * o->phi);
            break;
        }

      coordsx = x + shift * sin (angle_rad);
      coordsy = y + shift * cos (angle_rad);

      gegl_sampler_get (sampler,
                        coordsx,
                        coordsy,
                        NULL,
                        out_pixel);

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=result->x + result->width)
        {
          x=result->x;
          y++;
        }
    }

  gegl_buffer_set (output, result, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);

  g_object_unref (sampler);

  return  TRUE;
}
Пример #5
0
static gboolean
gegl_affine_process (GeglOperation        *operation,
                     GeglOperationContext *context,
                     const gchar          *output_prop,
                     const GeglRectangle  *result)
{
  GeglBuffer          *input;
  GeglBuffer          *output;
  GeglMatrix3          matrix;
  OpAffine            *affine = (OpAffine *) operation;

  gegl_affine_create_composite_matrix (affine, &matrix);

  if (gegl_affine_is_intermediate_node (affine) ||
      gegl_matrix3_is_identity (&matrix))
    {
      /* passing straight through (like gegl:nop) */
      input  = gegl_operation_context_get_source (context, "input");
      if (!input)
        {
          g_warning ("transform received NULL input");
          return FALSE;
        }

      gegl_operation_context_take_object (context, "output", G_OBJECT (input));
    }
  else if (gegl_affine_matrix3_allow_fast_translate (&matrix) ||
           (gegl_matrix3_is_translate (&matrix) &&
            ! strcmp (affine->filter, "nearest")))
    {
      /* doing a buffer shifting trick, (enhanced nop) */
      input  = gegl_operation_context_get_source (context, "input");

      output = g_object_new (GEGL_TYPE_BUFFER,
                             "source",    input,
                             "shift-x",   (int)-matrix.coeff[0][2],
                             "shift-y",   (int)-matrix.coeff[1][2],
                             "abyss-width", -1,  /* turn of abyss
                                                    (relying on abyss
                                                    of source) */
                         NULL);

      if (gegl_object_get_has_forked (input))
        gegl_object_set_has_forked (output);

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

      if (input != NULL)
        g_object_unref (input);
    }
  else if (gegl_affine_matrix3_allow_fast_reflect_x (&matrix))
    {
      GeglRectangle      src_rect;
      GeglSampler       *sampler;
      GeglRectangle      context_rect;

      input  = gegl_operation_context_get_source (context, "input");
      if (!input)
        {
          g_warning ("transform received NULL input");
          return FALSE;
        }

      output = gegl_operation_context_get_target (context, "output");

      src_rect = gegl_operation_get_required_for_output (operation, "output", result);
      src_rect.y += 1;

      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
          gegl_sampler_type_from_string (affine->filter));
      context_rect = *gegl_sampler_get_context_rect (sampler);

      src_rect.width -= context_rect.width;
      src_rect.height -= context_rect.height;

      gegl_affine_fast_reflect_x (output, input, result, &src_rect);
      g_object_unref (sampler);

      if (input != NULL)
        g_object_unref (input);
    }
  else if (gegl_affine_matrix3_allow_fast_reflect_y (&matrix))
    {
      GeglRectangle      src_rect;
      GeglSampler       *sampler;
      GeglRectangle      context_rect;

      input  = gegl_operation_context_get_source (context, "input");
      if (!input)
        {
          g_warning ("transform received NULL input");
          return FALSE;
        }

      output = gegl_operation_context_get_target (context, "output");

      src_rect = gegl_operation_get_required_for_output (operation, "output", result);
      src_rect.x += 1;

      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
          gegl_sampler_type_from_string (affine->filter));
      context_rect = *gegl_sampler_get_context_rect (sampler);

      src_rect.width -= context_rect.width;
      src_rect.height -= context_rect.height;

      gegl_affine_fast_reflect_y (output, input, result, &src_rect);
      g_object_unref (sampler);

      if (input != NULL)
        g_object_unref (input);
    }
  else
    {
      /* for all other cases, do a proper resampling */
      GeglSampler *sampler;

      input  = gegl_operation_context_get_source (context, "input");
      output = gegl_operation_context_get_target (context, "output");

      sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
          gegl_sampler_type_from_string (affine->filter));
      affine_generic (output, input, &matrix, sampler);
      g_object_unref (sampler);

      if (input != NULL)
        g_object_unref (input);
    }

  return TRUE;
}
Пример #6
0
static GeglRectangle
gegl_affine_get_invalidated_by_change (GeglOperation       *op,
                                       const gchar         *input_pad,
                                       const GeglRectangle *input_region)
{
  OpAffine          *affine = OP_AFFINE (op);
  GeglMatrix3        matrix;
  GeglRectangle      affected_rect;
  GeglRectangle      context_rect;
  GeglSampler       *sampler;
  gdouble            affected_points [8];
  gint               i;
  GeglRectangle      region = *input_region;

  sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
      gegl_sampler_type_from_string (affine->filter));
  context_rect = *gegl_sampler_get_context_rect (sampler);
  g_object_unref (sampler);

  gegl_affine_create_matrix (affine, &matrix);

  if (affine->origin_x || affine->origin_y)
    gegl_matrix3_originate (&matrix, affine->origin_x, affine->origin_y);

  if (gegl_affine_is_composite_node (affine))
    {
      GeglMatrix3 source;

      gegl_affine_get_source_matrix (affine, &source);
      gegl_matrix3_multiply (&source, &matrix, &matrix);
    }

  if (gegl_affine_is_intermediate_node (affine) ||
      gegl_matrix3_is_identity (&matrix))
    {
      return region;
    }

  region.x      += context_rect.x;
  region.y      += context_rect.y;
  region.width  += context_rect.width;
  region.height += context_rect.height;

  affected_points [0] = region.x;
  affected_points [1] = region.y;

  affected_points [2] = region.x + region.width ;
  affected_points [3] = region.y;

  affected_points [4] = region.x + region.width ;
  affected_points [5] = region.y + region.height ;

  affected_points [6] = region.x;
  affected_points [7] = region.y + region.height ;

  for (i = 0; i < 8; i += 2)
    gegl_matrix3_transform_point (&matrix,
                             affected_points + i, affected_points + i + 1);

  gegl_affine_bounding_box (affected_points, 4, &affected_rect);
  return affected_rect;
}
Пример #7
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO  *o = GEGL_CHANT_PROPERTIES (operation);
  gint         x = result->x; /* initial x                   */
  gint         y = result->y; /*           and y coordinates */

  gfloat      *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof (gfloat));

  gfloat      *out_pixel = dst_buf;

  GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                  babl_format ("RGBA float"),
                                                  o->sampler_type);

  gint         n_pixels = result->width * result->height;
  GeglAbyssPolicy abyss = o->clamp ? GEGL_ABYSS_CLAMP : GEGL_ABYSS_NONE;

  gdouble scalex;
  gdouble scaley;

  if (o->aspect > 1.0)
    {
      scalex = 1.0;
      scaley = o->aspect;
    }
  else if (o->aspect < 1.0)
    {
      scalex = 1.0 / o->aspect;
      scaley = 1.0;
    }
  else
    {
      scalex = 1.0;
      scaley = 1.0;
    }

  while (n_pixels--)
    {
      gdouble radius;
      gdouble shift;
      gdouble dx;
      gdouble dy;
      gdouble ux;
      gdouble uy;

      dx = (x - o->x) * scalex;
      dy = (y - o->y) * scaley;

      radius = sqrt (dx * dx + dy * dy);

      shift = o->amplitude * sin (2.0 * G_PI * radius / o->period +
                                  2.0 * G_PI * o->phi);

      ux = dx / radius;
      uy = dy / radius;

      gegl_sampler_get (sampler,
                        x + (shift + ux) / scalex,
                        y + (shift + uy) / scaley,
                        NULL,
                        out_pixel,
                        abyss);

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x >= result->x + result->width)
        {
          x = result->x;
          y++;
        }
    }

  gegl_buffer_set (output, result, 0, babl_format ("RGBA float"),
                   dst_buf, GEGL_AUTO_ROWSTRIDE);

  g_slice_free1 (result->width * result->height * 4 * sizeof (gfloat), dst_buf);

  g_object_unref (sampler);

  return TRUE;
}
Пример #8
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);

  gint x = result->x; /* initial x                   */
  gint y = result->y; /*           and y coordinates */

  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat));

  gfloat *out_pixel = dst_buf;

  GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                  babl_format ("RGBA float"),
                                                  o->sampler_type);

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

  while (n_pixels--)
    {
      gdouble coordsx = 0.0;
      gdouble coordsy = 0.0;
      gdouble radius = 0.0;
      gdouble shift = 0.0;
      gdouble ux = 0.0; /* unit vector of the radius */
      gdouble uy = 0.0;
      gdouble vx = 0.0; /* orthogonal vector of u */
      gdouble vy = 0.0;
      gdouble dx = 0.0;
      gdouble dy = 0.0;

      dx = (gdouble)x-o->x;
      dy = (gdouble)y-o->y;

      radius = sqrt( dx * dx + dy * dy );
      shift = o->amplitude * sin(2.0 * G_PI * radius / o->period + 2.0 * G_PI * o->phi);

      ux = dx / radius;
      uy = dy / radius;
      vx = -uy;
      vy = ux;

      coordsx = x + shift * vx;
      coordsy = y + shift * vy;


      gegl_sampler_get (sampler,
                        coordsx,
                        coordsy,
                        NULL,
                        out_pixel);

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=result->x + result->width)
        {
          x=result->x;
          y++;
        }
    }

  gegl_buffer_set (output, result, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);

  g_object_unref (sampler);

  return  TRUE;
}