Esempio n. 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);
}
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;
}
Esempio n. 3
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o            = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle            boundary     = get_effective_area (operation);
  const Babl              *format       = babl_format ("RGBA float");

  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, ry;                                               \
          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_buffer_sample (input, px, py, &scale, dest, format,
                              GEGL_SAMPLER_NOHALO, 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);

  return  TRUE;
}
Esempio n. 4
0
static void
fractaltrace (GeglBuffer            *input,
              const GeglRectangle   *picture,
              gfloat                *dst_buf,
              const GeglRectangle   *roi,
              GeglChantO            *o,
              gint                   y,
              GeglFractalTraceType  fractal_type,
              const Babl           *format)
{
  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_buffer_sample (input, px, py, &scale, dest, format,
                          GEGL_SAMPLER_NOHALO, o->abyss_policy);

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