]> git.imager.perl.org - imager.git/blob - conv.im
move t1lib font support to a separate module
[imager.git] / conv.im
1 #include "imager.h"
2 #include "imageri.h"
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
15 int
16 i_conv(i_img *im, const double *coeff,int len) {
17   int xo, yo; /* output pixel co-ordinate */
18   int c, ch, center;
19   double pc;
20   double res[MAXCHANNELS];
21   i_img *timg;
22
23   mm_log((1,"i_conv(im %p, coeff %p, len %d)\n",im,coeff,len));
24   i_clear_error();
25  
26   center=(len-1)/2;
27
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
39 #code im->bits <= 8
40   IM_COLOR rcolor;
41   /* don't move the calculation of pc up here, it depends on which pixels
42      are readable */
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];
57         }
58       }
59       im_assert(pc != 0);
60       for(ch = 0; ch < im->channels; ch++) {
61         double temp = res[ch] / pc;
62         rcolor.channel[ch] = 
63           temp < 0 ? 0 : temp > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : (IM_SAMPLE_T)temp;
64       }
65       IM_PPIX(timg, xo, yo, &rcolor);
66     }
67   }
68
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];
82         }
83       }
84       im_assert(pc != 0);
85       for(ch = 0;ch < im->channels; ch++) {
86         double temp = res[ch] / pc;
87         rcolor.channel[ch] = 
88           temp < 0 ? 0 : temp > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : (IM_SAMPLE_T)temp;
89       }
90       IM_PPIX(im, xo, yo,&rcolor);
91     }
92   }
93 #/code
94
95   i_img_destroy(timg);
96
97   return 1;
98 }