#include "imager.h" #include static double gauss(int x, double std) { return 1.0/(sqrt(2.0*PI)*std)*exp(-(double)(x)*(float)(x)/(2*std*std)); } /* Counters are as follows l: lines i: columns c: filter coeffs ch: channels pc: coeff equalization */ int i_gaussian(i_img *im, double stddev) { int i,l,c,ch; double pc; double *coeff; double res[MAXCHANNELS]; i_img *timg; int radius, diameter; mm_log((1,"i_gaussian(im %p, stdev %.2f)\n",im,stddev)); i_clear_error(); if (stddev <= 0) { i_push_error(0, "stddev must be positive"); return 0; } /* totally silly cutoff */ if (stddev > 1000) { stddev = 1000; } timg = i_sametype(im, im->xsize, im->ysize); if (im->bits <= 8) radius = ceil(2 * stddev); else radius = ceil(3 * stddev); diameter = 1 + radius * 2; coeff = mymalloc(sizeof(double) * diameter); for(i=0;i <= radius;i++) coeff[radius + i]=coeff[radius - i]=gauss(i, stddev); pc=0; for(i=0; i < diameter; i++) pc+=coeff[i]; for(i=0;i < diameter;i++) coeff[i] /= pc; #code im->bits <= 8 IM_COLOR rcolor; for(l=0;lysize;l++) { for(i=0;ixsize;i++) { pc=0.0; for(ch=0;chchannels;ch++) res[ch]=0; for(c = 0;c < diameter; c++) if (IM_GPIX(im,i+c-radius,l,&rcolor)!=-1) { for(ch=0;chchannels;ch++) res[ch]+= rcolor.channel[ch] * coeff[c]; pc+=coeff[c]; } for(ch=0;chchannels;ch++) { double value = res[ch] / pc; rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value); } IM_PPIX(timg,i,l,&rcolor); } } for(l=0;lxsize;l++) { for(i=0;iysize;i++) { pc=0.0; for(ch=0; chchannels; ch++) res[ch]=0; for(c=0; c < diameter; c++) if (IM_GPIX(timg,l,i+c-radius,&rcolor)!=-1) { for(ch=0;chchannels;ch++) res[ch]+= rcolor.channel[ch] * coeff[c]; pc+=coeff[c]; } for(ch=0;chchannels;ch++) { double value = res[ch]/pc; rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value); } IM_PPIX(im,l,i,&rcolor); } } #/code myfree(coeff); i_img_destroy(timg); return 1; }