Beispiel #1
0
static void
apply_whirl_pinch (gdouble              whirl,
                   gdouble              pinch,
                   gdouble              radius,
                   gdouble              cen_x,
                   gdouble              cen_y,
                   const Babl          *format,
                   GeglBuffer          *src,
                   GeglRectangle       *in_boundary,
                   GeglBuffer          *dst,
                   GeglRectangle       *boundary,
                   const GeglRectangle *roi,
                   gint                 level)
{
  gfloat *dst_buf;
  gint row, col;
  gdouble scale_x, scale_y;
  gdouble cx, cy;
  GeglSampler *sampler;

  /* 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 = (gdouble) in_boundary->width / in_boundary->height;
  sampler = gegl_buffer_sampler_new_at_level (src, babl_format ("RaGaBaA float"),
                                     GEGL_SAMPLER_NOHALO, level);

  for (row = 0; row < roi->height; row++) {
    for (col = 0; col < roi->width; col++) {
        GeglMatrix2 scale;
#define gegl_unmap(u,v,du,dv) \
        { \
          calc_undistorted_coords (u, v,\
                                   cen_x, cen_y,\
                                   scale_x, scale_y,\
                                   whirl, pinch, radius,\
                                   &cx, &cy);\
          du=cx;dv=cy;\
        }
        gegl_sampler_compute_scale (scale, roi->x + col, roi->y + row);
        gegl_unmap (roi->x + col, roi->y + row, cx, cy);

        gegl_sampler_get (sampler, cx, cy, &scale, &dst_buf[(row * roi->width + col) * 4], GEGL_ABYSS_NONE);
    } /* for */
  } /* for */

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

  g_free (dst_buf);
  g_object_unref (sampler);
}
Beispiel #2
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;
}
Beispiel #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(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;
}
Beispiel #4
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties     *o       = GEGL_PROPERTIES (operation);
  GeglSampler        *sampler = gegl_buffer_sampler_new_at_level (input,
                                                         babl_format ("RGBA float"),
                                                         o->sampler_type,
                                                         level);
  GeglRectangle      *in_extent = gegl_operation_source_get_bounding_box (operation, "input");
  GeglBufferIterator *iter;

  GeglAbyssPolicy abyss = o->clamp ? GEGL_ABYSS_CLAMP : GEGL_ABYSS_NONE;

  gdouble px_x = gegl_coordinate_relative_to_pixel (o->x, in_extent->width);
  gdouble px_y = gegl_coordinate_relative_to_pixel (o->y, in_extent->height);

  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;
    }

  iter = gegl_buffer_iterator_new (output, result, 0, babl_format ("RGBA float"),
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gint x = result->x;
      gint y = result->y;
      gfloat *out_pixel = iter->data[0];

      for (y = iter->roi[0].y; y < iter->roi[0].y + iter->roi[0].height; ++y)
        for (x = iter->roi[0].x; x < iter->roi[0].x + iter->roi[0].width; ++x)
          {
            gdouble radius;
            gdouble shift;
            gdouble dx;
            gdouble dy;
            gdouble ux;
            gdouble uy;

            dx = (x - px_x) * scalex;
            dy = (y - px_y) * scaley;

            if (!dx && !dy)
              radius = 0.000001;
            else
              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;
          }
    }

  g_object_unref (sampler);

  return TRUE;
}
Beispiel #5
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties         *o       = GEGL_PROPERTIES (operation);
  GeglSampler        *sampler = gegl_buffer_sampler_new_at_level (input,
                                                         babl_format ("RGBA float"),
                                                         o->sampler_type,
                                                         level);
  GeglBufferIterator *iter;

  GeglAbyssPolicy abyss = o->tileable ? GEGL_ABYSS_LOOP : GEGL_ABYSS_NONE;

  iter = gegl_buffer_iterator_new (output, result, 0, babl_format ("RGBA float"),
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gint x = result->x;
      gint y = result->y;
      gfloat *out_pixel = iter->data[0];

      for (y = iter->roi[0].y; y < iter->roi[0].y + iter->roi[0].height; ++y)
        for (x = iter->roi[0].x; x < iter->roi[0].x + iter->roi[0].width; ++x)
          {
            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,
                              abyss);

            out_pixel += 4;
          }
    }

  g_object_unref (sampler);

  return  TRUE;
}
Beispiel #6
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties      *o      = GEGL_PROPERTIES (operation);
  const Babl          *format = babl_format ("RGBA float");
  GeglSampler         *sampler;
  GeglBufferIterator  *iter;
  const GeglRectangle *in_extent;
  gdouble              cx, cy;
  gdouble              dx = 0.0, dy = 0.0;
  gdouble              coangle_of_view_2;
  gdouble              focal_length;
  gdouble              curvature_sign;
  gdouble              cap_angle_2;
  gdouble              cap_radius;
  gdouble              cap_depth;
  gdouble              factor;
  gdouble              f, f2, r, r_inv, r2, p, f_p, f_p2, f_pf, a, a_inv, sgn;
  gboolean             perspective;
  gboolean             inverse;
  gint                 i, j;

  sampler = gegl_buffer_sampler_new_at_level (input, format,
                                              o->sampler_type, level);

  iter = gegl_buffer_iterator_new (output, roi, level, format,
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, input, roi, level, format,
                            GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  in_extent = gegl_operation_source_get_bounding_box (operation, "input");

  cx = in_extent->x + in_extent->width  / 2.0;
  cy = in_extent->y + in_extent->height / 2.0;

  if (o->mode == GEGL_SPHERIZE_MODE_RADIAL ||
      o->mode == GEGL_SPHERIZE_MODE_HORIZONTAL)
    {
      dx = 2.0 / (in_extent->width - 1);
    }
  if (o->mode == GEGL_SPHERIZE_MODE_RADIAL ||
      o->mode == GEGL_SPHERIZE_MODE_VERTICAL)
    {
      dy = 2.0 / (in_extent->height - 1);
    }

  coangle_of_view_2 = MAX (180.0 - o->angle_of_view, 0.01) * G_PI / 360.0;
  focal_length      = tan (coangle_of_view_2);
  curvature_sign    = o->curvature > 0.0 ? +1.0 : -1.0;
  cap_angle_2       = fabs (o->curvature) * coangle_of_view_2;
  cap_radius        = 1.0 / sin (cap_angle_2);
  cap_depth         = curvature_sign * cap_radius * cos (cap_angle_2);
  factor            = fabs (o->amount);

  f     = focal_length;
  f2    = f * f;
  r     = cap_radius;
  r_inv = 1 / r;
  r2    = r * r;
  p     = cap_depth;
  f_p   = f + p;
  f_p2  = f_p * f_p;
  f_pf  = f_p * f;
  a     = cap_angle_2;
  a_inv = 1 / a;
  sgn   = curvature_sign;

  perspective = o->angle_of_view > EPSILON;
  inverse     = o->amount < 0.0;

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat       *out_pixel = iter->data[0];
      const gfloat *in_pixel  = iter->data[1];
      gfloat        x,  y;

      y = dy * (iter->roi->y + 0.5 - cy);

      for (j = iter->roi->y; j < iter->roi->y + iter->roi->height; j++, y += dy)
        {
          x = dx * (iter->roi->x + 0.5 - cx);

          for (i = iter->roi->x; i < iter->roi->x + iter->roi->width; i++, x += dx)
            {
              gfloat d2;

              d2 = x * x + y * y;

              if (d2 > EPSILON && d2 < 1.0 - EPSILON)
                {
                  gdouble d     = sqrt (d2);
                  gdouble src_d = d;
                  gdouble src_x, src_y;

                  if (! inverse)
                    {
                      gdouble d2_f2 = d2 + f2;

                      if (perspective)
                        src_d = (f_pf - sgn * sqrt (d2_f2 * r2 - f_p2 * d2)) * d / d2_f2;

                      src_d = (G_PI_2 - acos (src_d * r_inv)) * a_inv;
                    }
                  else
                    {
                      src_d = r * cos (G_PI_2 - src_d * a);

                      if (perspective)
                        src_d = f * src_d / (f_p - sgn * sqrt (r2 - src_d * src_d));
                    }

                  if (factor < 1.0)
                    src_d = d + (src_d - d) * factor;

                  src_x = dx ? cx + src_d * x / (dx * d) :
                               i + 0.5;
                  src_y = dy ? cy + src_d * y / (dy * d) :
                               j + 0.5;

                  gegl_sampler_get (sampler, src_x, src_y,
                                    NULL, out_pixel, GEGL_ABYSS_NONE);
                }
              else
                {
                  memcpy (out_pixel, in_pixel, sizeof (gfloat) * 4);
                }

              out_pixel += 4;
              in_pixel  += 4;
            }
        }
    }

  g_object_unref (sampler);

  return TRUE;
}
Beispiel #7
0
static void
affine_generic (GeglBuffer  *dest,
                GeglBuffer  *src,
                GeglMatrix3 *matrix,
                GeglSampler *sampler)
{
  GeglBufferIterator *i;
  const GeglRectangle *dest_extent;
  gint                  x, y;
  gfloat * restrict     dest_buf,
                       *dest_ptr;
  GeglMatrix3           inverse;
  GeglMatrix2           inverse_jacobian;
  gdouble               u_start,
                        v_start,
                        u_float,
                        v_float;

  Babl                 *format;

  gint                  dest_pixels;

  format = babl_format ("RaGaBaA float");

  /* XXX: fast paths as existing in files in the same dir as affine.c
   *      should probably be hooked in here, and bailing out before using
   *      the generic code.
   */
  g_object_get (dest, "pixels", &dest_pixels, NULL);
  dest_extent = gegl_buffer_get_extent (dest);


  i = gegl_buffer_iterator_new (dest, dest_extent, format, GEGL_BUFFER_WRITE);
  while (gegl_buffer_iterator_next (i))
    {
      GeglRectangle *roi = &i->roi[0];
      dest_buf           = (gfloat *)i->data[0];

      gegl_matrix3_copy_into (&inverse, matrix);
      gegl_matrix3_invert (&inverse);
      inverse_jacobian.coeff[0][0] = inverse.coeff[0][0];
      inverse_jacobian.coeff[0][1] = inverse.coeff[0][1];
      inverse_jacobian.coeff[1][0] = inverse.coeff[1][0];
      inverse_jacobian.coeff[1][1] = inverse.coeff[1][1];

     /* set inverse_jacobian for samplers that support it */
      u_start = inverse.coeff[0][0] * roi->x + inverse.coeff[0][1]
                    * roi->y + inverse.coeff[0][2];
      v_start = inverse.coeff[1][0] * roi->x + inverse.coeff[1][1]
                    * roi->y + inverse.coeff[1][2];

      /* correct rounding on e.g. negative scaling (is this sound?) */
      if (inverse.coeff [0][0] < 0.)  u_start -= .001;
      if (inverse.coeff [1][1] < 0.)  v_start -= .001;

      for (dest_ptr = dest_buf, y = roi->height; y--;)
        {
           u_float = u_start;
           v_float = v_start;

           for (x = roi->width; x--;)
             {
               gegl_sampler_get (sampler, u_float, v_float, &inverse_jacobian, dest_ptr);
               dest_ptr+=4;
               u_float += inverse.coeff [0][0];
               v_float += inverse.coeff [1][0];
             }
           u_start += inverse.coeff [0][1];
           v_start += inverse.coeff [1][1];
        }
    }
}
Beispiel #8
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;
}
Beispiel #9
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties         *o = GEGL_PROPERTIES (operation);
  GeglBufferIterator *iter;
  GeglBuffer         *dest1;
  GeglBuffer         *dest2;
  GeglSampler        *sampler1;
  GeglSampler        *sampler2;
  gdouble             ramp;
  gint                x;
  gint                y;
  gfloat              tot_pixels = result->width * result->height;
  gfloat              pixels = 0;

  grey_blur_buffer (input, o->mask_radius, &dest1, &dest2);

  sampler1 = gegl_buffer_sampler_new_at_level (dest1,
                                               babl_format ("Y' float"),
                                               GEGL_SAMPLER_LINEAR,
                                               level);

  sampler2 = gegl_buffer_sampler_new_at_level (dest2,
                                               babl_format ("Y' float"),
                                               GEGL_SAMPLER_LINEAR,
                                               level);

  ramp = compute_ramp (sampler1, sampler2, result, o->pct_black);

  iter = gegl_buffer_iterator_new (output, result, 0,
                                   babl_format ("Y'CbCrA float"),
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
  gegl_buffer_iterator_add (iter, input, result, 0,
                            babl_format ("Y'CbCrA float"),
                            GEGL_ACCESS_READ, GEGL_ABYSS_NONE);


  gegl_operation_progress (operation, 0.0, "");

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *out_pixel = iter->data[0];
      gfloat *in_pixel  = iter->data[1];

      for (y = iter->roi[0].y; y < iter->roi[0].y + iter->roi[0].height; ++y)
      {
        for (x = iter->roi[0].x; x < iter->roi[0].x + iter->roi[0].width; ++x)
          {
            gfloat  pixel1;
            gfloat  pixel2;
            gdouble mult = 0.0;
            gdouble diff;

            gegl_sampler_get (sampler1, x, y,
                              NULL, &pixel1,
                              GEGL_ABYSS_NONE);

            gegl_sampler_get (sampler2, x, y,
                              NULL, &pixel2,
                              GEGL_ABYSS_NONE);

            if (pixel2 != 0)
              {
                diff = (gdouble) pixel1 / (gdouble) pixel2;
                if (diff < THRESHOLD)
                  {
                    if (GEGL_FLOAT_EQUAL (ramp, 0.0))
                      mult = 0.0;
                    else
                      mult = (ramp - MIN (ramp, (THRESHOLD - diff))) / ramp;
                  }
                else
                  mult = 1.0;
              }

            out_pixel[0] = CLAMP (pixel1 * mult, 0.0, 1.0);
            out_pixel[1] = in_pixel[1];
            out_pixel[2] = in_pixel[2];
            out_pixel[3] = in_pixel[3];

            out_pixel += 4;
            in_pixel  += 4;

          }
        pixels += iter->roi[0].width;
        gegl_operation_progress (operation, pixels / tot_pixels, "");
      }
    }

  gegl_operation_progress (operation, 1.0, "");

  g_object_unref (sampler1);
  g_object_unref (sampler2);

  g_object_unref (dest1);
  g_object_unref (dest2);

  return TRUE;
}
Beispiel #10
0
static void
fractaltrace (GeglBuffer            *input,
              GeglSampler           *sampler,
              const GeglRectangle   *picture,
              gfloat                *dst_buf,
              const GeglRectangle   *roi,
              GeglProperties        *o,
              gint                   y,
              GeglFractalTraceType   fractal_type,
              const Babl            *format,
              gint                   level)
{
  GeglMatrix2  scale;        /* a matrix indicating scaling factors around the
                                current center pixel.
                              */
  gint         x, i, offset;
  gdouble      scale_x, scale_y;
  gdouble      bailout2;
  gfloat       dest[4];

  scale_x = (o->X2 - o->X1) / picture->width;
  scale_y = (o->Y2 - o->Y1) / picture->height;

  bailout2 = o->bailout * o->bailout;

  offset = (y - roi->y) * roi->width * 4;

  for (x = roi->x; x < roi->x + roi->width; x++)
    {
      gdouble cx, cy;
      gdouble px, py;
      dest[1] = dest[2] = dest[3] = dest[0] = 0.0;

      switch (fractal_type)
        {
        case GEGL_FRACTAL_TRACE_TYPE_JULIA:
#define gegl_unmap(u,v,ud,vd) {                                         \
            gdouble rx, ry;                                             \
            cx = o->X1 + ((u) - picture->x) * scale_x;                  \
            cy = o->Y1 + ((v) - picture->y) * scale_y;                  \
            julia (cx, cy, o->JX, o->JY, &rx, &ry, o->depth, bailout2); \
            ud = (rx - o->X1) / scale_x + picture->x;                   \
            vd = (ry - o->Y1) / scale_y + picture->y;                   \
          }
        gegl_sampler_compute_scale (scale, x, y);
        gegl_unmap(x,y,px,py);
#undef gegl_unmap
        break;

        case GEGL_FRACTAL_TRACE_TYPE_MANDELBROT:
#define gegl_unmap(u,v,ud,vd) {                                     \
            gdouble rx, ry;                                         \
            cx = o->X1 + ((u) - picture->x) * scale_x;              \
            cy = o->Y1 + ((v) - picture->y) * scale_y;              \
            julia (cx, cy, cx, cy, &rx, &ry, o->depth, bailout2);   \
            ud = (rx - o->X1) / scale_x + picture->x;               \
            vd = (ry - o->Y1) / scale_y + picture->y;               \
          }
        gegl_sampler_compute_scale (scale, x, y);
        gegl_unmap(x,y,px,py);
#undef gegl_unmap
        break;

        default:
          g_error (_("Unsupported fractal type"));
        }

      gegl_sampler_get (sampler, px, py, &scale, dest, o->abyss_policy);

      for (i = 0; i < 4; i++)
        dst_buf[offset++] = dest[i];
    }
}
Beispiel #11
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;
}
Beispiel #12
0
static void
apply_mirror (double               mirror_angle,
              double               result_angle,
              int                  nsegs,
              double               cen_x,
              double               cen_y,
              double               off_x,
              double               off_y,
              double               input_scale,
              gboolean             clip,
              gboolean             warp,
              const Babl          *format,
              GeglBuffer          *src,
              GeglRectangle       *in_boundary,
              GeglBuffer          *dst,
              GeglRectangle       *boundary,
              const GeglRectangle *roi,
              gint                 level)
{
  gfloat *dst_buf;
  GeglSampler *sampler;
  gint    row, col;
  gdouble cx, cy;

  /* Get src pixels. */

  #ifdef TRACE
    g_warning ("> mirror marker1, boundary x:%d, y:%d, w:%d, h:%d, center: (%f, %f) offset: (%f, %f)", boundary->x, boundary->y, boundary->width, boundary->height, cen_x, cen_y, off_x,off_y );
  #endif

  #ifdef DO_NOT_USE_BUFFER_SAMPLE
    src_buf = g_new0 (gfloat, boundary->width * boundary->height * 4);
    gegl_buffer_get (src, 1.0, boundary, format, src_buf, GEGL_AUTO_ROWSTRIDE);
  #else
    sampler = gegl_buffer_sampler_new_at_level (src, format, GEGL_SAMPLER_LINEAR, level);
  #endif
  /* Get buffer in which to place dst pixels. */
  dst_buf = g_new0 (gfloat, roi->width * roi->height * 4);

  mirror_angle   = mirror_angle * G_PI / 180;
  result_angle   = result_angle * G_PI / 180;

  for (row = 0; row < roi->height; row++) {
    for (col = 0; col < roi->width; col++) {
        calc_undistorted_coords(roi->x + col + 0.01, roi->y + row - 0.01, mirror_angle, result_angle,
                                  nsegs,
                                  cen_x, cen_y,
                                  off_x * input_scale, off_y * input_scale,
                                  &cx, &cy);


  /* apply scale*/
  cx = in_boundary->x + (cx - in_boundary->x) / input_scale;
  cy = in_boundary->y + (cy - in_boundary->y) / input_scale;

        /*Warping*/
        if (warp)
          {
            double dx = cx - in_boundary->x;
            double dy = cy - in_boundary->y;

            double width_overrun = ceil ((dx) / (in_boundary->width)) ;
            double height_overrun = ceil ((dy) / (in_boundary->height));

            if (cx <= (in_boundary->x))
              {
                if ( fabs (fmod (width_overrun, 2)) < 1.0)
                  cx = in_boundary->x - fmod (dx, in_boundary->width);
                else
                  cx = in_boundary->x + in_boundary->width + fmod (dx, in_boundary->width);
              }

            if (cy <= (in_boundary->y))
              {
                if ( fabs (fmod (height_overrun, 2)) < 1.0)
                  cy = in_boundary->y + fmod (dy, in_boundary->height);
                else
                  cy = in_boundary->y + in_boundary->height - fmod (dy, in_boundary->height);
              }

            if (cx >= (in_boundary->x + in_boundary->width))
              {
                if ( fabs (fmod (width_overrun, 2)) < 1.0)
                  cx = in_boundary->x + in_boundary->width - fmod (dx, in_boundary->width);
                else
                  cx = in_boundary->x + fmod (dx, in_boundary->width);
              }

            if (cy >= (in_boundary->y + in_boundary->height))
              {
                if ( fabs (fmod (height_overrun, 2)) < 1.0)
                  cy = in_boundary->y + in_boundary->height - fmod (dy, in_boundary->height);
                else
                  cy = in_boundary->y + fmod (dy, in_boundary->height);
              }
          }
        else /* cliping */
          {
            if (cx < boundary->x)
              cx = 0;
            if (cy < boundary->x)
              cy = 0;

            if (cx >= boundary->width)
              cx = boundary->width - 1;
            if (cy >= boundary->height)
              cy = boundary->height -1;
        }


        /* Top */
#ifdef DO_NOT_USE_BUFFER_SAMPLE

        if (cx >= 0.0)
          ix = (int) cx;
        else
          ix = -((int) -cx + 1);

        if (cy >= 0.0)
          iy = (int) cy;
        else
          iy = -((int) -cy + 1);

        spx_pos = (iy * boundary->width + ix) * 4;
#endif

#ifndef DO_NOT_USE_BUFFER_SAMPLE
        gegl_sampler_get (sampler, cx, cy, NULL, &dst_buf[(row * roi->width + col) * 4], GEGL_ABYSS_NONE);
#endif

#ifdef DO_NOT_USE_BUFFER_SAMPLE
         dst_buf[dpx_pos]     = src_buf[spx_pos];
         dst_buf[dpx_pos + 1] = src_buf[spx_pos + 1];
         dst_buf[dpx_pos + 2] = src_buf[spx_pos + 2];
         dst_buf[dpx_pos + 3] = src_buf[spx_pos + 3];
#endif

    } /* for */
  } /* for */


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

  /* Free acquired storage. */
#ifdef DO_NOT_USE_BUFFER_SAMPLE
  g_free (src_buf);
#else
  g_object_unref (sampler);
#endif
  g_free (dst_buf);

}
Beispiel #13
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties          *o            = GEGL_PROPERTIES (operation);
  GeglRectangle            boundary     = get_effective_area (operation);
  const Babl              *format       = babl_format ("RGBA float");
  GeglSampler             *sampler      = gegl_buffer_sampler_new_at_level (
                                    input, format, GEGL_SAMPLER_NOHALO,
                                    level);

  gint      x,y;
  gfloat   *src_buf, *dst_buf;
  gfloat    dest[4];
  gint      i, offset = 0;
  gboolean  inside;
  gdouble   px, py;

  GeglMatrix2  scale;        /* a matrix indicating scaling factors around the
                                current center pixel.
                             */

  src_buf = g_new0 (gfloat, result->width * result->height * 4);
  dst_buf = g_new0 (gfloat, result->width * result->height * 4);

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

  if (o->middle)
    {
      o->pole_x = boundary.width / 2;
      o->pole_y = boundary.height / 2;
    }

  for (y = result->y; y < result->y + result->height; y++)
    for (x = result->x; x < result->x + result->width; x++)
      {
#define gegl_unmap(u,v,ud,vd) {                                         \
          gdouble rx = 0.0, ry = 0.0;                                   \
          inside = calc_undistorted_coords ((gdouble)x, (gdouble)y,     \
                                            &rx, &ry, o, boundary);     \
          ud = rx;                                                      \
          vd = ry;                                                      \
        }
        gegl_sampler_compute_scale (scale, x, y);
        gegl_unmap(x,y,px,py);
