GeglSampler * gegl_buffer_sampler_new (GeglBuffer *buffer, const Babl *format, GeglSamplerType sampler_type) { return gegl_buffer_sampler_new_at_level (buffer, format, sampler_type, 0); }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglProperties *o = GEGL_PROPERTIES (operation); GeglRectangle boundary; const Babl *format; GeglSampler *sampler; gfloat *dst_buf; gint y; boundary = gegl_operation_get_bounding_box (operation); format = babl_format ("RGBA float"); dst_buf = g_new0 (gfloat, result->width * result->height * 4); sampler = gegl_buffer_sampler_new_at_level (input, format, GEGL_SAMPLER_CUBIC, level); for (y = result->y; y < result->y + result->height; y++) fractaltrace (input, sampler, &boundary, dst_buf, result, o, y, o->fractal, format, level); gegl_buffer_set (output, result, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE); g_object_unref (sampler); g_free (dst_buf); gegl_buffer_sample_cleanup (input); return TRUE; }
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 *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 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) { 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 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 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); 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; }