]> git.imager.perl.org - imager.git/blob - conv.c
This is primarily a feature release:
[imager.git] / conv.c
1 #include "imager.h"
2
3 /*
4   General convolution for 2d decoupled filters
5   end effects are acounted for by increasing
6   scaling the result with the sum of used coefficients
7
8   coeff: (float array) coefficients for filter
9     len: length of filter.. number of coefficients
10            note that this has to be an odd number
11            (since the filter is even);
12 */
13
14 void
15 i_conv(i_img *im,const float *coeff,int len) {
16   int i,l,c,ch,center;
17   float pc;
18   i_color rcolor;
19   float res[11];
20   i_img timg;
21
22   mm_log((1,"i_conv(im %p, coeff %p, len %d)\n",im,coeff,len));
23  
24   i_img_empty_ch(&timg,im->xsize,im->ysize,im->channels);
25
26   center=(len-1)/2;
27
28   /* don't move the calculation of pc up here, it depends on which pixels
29      are readable */
30   for(l=0;l<im->ysize;l++) {
31     for(i=0;i<im->xsize;i++) {
32       pc=0.0;
33       for(ch=0;ch<im->channels;ch++) res[ch]=0;
34       for(c=0;c<len;c++)
35         if (i_gpix(im,i+c-center,l,&rcolor)!=-1) {
36           for(ch=0;ch<im->channels;ch++) 
37             res[ch]+=(float)(rcolor.channel[ch])*coeff[c];
38           pc+=coeff[c];
39         }
40       for(ch=0;ch<im->channels;ch++) {
41         double temp = res[ch]/pc;
42         rcolor.channel[ch] = 
43           temp < 0 ? 0 : temp > 255 ? 255 : (unsigned char)temp;
44       }
45       i_ppix(&timg,i,l,&rcolor);
46     }
47   }
48
49   for(l=0;l<im->xsize;l++)
50     {
51       for(i=0;i<im->ysize;i++)
52         {
53           pc=0.0;
54           for(ch=0;ch<im->channels;ch++) res[ch]=0;
55           for(c=0;c<len;c++)
56             if (i_gpix(&timg,l,i+c-center,&rcolor)!=-1)
57               {
58                 for(ch=0;ch<im->channels;ch++) 
59                   res[ch]+=(float)(rcolor.channel[ch])*coeff[c];
60                 pc+=coeff[c];
61               }
62           for(ch=0;ch<im->channels;ch++) {
63             double temp = res[ch]/pc;
64             rcolor.channel[ch]= 
65               temp < 0 ? 0 : temp > 255 ? 255 : (unsigned char)temp;
66           }
67           i_ppix(im,l,i,&rcolor);
68         }
69     }
70   i_img_exorcise(&timg);
71 }
72
73
74
75
76
77
78
79
80