#undef gegl_unmap

        if (inside)
          gegl_sampler_get (sampler, px, py, &scale, dest,
                            GEGL_ABYSS_NONE);
        else
          for (i=0; i<4; i++)
            dest[i] = 0.0;

        for (i=0; i<4; i++)
          dst_buf[offset++] = dest[i];
      }

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

  g_free (src_buf);
  g_free (dst_buf);

  g_object_unref (sampler);

  return  TRUE;
}
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  Transform           transform;
  const Babl         *format_io;
  GeglSampler        *sampler;
  gint                factor = 1 << level;
  GeglBufferIterator *it;
  GeglRectangle in_rect = *gegl_operation_source_get_bounding_box (operation, "input");
  GeglMatrix2  scale_matrix;
  GeglMatrix2 *scale = NULL;
  gint sampler_type = o->sampler_type;
  level = 0;
  factor = 1;
  prepare_transform2 (&transform, operation, level);

  if (level)
    sampler_type = GEGL_SAMPLER_NEAREST;

  format_io = babl_format ("RaGaBaA float");
  {
    /* XXX: panorama projection needs to sample from a higher resolution than
     * its output to yield good results. This affects which level should
     * be rendered for source nodes..
     */

    gint sample_level = level - 3;

    if (sample_level < 0)
      sample_level = 0;
    sampler = gegl_buffer_sampler_new_at_level (input, format_io, sampler_type,
                                       sample_level);
  }

  if (sampler_type == GEGL_SAMPLER_NOHALO ||
      sampler_type == GEGL_SAMPLER_LOHALO)
    scale = &scale_matrix;

  {
    float   ud = ((1.0/transform.width)*factor);
    float   vd = ((1.0/transform.height)*factor);

    it = gegl_buffer_iterator_new (output, result, level, format_io,
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

    while (gegl_buffer_iterator_next (it))
      {
        gint i;
        gint n_pixels = it->length;
        gint x = it->roi->x; /* initial x                   */
        gint y = it->roi->y; /*           and y coordinates */

        float   u0 = (((x*factor)/transform.width) - transform.xoffset);
        float   u, v;

        float *out = it->data[0];

        u = u0;
        v = ((y*factor/transform.height) - 0.5);

        if (scale)
          {
            for (i=0; i<n_pixels; i++)
              {
                float cx, cy;
#define gegl_unmap(xx,yy,ud,vd) {                                       \
                  float rx, ry;                                         \
                  transform.xy2ll (&transform, xx, yy, &rx, &ry);       \
                  ud = rx;vd = ry;}
                gegl_sampler_compute_scale (scale_matrix, u, v);
                gegl_unmap(u,v, cx, cy);
#undef gegl_unmap

                gegl_sampler_get (sampler,
                                  cx * in_rect.width, cy * in_rect.height,
                                  scale, out, GEGL_ABYSS_LOOP);
                out += 4;

                /* update x, y and u,v coordinates */
                x++;
                u+=ud;
                if (x >= (it->roi->x + it->roi->width))
                  {
                    x = it->roi->x;
                    y++;
                    u = u0;
                    v += vd;
                  }
              }
          }
        else
          {
            for (i=0; i<n_pixels; i++)
              {
                float cx, cy;

                transform.xy2ll (&transform, u, v, &cx, &cy);

                gegl_sampler_get (sampler,
                                  cx * in_rect.width, cy * in_rect.height,
                                  scale, out, GEGL_ABYSS_LOOP);
                out += 4;

                /* update x, y and u,v coordinates */
                x++;
                u+=ud;
                if (x >= (it->roi->x + it->roi->width))
                  {
                    x = it->roi->x;
                    u = u0;
                    y++;
                    v += vd;
                  }
              }
          }
      }
  }

  g_object_unref (sampler);

