CRIMP
convolve-float-hsv.crimp at [33c5c1beda]
Not logged in

File operator/convolve-float-hsv.crimp artifact bb525c7aa3 part of check-in 33c5c1beda


convolve_float_hsv
Tcl_Obj* imageObj
Tcl_Obj* kernelImageObj
int scale
int offset

/*
 * Generic convolution operator. The kernel to convole with is specified as a
 * floating-point image together with a scaling factor. This way we do not
 * need a separate matrix Tcl_ObjType.
 *
 * This convolver should be used only for small kernels, as it uses direct
 * convolution. For larger kernels it is planned to provide an FFT based
 * convolver.
 */

crimp_image*     result;
crimp_image*     image;
crimp_image*     kernel;
int              xo, yo, xi, yi, xk, yk, dx, dy, kw, kh;

crimp_input (imageObj,         image,    hsv);
crimp_input (kernelImageObj,   kernel,   float);

if (((crimp_w (kernel) % 2) == 0) ||
    ((crimp_h (kernel) % 2) == 0)) {
    Tcl_SetResult(interp, "bad kernel dimensions, expected odd size", TCL_STATIC);
    return TCL_ERROR;
}

kw = crimp_w (kernel)/2;
kh = crimp_h (kernel)/2;

result = crimp_new_at (image->itype, crimp_x (image) + kw, crimp_y (image) + kh, crimp_w (image) - 2*kw, crimp_h (image) - 2*kh);

for (yo = 0, yi = kh; yo < crimp_h (result); yo++, yi++) {
    for (xo = 0, xi = kw; xo < crimp_w (result); xo++, xi++) {

	/*
	 * We convolve all channels with the same kernel, but otherwise
	 * identically
	 */

	double sumh = 0; int isumh;
	double sums = 0; int isums;
	double sumv = 0; int isumv;

	for (yk = 0, dy = -kh; yk < crimp_h (kernel); yk++, dy++) {
	    for (xk = 0, dx = -kw; xk < crimp_w (kernel); xk++, dx++) {

		sumh += FLOATP (kernel, xk, yk) * H (image, xi-dx, yi-dy);
		sums += FLOATP (kernel, xk, yk) * S (image, xi-dx, yi-dy);
		sumv += FLOATP (kernel, xk, yk) * V (image, xi-dx, yi-dy);
	    }
	}

	sumh /= scale; sumh += offset; isumh = sumh; H (result, xo, yo) = CLAMP (0, isumh, 255);
	sums /= scale; sums += offset; isums = sums; S (result, xo, yo) = CLAMP (0, isums, 255);
	sumv /= scale; sumv += offset; isumv = sumv; V (result, xo, yo) = CLAMP (0, isumv, 255);
    }
}

Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;


/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */