/* 2D RGB image convolution */
imconv(f, k, shape)
{
local c, rr, gg, bb, kr, kg, kb, ka, dx, dy, alpha = 0;
local r, g, b, a;
if (argc < 3)
{
if (argc < 2) error("imconv - input image and kernel required");
shape = "same";
}
if (rgbimage(f))
{
(r, g, b, a) = getrgb(f);
if (imhasalpha(f))
{
/* factor out alpha */
r /= a;
g /= a;
b /= a;
alpha = 1;
}
if (rgbimage(k))
{
/* kernel is an image */
(kr, kg, kb) = getrgb(k);
rr = conv2d(r, kr, shape);
gg = conv2d(g, kg, shape);
bb = conv2d(b, kb, shape);
}
else
{
/* numeric kernel */
rr = conv2d(r, k, shape);
gg = conv2d(g, k, shape);
bb = conv2d(b, k, shape);
}
/* rescale result */
rr = rescale(rr, 0, 1, 0, 1);
gg = rescale(gg, 0, 1, 0, 1);
bb = rescale(bb, 0, 1, 0, 1);
if (alpha)
{
rr *= a;
gg *= a;
bb *= a;
}
if (outargc > 1)
{
/* return individual components */
return(rr, gg, bb, a);
}
else
{
/* return 24 bit image */
c = alpha ? rgbimage(rr, gg, bb, a) : rgbimage(rr, gg, bb);
dx = rr.deltax;
dy = rr.deltay;
if (dx == gg.deltax && dx == bb.deltax &&
dy == gg.deltay && dy == bb.deltay)
{
c.deltax = dx;
c.deltay = dy;
}
return(c);
}
}
else
{
/* standard 2D convolution */
c = conv2d(f, k, shape);
return(c);
}
}