File Coverage

gaussian.im
Criterion Covered Total %
statement 102 110 92.7
branch 94 104 90.3
condition n/a
subroutine n/a
pod n/a
total 196 214 91.5


line stmt bran cond sub pod time code
1             #define IMAGER_NO_CONTEXT
2             #include "imager.h"
3             #include
4              
5             static double
6 101           gauss(int x, double std) {
7 101           return 1.0/(sqrt(2.0*PI)*std)*exp(-(double)(x)*(double)(x)/(2*std*std));
8             }
9              
10             /* Counters are as follows
11             l: lines
12             i: columns
13             c: filter coeffs
14             ch: channels
15             pc: coeff equalization
16             */
17              
18              
19              
20             int
21 3           i_gaussian(i_img *im, double stddev) {
22 3           return i_gaussian2( im, stddev, stddev );
23             }
24              
25             typedef struct s_gauss_coeff {
26             int diameter;
27             int radius;
28             double *coeff;
29             } t_gauss_coeff;
30              
31            
32 10           static t_gauss_coeff *build_coeff( i_img *im, double stddev ) {
33 10           double *coeff = NULL;
34             double pc;
35             int radius, diameter, i;
36 10           t_gauss_coeff *ret = mymalloc(sizeof(struct s_gauss_coeff));
37 10           ret->coeff = NULL;
38              
39 10 100         if (im->bits <= 8)
40 5           radius = ceil(2 * stddev);
41             else
42 5           radius = ceil(3 * stddev);
43              
44 10           diameter = 1 + radius * 2;
45              
46 10           coeff = mymalloc(sizeof(double) * diameter);
47              
48 111 100         for(i=0;i <= radius;i++)
49 101           coeff[radius + i]=coeff[radius - i]=gauss(i, stddev);
50 10           pc=0.0;
51 202 100         for(i=0; i < diameter; i++)
52 192           pc+=coeff[i];
53 202 100         for(i=0;i < diameter;i++) {
54 192           coeff[i] /= pc;
55             // im_log((aIMCTX, 1, "i_gaussian2 Y i=%i coeff=%.2f\n", i, coeff[i] ));
56             }
57              
58 10           ret->diameter = diameter;
59 10           ret->radius = radius;
60 10           ret->coeff = coeff;
61 10           return ret;
62             }
63              
64 10           static void free_coeff(t_gauss_coeff *co ) {
65              
66 10 50         if( co->coeff != NULL )
67 10           myfree( co->coeff );
68 10           myfree( co );
69 10           }
70              
71             #define img_copy(dest, src) i_copyto( (dest), (src), 0,0, (src)->xsize,(src)->ysize, 0,0);
72              
73              
74              
75             int
76 8           i_gaussian2(i_img *im, double stddevX, double stddevY) {
77             int c, ch;
78             i_img_dim x, y;
79             double pc;
80 8           t_gauss_coeff *co = NULL;
81             double res[MAXCHANNELS];
82             i_img *timg;
83             i_img *yin;
84             i_img *yout;
85 8           dIMCTXim(im);
86              
87 8           im_log((aIMCTX, 1,"i_gaussian2(im %p, stddev %.2f,%.2f)\n",im,stddevX,stddevY));
88 8           i_clear_error();
89              
90 8 50         if (stddevX < 0) {
91 0           i_push_error(0, "stddevX must be positive");
92 0           return 0;
93             }
94 8 50         if (stddevY < 0) {
95 0           i_push_error(0, "stddevY must be positive");
96 0           return 0;
97             }
98              
99 8 100         if( stddevX == stddevY && stddevY == 0 ) {
    50          
100 0           i_push_error(0, "stddevX or stddevY must be positive");
101 0           return 0;
102             }
103              
104              
105             /* totally silly cutoff */
106 8 50         if (stddevX > 1000) {
107 0           stddevX = 1000;
108             }
109 8 50         if (stddevY > 1000) {
110 0           stddevY = 1000;
111             }
112              
113 8           timg = i_sametype(im, im->xsize, im->ysize);
114              
115 8 100         if( stddevX > 0 ) {
116             /* Build Y coefficient matrix */
117 7           co = build_coeff( im, stddevX );
118 7           im_log((aIMCTX, 1, "i_gaussian2 X coeff radius=%i diamter=%i coeff=%p\n", co->radius, co->diameter, co->coeff));
119              
120             /******************/
121             /* Process X blur */
122 7           im_log((aIMCTX, 1, "i_gaussian2 X blur from im=%p to timg=%p\n", im, timg));
123              
124 7 100         #code im->bits <= 8
125             IM_COLOR rcolor;
126              
127 1057 100         for(y = 0; y < im->ysize; y++) {
    100          
128 158550 100         for(x = 0; x < im->xsize; x++) {
    100          
129 157500           pc=0.0;
130 630000 100         for(ch=0;chchannels;ch++)
    100          
131 472500           res[ch]=0;
132 3240000 100         for(c = 0;c < co->diameter; c++)
    100          
133 3082500 100         if (IM_GPIX(im,x+c-co->radius,y,&rcolor)!=-1) {
    100          
134 11830800 100         for(ch=0;chchannels;ch++)
    100          
135 8873100           res[ch]+= rcolor.channel[ch] * co->coeff[c];
136 2957700           pc+=co->coeff[c];
137             }
138 630000 100         for(ch=0;chchannels;ch++) {
    100          
139 472500           double value = res[ch] / pc;
140 472500 100         rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value);
    50          
141             }
142 157500           IM_PPIX(timg, x, y, &rcolor);
143             }
144             }
145             #/code
146             /* processing is im -> timg=yin -> im=yout */
147 7           yin = timg;
148 7           yout = im;
149             }
150             else {
151 1           im_log((aIMCTX, 1, "i_gaussian2 X coeff is unity\n"));
152              
153             /* processing is im=yin -> timg=yout -> im */
154 1           yin = im;
155 1           yout = timg;
156             }
157            
158 8 100         if( stddevY > 0 ) {
159 7 100         if( stddevX != stddevY ) {
160 3 100         if( co != NULL ) {
161 2           free_coeff(co);
162 2           co = NULL;
163             }
164              
165             /* Build Y coefficient matrix */
166 3           co = build_coeff( im, stddevY );
167 3           im_log((aIMCTX, 1, "i_gaussian2 Y coeff radius=%i diamter=%i coeff=%p\n", co->radius, co->diameter, co->coeff));
168             }
169              
170             /******************/
171             /* Process Y blur */
172 7           im_log((aIMCTX, 1, "i_gaussian2 Y blur from yin=%p to yout=%p\n", yin, yout));
173 7 100         #code im->bits <= 8
174             IM_COLOR rcolor;
175 1057 100         for(x = 0;x < im->xsize; x++) {
    100          
176 158550 100         for(y = 0; y < im->ysize; y++) {
    100          
177 157500           pc=0.0;
178 630000 100         for(ch=0; chchannels; ch++)
    100          
179 472500           res[ch]=0;
180 3240000 100         for(c=0; c < co->diameter; c++)
    100          
181 3082500 100         if (IM_GPIX(yin, x, y+c-co->radius, &rcolor)!=-1) {
    100          
182 11830800 100         for(ch=0;chchannels;ch++)
    100          
183 8873100           res[ch]+= rcolor.channel[ch] * co->coeff[c];
184 2957700           pc+=co->coeff[c];
185             }
186 630000 100         for(ch=0;chchannels;ch++) {
    100          
187 472500           double value = res[ch]/pc;
188 472500 100         rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value);
    50          
189             }
190 157500           IM_PPIX(yout, x, y, &rcolor);
191             }
192             }
193             #/code
194 7 100         if( im != yout ) {
195 1           im_log((aIMCTX, 1, "i_gaussian2 copying yout=%p to im=%p\n", yout, im));
196 7           img_copy( im, yout );
197             }
198             }
199             else {
200 1           im_log((aIMCTX, 1, "i_gaussian2 Y coeff is unity\n"));
201 1 50         if( yin == timg ) {
202 1           im_log((aIMCTX, 1, "i_gaussian2 copying timg=%p to im=%p\n", timg, im));
203 1           img_copy( im, timg );
204             }
205             }
206              
207 8           im_log((aIMCTX, 1, "i_gaussian2 im=%p\n", im));
208 8           im_log((aIMCTX, 1, "i_gaussian2 timg=%p\n", timg));
209 8           im_log((aIMCTX, 1, "i_gaussian2 yin=%p\n", yin));
210 8           im_log((aIMCTX, 1, "i_gaussian2 yout=%p\n", yout));
211              
212 8 50         if( co != NULL )
213 8           free_coeff(co);
214              
215 8           i_img_destroy(timg);
216            
217 8           return 1;
218             }
219              
220              
221              
222              
223              
224              
225