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