]> git.imager.perl.org - imager.git/blame - gaussian.im
planning too far ahead
[imager.git] / gaussian.im
CommitLineData
73962964
TC
1#include "imager.h"
2#include <math.h>
3
4static double
5gauss(int x, double std) {
6 return 1.0/(sqrt(2.0*PI)*std)*exp(-(double)(x)*(float)(x)/(2*std*std));
7}
8
9/* Counters are as follows
10 l: lines
11 i: columns
12 c: filter coeffs
13 ch: channels
14 pc: coeff equalization
15*/
16
17
18
19int
20i_gaussian(i_img *im, double stddev) {
21 int i,l,c,ch;
22 double pc;
23 double *coeff;
24 double res[MAXCHANNELS];
25 i_img *timg;
26 int radius, diameter;
27
28 mm_log((1,"i_gaussian(im %p, stdev %.2f)\n",im,stddev));
29 i_clear_error();
30
31 if (stddev <= 0) {
32 i_push_error(0, "stddev must be positive");
33 return 0;
34 }
35 /* totally silly cutoff */
36 if (stddev > 1000) {
37 stddev = 1000;
38 }
39
40 timg = i_sametype(im, im->xsize, im->ysize);
41
42 if (im->bits <= 8)
43 radius = ceil(2 * stddev);
44 else
45 radius = ceil(3 * stddev);
46
47 diameter = 1 + radius * 2;
48
49 coeff = mymalloc(sizeof(double) * diameter);
50
51 for(i=0;i <= radius;i++)
52 coeff[radius + i]=coeff[radius - i]=gauss(i, stddev);
53 pc=0;
54 for(i=0; i < diameter; i++)
55 pc+=coeff[i];
56 for(i=0;i < diameter;i++)
57 coeff[i] /= pc;
58
59
60#code im->bits <= 8
61 IM_COLOR rcolor;
62 for(l=0;l<im->ysize;l++) {
63 for(i=0;i<im->xsize;i++) {
64 pc=0.0;
65 for(ch=0;ch<im->channels;ch++)
66 res[ch]=0;
67 for(c = 0;c < diameter; c++)
68 if (IM_GPIX(im,i+c-radius,l,&rcolor)!=-1) {
69 for(ch=0;ch<im->channels;ch++)
70 res[ch]+= rcolor.channel[ch] * coeff[c];
71 pc+=coeff[c];
72 }
73 for(ch=0;ch<im->channels;ch++) {
74 double value = res[ch] / pc;
75 rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : value;
76 }
77 IM_PPIX(timg,i,l,&rcolor);
78 }
79 }
80
81 for(l=0;l<im->xsize;l++) {
82 for(i=0;i<im->ysize;i++) {
83 pc=0.0;
84 for(ch=0; ch<im->channels; ch++)
85 res[ch]=0;
86 for(c=0; c < diameter; c++)
87 if (IM_GPIX(timg,l,i+c-radius,&rcolor)!=-1) {
88 for(ch=0;ch<im->channels;ch++)
89 res[ch]+= rcolor.channel[ch] * coeff[c];
90 pc+=coeff[c];
91 }
92 for(ch=0;ch<im->channels;ch++) {
93 double value = res[ch]/pc;
94 rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : value;
95 }
96 IM_PPIX(im,l,i,&rcolor);
97 }
98 }
99#/code
100 myfree(coeff);
101 i_img_destroy(timg);
102
103 return 1;
104}
105
106
107
108
109
110
111