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
|
|
|
|
|
|
|
|