ETL  0.04.19
_gaussian.h
Go to the documentation of this file.
1 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __ETL__GAUSSIAN_H
28 #define __ETL__GAUSSIAN_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include <cstring> // for memset()
33 #include <iterator>
34 
35 /* === M A C R O S ========================================================= */
36 
37 /* === T Y P E D E F S ===================================================== */
38 
39 /* === C L A S S E S & S T R U C T S ======================================= */
40 
42 
43 template<typename T> void
44 gaussian_blur_5x5_(T pen,int w, int h,
45 typename T::accumulator_pointer SC0,
46 typename T::accumulator_pointer SC1,
47 typename T::accumulator_pointer SC2,
48 typename T::accumulator_pointer SC3)
49 {
50  int x,y;
51  typename T::accumulator_type Tmp1,Tmp2,SR0,SR1,SR2,SR3;
52 
53  //typename T::iterator_x iter;
54 
55  // Setup the row buffers
56  for(x=0;x<w;x++)SC0[x+2]=(typename T::accumulator_type)(pen.x()[x])*24;
57  memset(SC1,0,(w+2)*sizeof(typename T::accumulator_type));
58  memset(SC2,0,(w+2)*sizeof(typename T::accumulator_type));
59  memset(SC3,0,(w+2)*sizeof(typename T::accumulator_type));
60 
61  for(y=0;y<h+2;y++,pen.inc_y())
62  {
63  int yadj;
64  if(y>=h)
65  {yadj=(h-y)-1; SR0=(typename T::accumulator_type)(pen.y()[yadj])*1.35;}
66  else
67  {yadj=0; SR0=(typename T::accumulator_type)(pen.get_value())*1.35; }
68 
69  SR1=SR2=SR3=typename T::accumulator_type();
70  for(x=0;x<w+2;x++,pen.inc_x())
71  {
72  if(x>=w)
73  Tmp1=(typename T::accumulator_type)(pen[yadj][(w-x)-1]);
74  else
75  Tmp1=(typename T::accumulator_type)(*pen[yadj]);
76 
77  Tmp2=SR0+Tmp1;
78  SR0=Tmp1;
79  Tmp1=SR1+Tmp2;
80  SR1=Tmp2;
81  Tmp2=SR2+Tmp1;
82  SR2=Tmp1;
83  Tmp1=SR3+Tmp2;
84  SR3=Tmp2;
85 
86  // Column Machine
87  Tmp2=SC0[x]+Tmp1;
88  SC0[x]=Tmp1;
89  Tmp1=SC1[x]+Tmp2;
90  SC1[x]=Tmp2;
91  Tmp2=SC2[x]+Tmp1;
92  SC2[x]=Tmp1;
93  if(y>1&&x>1)
94  pen[-2][-2]=(typename T::value_type)((SC3[x]+Tmp2)/256);
95  SC3[x]=Tmp2;
96  }
97  pen.dec_x(x);
98  }
99 
100 }
101 
102 template<typename T> void
103 gaussian_blur_5x5(T pen, int w, int h)
104 {
105  typename T::accumulator_pointer SC0=new typename T::accumulator_type[w+2];
106  typename T::accumulator_pointer SC1=new typename T::accumulator_type[w+2];
107  typename T::accumulator_pointer SC2=new typename T::accumulator_type[w+2];
108  typename T::accumulator_pointer SC3=new typename T::accumulator_type[w+2];
109 
110  gaussian_blur_5x5_(pen,w,h,SC0,SC1,SC2,SC3);
111 
112  delete [] SC0;
113  delete [] SC1;
114  delete [] SC2;
115  delete [] SC3;
116 }
117 
118 template<typename T> void
119 gaussian_blur_5x5(T begin, T end)
120 {
121  typename T::difference_type size(end-begin);
122 
123  typename T::accumulator_pointer SC0=new typename T::accumulator_type[size.x+2];
124  typename T::accumulator_pointer SC1=new typename T::accumulator_type[size.x+2];
125  typename T::accumulator_pointer SC2=new typename T::accumulator_type[size.x+2];
126  typename T::accumulator_pointer SC3=new typename T::accumulator_type[size.x+2];
127 
128  gaussian_blur_5x5_(begin,size.x,size.y,SC0,SC1,SC2,SC3);
129 
130  delete [] SC0;
131  delete [] SC1;
132  delete [] SC2;
133  delete [] SC3;
134 }
135 
136 template<typename T> void
137 gaussian_blur_3x3(T pen,int w, int h)
138 {
139  int x,y;
140  typename T::accumulator_type Tmp1,Tmp2,SR0,SR1;
141 
142 // typename T::iterator_x iter;
143 
144  typename T::accumulator_pointer SC0=new typename T::accumulator_type[w+1];
145  typename T::accumulator_pointer SC1=new typename T::accumulator_type[w+1];
146 
147  // Setup the row buffers
148  for(x=0;x<w;x++)SC0[x+1]=(typename T::accumulator_type)(pen.x()[x])*4;
149  memset(SC1,0,(w+1)*sizeof(typename T::accumulator_type));
150 
151  for(y=0;y<h+1;y++,pen.inc_y())
152  {
153  int yadj;
154  if(y>=h)
155  {yadj=-1; SR1=SR0=(typename T::accumulator_type)(pen.y()[yadj]);}
156  else
157  {yadj=0; SR1=SR0=(typename T::accumulator_type)(pen.get_value()); }
158 
159  for(x=0;x<w+1;x++,pen.inc_x())
160  {
161  if(x>=w)
162  Tmp1=(typename T::accumulator_type)(pen[yadj][(w-x)-2]);
163  else
164  Tmp1=(typename T::accumulator_type)(*pen[yadj]);
165 
166  Tmp2=SR0+Tmp1;
167  SR0=Tmp1;
168  Tmp1=SR1+Tmp2;
169  SR1=Tmp2;
170 
171  Tmp2=SC0[x]+Tmp1;
172  SC0[x]=Tmp1;
173  if(y&&x)
174  pen[-1][-1]=(typename T::value_type)((SC1[x]+Tmp2)/16);
175  SC1[x]=Tmp2;
176  }
177  pen.dec_x(x);
178  }
179 
180  delete [] SC0;
181  delete [] SC1;
182 }
183 
185 template<typename _PEN> void
186 gaussian_blur_3x3(_PEN begin, _PEN end)
187 {
188  typename _PEN::difference_type size(end-begin);
189  gaussian_blur_3x3(begin,size.x,size.y);
190 }
191 
193 template<typename I> void
194 gaussian_blur_3(I begin, I end, bool endpts = true)
195 {
196 // typedef typename I _itertype;
197 // int i;
198  typename std::iterator_traits<I>::value_type Tmp1,Tmp2,SR0,SR1;
199 
200  SR0=SR1=*begin;
201  I iter,prev=begin;
202  for(iter=begin;iter!=end;prev=iter++)
203  {
204  Tmp1=*iter;
205  Tmp2=SR0+Tmp1;
206  SR0=Tmp1;
207  Tmp1=SR1+Tmp2;
208  SR1=Tmp2;
209  if(iter!=begin && ( endpts || (prev != begin) ))
210  *prev=(Tmp1)/4;
211  }
212 
213  if(endpts)
214  {
215  Tmp1=*prev;
216  Tmp2=SR0+Tmp1;
217  SR0=Tmp1;
218  Tmp1=SR1+Tmp2;
219  SR1=Tmp2;
220  *prev=(Tmp1)/4;
221  }
222 }
223 
225 template<typename _PEN> void
226 gaussian_blur_3x1(_PEN begin, _PEN end)
227 {
228  typename _PEN::difference_type size=end-begin;
229  for(;size.y>0;size.y--, begin.inc_y())
230  gaussian_blur_3(begin.x(),begin.x()+size.x);
231 }
232 
234 template<typename _PEN> void
235 gaussian_blur_1x3(_PEN begin, _PEN end)
236 {
237  typename _PEN::difference_type size=end-begin;
238  for(;size.x>0;size.x--,begin.inc_x())
239  gaussian_blur_3(begin.y(),begin.y()+size.y);
240 }
241 
242 template<typename T> void
243 gaussian_blur(T pen, int w, int h, int blur_x, int blur_y)
244 {
245  typename T::accumulator_pointer SC0=new typename T::accumulator_type[w+2];
246  typename T::accumulator_pointer SC1=new typename T::accumulator_type[w+2];
247  typename T::accumulator_pointer SC2=new typename T::accumulator_type[w+2];
248  typename T::accumulator_pointer SC3=new typename T::accumulator_type[w+2];
249 
250  blur_x--;
251  blur_y--;
252 
253  while(blur_x&&blur_y)
254  {
255  if(blur_x>=4 && blur_y>=4)
256  {
257  gaussian_blur_5x5_(pen,w,h,SC0,SC1,SC2,SC3);
258  blur_x-=4,blur_y-=4;
259  }
260  else if(blur_x>=2 && blur_y>=2)
261  {
262  gaussian_blur_3x3(pen,w,h);
263  blur_x-=2,blur_y-=2;
264  }
265  else
266  blur_x--,blur_y--;
267  }
268  while(blur_x)
269  {
270  if(blur_x>=2)
271  {
272  gaussian_blur_3x1(pen,T(pen).move(w,h));
273  blur_x-=2;
274  }
275  else
276  blur_x--;
277  }
278  while(blur_y)
279  {
280  if(blur_y>=2)
281  {
282  gaussian_blur_1x3(pen,T(pen).move(w,h));
283  blur_y-=2;
284  }
285  else
286  blur_y--;
287  }
288 
289  delete [] SC0;
290  delete [] SC1;
291  delete [] SC2;
292  delete [] SC3;
293 }
294 
295 template<typename T> void
296 gaussian_blur(T begin, T end,int w, int h)
297 {
298  typename T::difference_type size(end-begin);
299  gaussian_blur(begin,size.x,size.y,w,h);
300 }
301 
302 template<typename T> void
303 gaussian_blur(T begin, T end,int w)
304 {
305  typename T::difference_type size(end-begin);
306  gaussian_blur(begin,size.x,size.y,w,w);
307 }
308 
310 
311 /* === E X T E R N S ======================================================= */
312 
313 /* === E N D =============================================================== */
314 
315 #endif