Commit | Line | Data |
---|---|---|
01140725 | 1 | #define IMAGER_NO_CONTEXT |
92bda632 | 2 | #include "imager.h" |
6a3cbaef | 3 | #include "imageri.h" |
02d1d628 AMH |
4 | |
5 | /* | |
6 | General convolution for 2d decoupled filters | |
7 | end effects are acounted for by increasing | |
8 | scaling the result with the sum of used coefficients | |
9 | ||
8d14daab | 10 | coeff: (double array) coefficients for filter |
02d1d628 AMH |
11 | len: length of filter.. number of coefficients |
12 | note that this has to be an odd number | |
13 | (since the filter is even); | |
14 | */ | |
15 | ||
6a3cbaef TC |
16 | int |
17 | i_conv(i_img *im, const double *coeff,int len) { | |
8d14daab | 18 | i_img_dim xo, yo; /* output pixel co-ordinate */ |
6a3cbaef | 19 | int c, ch, center; |
bd8052a6 | 20 | double pc; |
6a3cbaef | 21 | double res[MAXCHANNELS]; |
bd8052a6 | 22 | i_img *timg; |
01140725 | 23 | dIMCTXim(im); |
02d1d628 | 24 | |
01140725 TC |
25 | im_log((aIMCTX,1,"i_conv(im %p, coeff %p, len %d)\n",im,coeff,len)); |
26 | im_clear_error(aIMCTX); | |
1e0418f1 TC |
27 | |
28 | if (len < 1) { | |
01140725 | 29 | im_push_error(aIMCTX, 0, "there must be at least one coefficient"); |
1e0418f1 TC |
30 | return 0; |
31 | } | |
02d1d628 | 32 | |
02d1d628 AMH |
33 | center=(len-1)/2; |
34 | ||
6a3cbaef TC |
35 | pc = 0; |
36 | for (c = 0; c < len; ++c) | |
37 | pc += coeff[c]; | |
38 | ||
39 | if (pc == 0) { | |
40 | i_push_error(0, "sum of coefficients is zero"); | |
41 | return 0; | |
42 | } | |
43 | ||
44 | timg = i_sametype(im, im->xsize, im->ysize); | |
45 | ||
bd8052a6 TC |
46 | #code im->bits <= 8 |
47 | IM_COLOR rcolor; | |
6e473a59 TC |
48 | /* don't move the calculation of pc up here, it depends on which pixels |
49 | are readable */ | |
6a3cbaef TC |
50 | for(yo = 0; yo < im->ysize; yo++) { |
51 | for(xo = 0; xo < im->xsize; xo++) { | |
52 | for(ch = 0;ch < im->channels; ch++) | |
53 | res[ch] = 0; | |
54 | for(c = 0;c < len; c++) { | |
8d14daab | 55 | i_img_dim xi = xo + c - center; |
6a3cbaef TC |
56 | if (xi < 0) |
57 | xi = 0; | |
58 | else if (xi >= im->xsize) | |
59 | xi = im->xsize - 1; | |
60 | ||
61 | if (IM_GPIX(im, xi, yo, &rcolor)!=-1) { | |
62 | for(ch = 0; ch < im->channels; ch++) | |
63 | res[ch] += (rcolor.channel[ch]) *coeff[c]; | |
02d1d628 | 64 | } |
6a3cbaef TC |
65 | } |
66 | im_assert(pc != 0); | |
67 | for(ch = 0; ch < im->channels; ch++) { | |
68 | double temp = res[ch] / pc; | |
0b76fec8 | 69 | rcolor.channel[ch] = |
bd8052a6 | 70 | temp < 0 ? 0 : temp > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : (IM_SAMPLE_T)temp; |
0b76fec8 | 71 | } |
6a3cbaef | 72 | IM_PPIX(timg, xo, yo, &rcolor); |
02d1d628 AMH |
73 | } |
74 | } | |
75 | ||
6a3cbaef TC |
76 | for(xo = 0; xo < im->xsize; xo++) { |
77 | for(yo = 0;yo < im->ysize; yo++) { | |
78 | for(ch = 0; ch < im->channels; ch++) | |
79 | res[ch] = 0; | |
80 | for(c = 0; c < len; c++) { | |
8d14daab | 81 | i_img_dim yi = yo + c - center; |
6a3cbaef TC |
82 | if (yi < 0) |
83 | yi = 0; | |
84 | else if (yi >= im->ysize) | |
85 | yi = im->ysize - 1; | |
86 | if (IM_GPIX(timg, xo, yi, &rcolor) != -1) { | |
87 | for(ch = 0;ch < im->channels; ch++) | |
88 | res[ch] += (rcolor.channel[ch]) * coeff[c]; | |
02d1d628 | 89 | } |
bd8052a6 | 90 | } |
6a3cbaef TC |
91 | im_assert(pc != 0); |
92 | for(ch = 0;ch < im->channels; ch++) { | |
93 | double temp = res[ch] / pc; | |
94 | rcolor.channel[ch] = | |
bd8052a6 TC |
95 | temp < 0 ? 0 : temp > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : (IM_SAMPLE_T)temp; |
96 | } | |
6a3cbaef | 97 | IM_PPIX(im, xo, yo,&rcolor); |
02d1d628 | 98 | } |
bd8052a6 TC |
99 | } |
100 | #/code | |
101 | ||
102 | i_img_destroy(timg); | |
02d1d628 | 103 | |
6a3cbaef TC |
104 | return 1; |
105 | } |