Add raster.pixel_coord_map function.

Originally committed to SVN as r1512.
This commit is contained in:
Niels Martin Hansen 2007-08-18 14:18:13 +00:00
parent 17fbbaa583
commit 1ffa8c5a3a
4 changed files with 97 additions and 6 deletions

View file

@ -224,3 +224,9 @@ Create a field of random gray-values.
"0 =R 1 G - =G" "0 =R 1 G - =G"
Zero out the red channel and invert the green channel. Zero out the red channel and invert the green channel.
For raster.pixel_coord_map:
"X .5 rand - + =X Y .5 rand - + =Y"
Create some jitter in the pixels.

View file

@ -207,6 +207,23 @@ The following new registers are made available to the expression evaluator:
Y Y-coordinate of pixel being processed. Input only. Y Y-coordinate of pixel being processed. Input only.
raster.pixel_coord_map(surface, expression)
Map each pixel coordinate pair to a new coordinate pair in the surface. Only
works for ARGB32 and RGB24 surfaces.
The expression is an RPN expression in the OverLua Expression Evaluator
language, see expression-evaluator.txt for details.
No additional functions are made available to the expression evaluator by
this function.
The following new registers are made available to the expression evaluator:
X Absolute pixel X coordinate. Input and output. The output may be
non-integer, in that case bilinear interpolation is used.
Y Ditto, for Y coordinate.
More filtering functions are planned, though no specifics yet. More filtering functions are planned, though no specifics yet.
Wishes/suggestions are welcome, and so are patches to add more functions. Wishes/suggestions are welcome, and so are patches to add more functions.

View file

@ -4,11 +4,12 @@ function render_frame(f, t)
--raster.invert(surf) --raster.invert(surf)
--raster.separable_filter(surf, {-1, 3, -1}, 1) --raster.separable_filter(surf, {-1, 3, -1}, 1)
--raster.directional_blur(surf, t, t/10) --raster.directional_blur(surf, t, t/10)
raster.radial_blur(surf, 200, 200, t/60) --raster.radial_blur(surf, 200, 200, t/60)
raster.pixel_value_map(surf, "0 =R 1 G - =G") raster.pixel_value_map(surf, "G rand 0.1 * + =G G 1 - 1 G ifgtz =G")
raster.pixel_coord_map(surf, "X .5 rand - + =X Y .5 rand - + =Y")
f.overlay_cairo_surface(surf, 0, 0) f.overlay_cairo_surface(surf, 0, 0)
surf = cairo.image_surface_create(200, 200, "rgb24") --surf = cairo.image_surface_create(200, 200, "rgb24")
raster.pixel_value_map(surf, "rand =t0 t0 =R t0 =G t0 =B") --raster.pixel_value_map(surf, "rand =t0 t0 =R t0 =G t0 =B")
f.overlay_cairo_surface(surf, 20, 20) --f.overlay_cairo_surface(surf, 20, 20)
end end

View file

@ -763,6 +763,73 @@ static int pixel_value_map(lua_State *L)
} }
static int pixel_coord_map(lua_State *L)
{
cairo_surface_t *surf = CheckSurface(L, 1);
const char *program = luaL_checkstring(L, 2);
// Set up engine specs
ExpressionEngine::Specification spec;
spec.registers.resize(2);
spec.registers[0] = "X";
spec.registers[1] = "Y";
// Compile program
ExpressionEngine::Machine machine;
try {
machine = ExpressionEngine::Machine(spec, program);
}
catch (const char *e) {
// This is a parse error
luaL_error(L, "Error in expression program near\"%s\"", e);
}
// Init image
cairo_surface_flush(surf);
int width = cairo_image_surface_get_width(surf);
int height = cairo_image_surface_get_height(surf);
ptrdiff_t stride = (ptrdiff_t)cairo_image_surface_get_stride(surf);
unsigned char *data = cairo_image_surface_get_data(surf);
cairo_format_t format = cairo_image_surface_get_format(surf);
unsigned char *work = new unsigned char[height * stride];
memcpy(work, data, height*stride);
if (format == CAIRO_FORMAT_ARGB32) {
BaseImage<PixelFormat::cairo_argb32> simg(width, height, stride, work);
BaseImage<PixelFormat::cairo_argb32> dimg(width, height, stride, data);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
machine.registers[0] = x;
machine.registers[1] = y;
machine.Run();
dimg.Pixel(x, y) = GetPixelBilinear<PixelFormat::cairo_argb32, EdgeCondition::Mirror<PixelFormat::cairo_argb32> >(simg, machine.registers[0], machine.registers[1]);
}
}
}
else if (format == CAIRO_FORMAT_RGB24) {
BaseImage<PixelFormat::cairo_rgb24> simg(width, height, stride, work);
BaseImage<PixelFormat::cairo_rgb24> dimg(width, height, stride, data);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
machine.registers[0] = x;
machine.registers[1] = y;
machine.Run();
dimg.Pixel(x, y) = GetPixelBilinear<PixelFormat::cairo_rgb24, EdgeCondition::Mirror<PixelFormat::cairo_rgb24> >(simg, machine.registers[0], machine.registers[1]);
}
}
}
else {
luaL_error(L, "Unsupported pixel format");
}
delete[] work;
cairo_surface_mark_dirty(surf);
return 0;
}
// Registration // Registration
static luaL_Reg rasterlib[] = { static luaL_Reg rasterlib[] = {
@ -770,7 +837,7 @@ static luaL_Reg rasterlib[] = {
{"directional_blur", directional_blur}, {"radial_blur", radial_blur}, {"directional_blur", directional_blur}, {"radial_blur", radial_blur},
{"separable_filter", separable_filter}, {"separable_filter", separable_filter},
{"invert", invert_image}, {"invert", invert_image},
{"pixel_value_map", pixel_value_map}, {"pixel_value_map", pixel_value_map}, {"pixel_coord_map", pixel_coord_map},
{NULL, NULL} {NULL, NULL}
}; };