forked from mia/Aegisub
Add raster.separable_filter function.
Originally committed to SVN as r1483.
This commit is contained in:
parent
dad6f7755b
commit
17f235515e
3 changed files with 53 additions and 2 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue