Add raster.separable_filter function.

Originally committed to SVN as r1483.
This commit is contained in:
Niels Martin Hansen 2007-08-13 14:56:02 +00:00
parent dad6f7755b
commit 17f235515e
3 changed files with 53 additions and 2 deletions

View file

@ -161,6 +161,22 @@ For RGB24 surfaces, all channels are inverted.
For A8 and A1 surfaces the alpha is inverted. For A8 and A1 surfaces the alpha is inverted.
raster.separable_filter(surface, filter, divisor)
Apply a custom separable filter over the image.
The filter must be a table of integers. After the convoluted value of each
pixel is calculated, it is divided by divisor before it's stored back to the
image.
Note that this function can only work on integers, floating point values in
the filter or divisor will be rounded first. To get higher precision, scale
up the filter and divisor. (Treat it as fixed-point math.)
The filter is one-dimensional, but is applied first horizontally and then
vertically ovre the image to get the final image.
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

@ -1,6 +1,7 @@
function render_frame(f, t) function render_frame(f, t)
local surf = f.create_cairo_surface() local surf = f.create_cairo_surface()
raster.gaussian_blur(surf, t)--1+(1-math.cos(t*10))*2) --raster.gaussian_blur(surf, t)--1+(1-math.cos(t*10))*2)
raster.invert(surf) --raster.invert(surf)
raster.separable_filter(surf, {-1, 3, -1}, 1)
f.overlay_cairo_surface(surf, 0, 0) f.overlay_cairo_surface(surf, 0, 0)
end end

View file

@ -408,10 +408,44 @@ static int invert_image(lua_State *L)
} }
static int separable_filter(lua_State *L)
{
cairo_surface_t *surf = CheckSurface(L, 1);
if (!lua_istable(L, 2)) {
luaL_error(L, "Expected table as second argument to raster.separable_filter, got %s", luaL_typename(L, 2));
return 0;
}
int divisor = luaL_checkint(L, 3);
int width = (int)lua_objlen(L, 2);
if (width < 1) {
luaL_error(L, "Cannot apply empty filter");
return 0;
}
int *kernel = new int[width];
int i = 0;
lua_pushnil(L);
while (lua_next(L, 2)) {
if (lua_isnumber(L, -1)) {
kernel[i] = (int)lua_tointeger(L, -1);
}
i++;
lua_pop(L, 1);
}
ApplySeparableFilter(L, surf, kernel, width, divisor);
delete[] kernel;
return 0;
}
// Registration // Registration
static luaL_Reg rasterlib[] = { static luaL_Reg rasterlib[] = {
{"gaussian_blur", gaussian_blur}, {"box_blur", box_blur}, {"gaussian_blur", gaussian_blur}, {"box_blur", box_blur},
{"separable_filter", separable_filter},
{"invert", invert_image}, {"invert", invert_image},
{NULL, NULL} {NULL, NULL}
}; };