remove a pointless NULL check from i_flipxy()
[imager.git] / gaussian.im
CommitLineData
e215ad76 1#define IMAGER_NO_CONTEXT
73962964
TC
2#include "imager.h"
3#include <math.h>
4
5static double
6gauss(int x, double std) {
8d14daab 7 return 1.0/(sqrt(2.0*PI)*std)*exp(-(double)(x)*(double)(x)/(2*std*std));
73962964
TC
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
20int
21i_gaussian(i_img *im, double stddev) {
8d14daab
TC
22 int i, c, ch;
23 i_img_dim x, y;
73962964
TC
24 double pc;
25 double *coeff;
26 double res[MAXCHANNELS];
27 i_img *timg;
28 int radius, diameter;
e215ad76 29 dIMCTXim(im);
73962964 30
e215ad76 31 im_log((aIMCTX, 1,"i_gaussian(im %p, stdev %.2f)\n",im,stddev));
73962964
TC
32 i_clear_error();
33
34 if (stddev <= 0) {
35 i_push_error(0, "stddev must be positive");
36 return 0;
37 }
38 /* totally silly cutoff */
39 if (stddev > 1000) {
40 stddev = 1000;
41 }
42
43 timg = i_sametype(im, im->xsize, im->ysize);
44
45 if (im->bits <= 8)
46 radius = ceil(2 * stddev);
47 else
48 radius = ceil(3 * stddev);
49
50 diameter = 1 + radius * 2;
51
52 coeff = mymalloc(sizeof(double) * diameter);
53
54 for(i=0;i <= radius;i++)
55 coeff[radius + i]=coeff[radius - i]=gauss(i, stddev);
56 pc=0;
57 for(i=0; i < diameter; i++)
58 pc+=coeff[i];
59 for(i=0;i < diameter;i++)
60 coeff[i] /= pc;
61
62
63#code im->bits <= 8
64 IM_COLOR rcolor;
8d14daab
TC
65 for(y = 0; y < im->ysize; y++) {
66 for(x = 0; x < im->xsize; x++) {
73962964
TC
67 pc=0.0;
68 for(ch=0;ch<im->channels;ch++)
69 res[ch]=0;
70 for(c = 0;c < diameter; c++)
8d14daab 71 if (IM_GPIX(im,x+c-radius,y,&rcolor)!=-1) {
73962964
TC
72 for(ch=0;ch<im->channels;ch++)
73 res[ch]+= rcolor.channel[ch] * coeff[c];
74 pc+=coeff[c];
75 }
76 for(ch=0;ch<im->channels;ch++) {
77 double value = res[ch] / pc;
bd8052a6 78 rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value);
73962964 79 }
8d14daab 80 IM_PPIX(timg, x, y, &rcolor);
73962964
TC
81 }
82 }
83
8d14daab
TC
84 for(x = 0;x < im->xsize; x++) {
85 for(y = 0; y < im->ysize; y++) {
73962964
TC
86 pc=0.0;
87 for(ch=0; ch<im->channels; ch++)
88 res[ch]=0;
89 for(c=0; c < diameter; c++)
8d14daab 90 if (IM_GPIX(timg, x, y+c-radius, &rcolor)!=-1) {
73962964
TC
91 for(ch=0;ch<im->channels;ch++)
92 res[ch]+= rcolor.channel[ch] * coeff[c];
93 pc+=coeff[c];
94 }
95 for(ch=0;ch<im->channels;ch++) {
96 double value = res[ch]/pc;
bd8052a6 97 rcolor.channel[ch] = value > IM_SAMPLE_MAX ? IM_SAMPLE_MAX : IM_ROUND(value);
73962964 98 }
8d14daab 99 IM_PPIX(im, x, y, &rcolor);
73962964
TC
100 }
101 }
102#/code
103 myfree(coeff);
104 i_img_destroy(timg);
105
106 return 1;
107}
108
109
110
111
112
113
114