#if 0
  {
    float t;
    float lat0  = 0;
    float lon0 = 0;
    float lat1  = 0.5;
    float lon1 = 0.5;
    int i = 0;
    guchar pixel[4] = {255,0,0,255};

    for (t = 0; t < 1.0; t+=0.01, i++)
    {
      float lat = lat0 * (1.0 - t) + lat1 * t;
      float lon = lon0 * (1.0 - t) + lon1 * t;
      float x, y;
      float xx, yy;
      GeglRectangle prect = {0,0,1,1};

      ll2xy (&transform, lon, lat, &x, &y);

      x += xoffset;
      y += 0.5;

      x *= width;
      y *= height;

      prect.x = floor (x);
      prect.y = floor (y);
      prect.width = 1;
      prect.height = 1;

      gegl_buffer_set (output, &prect, 0, babl_format ("R'G'B' u8"), pixel, 8);
    }
  }
#endif

  return TRUE;
}
Beispiel #15
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties       *o = GEGL_PROPERTIES (operation);
  AlParamsType    *params = (AlParamsType *) o->user_data;
  const Babl      *format = babl_format ("RGBA float");

  GeglSampler        *sampler;
  GeglBufferIterator *iter;
  gint                x, y;

  sampler = gegl_buffer_sampler_new_at_level (input, format,
                                              GEGL_SAMPLER_CUBIC, level);

  iter = gegl_buffer_iterator_new (output, roi, level, format,
                                   GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter, input, roi, level, format,
                            GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *out_pixel = iter->data[0];
      gfloat *in_pixel  = iter->data[1];

      for (y = iter->roi->y; y < iter->roi->y + iter->roi->height; y++)
        {
          gdouble dy, dysqr;

          dy = -((gdouble) y - params->b + 0.5);
          dysqr = dy * dy;

          for (x = iter->roi->x; x < iter->roi->x + iter->roi->width; x++)
            {
              gdouble dx, dxsqr;

              dx = (gdouble) x - params->a + 0.5;
              dxsqr = dx * dx;

              if (dysqr < (params->bsqr - (params->bsqr * dxsqr) / params->asqr))
                {
                  /**
                   * If (x, y) is inside the affected region, we can find its original
                   * position and fetch the pixel with the sampler
                   */
                  gdouble ox, oy;
                  find_undistorted_pos (dx, dy, o->refraction_index, params,
                                        &ox, &oy);

                  gegl_sampler_get (sampler, ox + params->a, params->b - oy,
                                    NULL, out_pixel, GEGL_ABYSS_NONE);
                }
              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 (o->keep_surroundings)
                    memcpy (out_pixel, in_pixel, sizeof (gfloat) * 4);
                  else
                    memcpy (out_pixel, params->bg_color, sizeof (gfloat) * 4);
                }

              out_pixel += 4;
              in_pixel  += 4;
            }
        }
    }

  g_object_unref (sampler);

  return TRUE;
}
Beispiel #16
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *aux,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglProperties       *o = GEGL_PROPERTIES (operation);
  const Babl           *format_io, *format_coords;
  GeglSampler          *sampler;
  GeglBufferIterator   *it;
  gint                  index_in, index_out, index_coords;

  format_io = babl_format ("RGBA float");
  format_coords = babl_format_n (babl_type ("float"), 2);

  sampler = gegl_buffer_sampler_new_at_level (input, format_io, o->sampler_type, level);

  if (aux != NULL)
    {
      it = gegl_buffer_iterator_new (output, result, level, format_io,
                                     GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
      index_out = 0;

      index_coords = gegl_buffer_iterator_add (it, aux, result, level, format_coords,
                                               GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
      index_in = gegl_buffer_iterator_add (it, input, result, level, format_io,
                                           GEGL_ACCESS_READ, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (it))
        {
          gint        i;
          gint        n_pixels = it->length;
          gint        x = it->roi->x; /* initial x                   */
          gint        y = it->roi->y; /*           and y coordinates */
          gdouble     scaling = GEGL_PROPERTIES (operation)->scaling;
          gfloat     *in = it->data[index_in];
          gfloat     *out = it->data[index_out];
          gfloat     *coords = it->data[index_coords];

          for (i=0; i<n_pixels; i++)
            {
              /* if the coordinate asked is an exact pixel, we fetch it
               * directly, to avoid the blur of sampling */
              if (coords[0] == 0 && coords[1] == 0)
                {
                  out[0] = in[0];
                  out[1] = in[1];
                  out[2] = in[2];
                  out[3] = in[3];
                }
              else
                {
                  gegl_sampler_get (sampler, x+coords[0] * scaling,
                                             y+coords[1] * scaling,
                                             NULL, out,
                                             GEGL_ABYSS_NONE);
                }

              coords += 2;
              in += 4;
              out += 4;

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

            }
        }
    }
  else
    {
      gegl_buffer_copy (input, result, GEGL_ABYSS_NONE,
                        output, result);
    }

  g_object_unref (sampler);

  return TRUE;
}
Beispiel #17
0
static gdouble
compute_ramp (GeglSampler         *sampler1,
              GeglSampler         *sampler2,
              const GeglRectangle *roi,
              gdouble              pct_black)
{
  gint    hist[100];
  gdouble diff;
  gint    count;
  gfloat pixel1, pixel2;
  gint x;
  gint y;
  gint i;
  gint sum;

  memset (hist, 0, sizeof (int) * 100);
  count = 0;

  for (y = roi->y; y < roi->y + roi->height; ++y)
    for (x = roi->x; x < roi->x + roi->width; ++x)
      {
        gegl_sampler_get (sampler1,
                          x,
                          y,
                          NULL,
                          &pixel1,
                          GEGL_ABYSS_NONE);

        gegl_sampler_get (sampler2,
                          x,
                          y,
                          NULL,
                          &pixel2,
                          GEGL_ABYSS_NONE);

        if (pixel2 != 0)
          {
            diff = (gdouble) pixel1 / (gdouble) pixel2;

            if (diff < 1.0 && diff >= 0.0)
              {
                hist[(int) (diff * 100)] += 1;
                count += 1;
              }
          }
      }

  if (pct_black == 0.0 || count == 0)
    return 1.0;

  sum = 0;
  for (i = 0; i < 100; i++)
    {
      sum += hist[i];
      if (((gdouble) sum / (gdouble) count) > pct_black)
        return (1.0 - (gdouble) i / 100.0);
    }

  return 0.0;

}