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