buffer: add gegl_buffer_sampler_new

Always associating a sampler with a buffer allows for a tighter smaller public
API for efficient access to samplers.
parent bc158812
......@@ -358,6 +358,8 @@ void gegl_buffer_sample (GeglBuffer *buffer,
*/
void gegl_buffer_sample_cleanup (GeglBuffer *buffer);
/**
* gegl_interpolation_from_string:
* @string: the string to look up
......@@ -368,13 +370,25 @@ void gegl_buffer_sample_cleanup (GeglBuffer *buffer);
GeglInterpolation gegl_interpolation_from_string (const gchar *string);
/**
* gegl_sampler_from_interpolation:
* @string: the string to look up
* gegl_buffer_sample_new:
* @buffer: buffer to create a new sampler for
* @format: format we want data back in
* @interpolation: resampling method to create a sampler for.
*
* Looks up the GeglInterpolation corresponding to a string, if no matching
* interpolation is found returns GEGL_INTERPOLATION_NEAREST.
*/
GeglSampler *gegl_sampler_from_interpolation (GeglInterpolation interpolation);
GeglSampler *
gegl_buffer_sampler_new (GeglBuffer *buffer,
Babl *format,
GeglInterpolation interpolation);
void gegl_sampler_set_scale (GeglSampler *self,
GeglMatrix2 *scale);
void gegl_sampler_get (GeglSampler *self,
gdouble x,
gdouble y,
void *output);
/**
* gegl_buffer_linear_new:
......
......@@ -597,21 +597,27 @@ gegl_sampler_type_from_interpolation (GeglInterpolation interpolation)
}
GeglSampler *
gegl_sampler_from_interpolation (GeglInterpolation interpolation)
gegl_buffer_sampler_new (GeglBuffer *buffer,
Babl *format,
GeglInterpolation interpolation)
{
Babl *format = babl_format ("RaGaBaA float");
GeglSampler *sampler;
GType desired_type;
if (format == NULL)
format = babl_format ("RaGaBaA float");
desired_type = gegl_sampler_type_from_interpolation (interpolation);
if (interpolation == GEGL_INTERPOLATION_LANCZOS)
sampler = g_object_new (desired_type,
"format", format,
"buffer", buffer,
"lanczos_width", 4,
NULL);
else
sampler = g_object_new (desired_type,
"buffer", buffer,
"format", format,
NULL);
gegl_sampler_prepare (sampler);
return sampler;
}
......
......@@ -139,14 +139,6 @@ op_affine_get_type (void)
return g_define_type_id;
}
/* ************************* */
static GeglSampler *
op_affine_sampler (OpAffine *self)
{
return gegl_sampler_from_interpolation (gegl_interpolation_from_string (self->filter));
}
/* XXX: keep a pool of samplers */
#if 0
static void
op_affine_sampler_init (OpAffine *self)
......@@ -453,7 +445,8 @@ gegl_affine_get_bounding_box (GeglOperation *op)
GeglRectangle context_rect;
GeglSampler *sampler;
sampler = op_affine_sampler (OP_AFFINE (op));
sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
gegl_interpolation_from_string (affine->filter));
context_rect = sampler->context_rect[0];
g_object_unref (sampler);
......@@ -539,7 +532,8 @@ gegl_affine_get_required_for_output (GeglOperation *op,
gint i;
requested_rect = *region;
sampler = op_affine_sampler (OP_AFFINE (op));
sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
gegl_interpolation_from_string (affine->filter));
context_rect = sampler->context_rect[0];
g_object_unref (sampler);
......@@ -590,7 +584,8 @@ gegl_affine_get_invalidated_by_change (GeglOperation *op,
gint i;
GeglRectangle region = *input_region;
sampler = op_affine_sampler (OP_AFFINE (op));
sampler = gegl_buffer_sampler_new (NULL, babl_format("RaGaBaA float"),
gegl_interpolation_from_string (affine->filter));
context_rect = sampler->context_rect[0];
g_object_unref (sampler);
......@@ -828,11 +823,6 @@ gegl_affine_fast_reflect_y (GeglBuffer *dest,
g_free (buf);
}
void gegl_sampler_prepare (GeglSampler *self);
/*XXX: Eeeek, obsessive avoidance of public headers, the API needed to
* satisfy this use case should probably be provided.
*/
static gboolean
gegl_affine_process (GeglOperation *operation,
GeglOperationContext *context,
......@@ -900,7 +890,9 @@ gegl_affine_process (GeglOperation *operation,
src_rect = gegl_operation_get_required_for_output (operation, "output", result);
src_rect.y += 1;
sampler = op_affine_sampler (OP_AFFINE (operation));
sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
gegl_interpolation_from_string (affine->filter));
src_rect.width -= sampler->context_rect[0].width;
src_rect.height -= sampler->context_rect[0].height;
......@@ -926,7 +918,9 @@ gegl_affine_process (GeglOperation *operation,
src_rect = gegl_operation_get_required_for_output (operation, "output", result);
src_rect.x += 1;
sampler = op_affine_sampler (OP_AFFINE (operation));
sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
gegl_interpolation_from_string (affine->filter));
src_rect.width -= sampler->context_rect[0].width;
src_rect.height -= sampler->context_rect[0].height;
......@@ -943,9 +937,8 @@ gegl_affine_process (GeglOperation *operation,
input = gegl_operation_context_get_source (context, "input");
output = gegl_operation_context_get_target (context, "output");
sampler = op_affine_sampler (affine);
g_object_set(sampler, "buffer", input, NULL);
gegl_sampler_prepare (sampler);
sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"),
gegl_interpolation_from_string (affine->filter));
affine_generic (output, input, &matrix, sampler);
g_object_unref(sampler->buffer);
sampler->buffer = NULL;
......
......@@ -162,7 +162,7 @@ fractaltrace (GeglBuffer *input,
ud = (rx - o->X1) / scale_x + picture->x;\
vd = (ry - o->Y1) / scale_y + picture->y;\
}
gegl_compute_inverse_jacobian (scale, x, y);
gegl_sampler_compute_scale (scale, x, y);
gegl_unmap(x,y,px,py);
#undef gegl_unmap
break;
......@@ -173,8 +173,8 @@ fractaltrace (GeglBuffer *input,
if (0 <= px && px < picture->width && 0 <= py && py < picture->height)
{
gegl_buffer_sample2 (input, px, py, &scale, dest, format,
GEGL_INTERPOLATION_LOHALO);
gegl_buffer_sample (input, px, py, &scale, dest, format,
GEGL_INTERPOLATION_LOHALO);
}
else
{
......@@ -206,8 +206,8 @@ fractaltrace (GeglBuffer *input,
py = picture->height - 1.0;
}
gegl_buffer_sample2 (input, px, py, &scale, dest, format,
GEGL_INTERPOLATION_LOHALO);
gegl_buffer_sample (input, px, py, &scale, dest, format,
GEGL_INTERPOLATION_LOHALO);
break;
case BACKGROUND_TYPE_TRANSPARENT:
......
......@@ -131,6 +131,7 @@ apply_whirl_pinch (gdouble whirl, gdouble pinch, gdouble radius,
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);
......@@ -139,28 +140,36 @@ apply_whirl_pinch (gdouble whirl, gdouble pinch, gdouble radius,
scale_x = 1.0;
scale_y = roi->width / (gdouble) roi->height;
sampler = gegl_buffer_sampler_new (src, babl_format ("RaGaBaA float"),
GEGL_INTERPOLATION_LOHALO);
for (row = 0; row < roi->height; row++) {
for (col = 0; col < roi->width; col++) {
calc_undistorted_coords (roi->x + col, roi->y + row,
cen_x, cen_y,
scale_x, scale_y,
whirl, pinch, radius,
&cx, &cy);
gegl_buffer_sample (src, cx, cy, NULL, &dst_buf[(row * roi->width + col) * 4], format, GEGL_INTERPOLATION_LINEAR);
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_set_scale (sampler, &scale);
gegl_sampler_get (sampler, cx, cy, &dst_buf[(row * roi->width + col) * 4]);
} /* for */
} /* for */
gegl_buffer_sample_cleanup (src);
/* Store dst pixels. */
gegl_buffer_set (dst, roi, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
gegl_buffer_flush(dst);
g_free (dst_buf);
g_object_unref (sampler);
}
/*****************************************************************************/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment