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