View Raw SPL
/* 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);
        }
}