1 /*! ========================================================================
2 ** Extended Template Library
3 ** Gaussian Blur Template Implementation
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
18 ** === N O T E S ===========================================================
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
23 ** ========================================================================= */
25 /* === S T A R T =========================================================== */
27 #ifndef __ETL_GAUSSIAN_H
28 #define __ETL_GAUSSIAN_H
30 /* === H E A D E R S ======================================================= */
32 #include <cstring> // for memset()
35 /* === M A C R O S ========================================================= */
37 /* === T Y P E D E F S ===================================================== */
39 /* === C L A S S E S & S T R U C T S ======================================= */
43 template<typename T> void
44 gaussian_blur_5x5_(T pen,int w, int h,
45 typename T::pointer SC0,
46 typename T::pointer SC1,
47 typename T::pointer SC2,
48 typename T::pointer SC3)
51 typename T::value_type Tmp1,Tmp2,SR0,SR1,SR2,SR3;
53 //typename T::iterator_x iter;
55 // Setup the row buffers
56 for(x=0;x<w;x++)SC0[x+2]=pen.x()[x]*24;
57 memset(SC1,0,(w+2)*sizeof(typename T::value_type));
58 memset(SC2,0,(w+2)*sizeof(typename T::value_type));
59 memset(SC3,0,(w+2)*sizeof(typename T::value_type));
61 for(y=0;y<h+2;y++,pen.inc_y())
65 {yadj=(h-y)-1; SR0=pen.y()[yadj]*1.35;}
67 {yadj=0; SR0=pen.get_value()*1.35; }
69 SR1=SR2=SR3=typename T::value_type();
70 for(x=0;x<w+2;x++,pen.inc_x())
73 Tmp1=pen[yadj][(w-x)-1];
94 pen[-2][-2]=(SC3[x]+Tmp2)/256;
102 template<typename T> void
103 gaussian_blur_5x5(T pen, int w, int h)
105 typename T::pointer SC0=new typename T::value_type[w+2];
106 typename T::pointer SC1=new typename T::value_type[w+2];
107 typename T::pointer SC2=new typename T::value_type[w+2];
108 typename T::pointer SC3=new typename T::value_type[w+2];
110 gaussian_blur_5x5_(pen,w,h,SC0,SC1,SC2,SC3);
118 template<typename T> void
119 gaussian_blur_5x5(T begin, T end)
121 typename T::difference_type size(end-begin);
123 typename T::pointer SC0=new typename T::value_type[size.x+2];
124 typename T::pointer SC1=new typename T::value_type[size.x+2];
125 typename T::pointer SC2=new typename T::value_type[size.x+2];
126 typename T::pointer SC3=new typename T::value_type[size.x+2];
128 gaussian_blur_5x5_(begin,size.x,size.y,SC0,SC1,SC2,SC3);
136 template<typename T> void
137 gaussian_blur_3x3(T pen,int w, int h)
140 typename T::value_type Tmp1,Tmp2,SR0,SR1;
142 // typename T::iterator_x iter;
144 typename T::pointer SC0=new typename T::value_type[w+1];
145 typename T::pointer SC1=new typename T::value_type[w+1];
147 // Setup the row buffers
148 for(x=0;x<w;x++)SC0[x+1]=pen.x()[x]*4;
149 memset(SC1,0,(w+1)*sizeof(typename T::value_type));
151 for(y=0;y<h+1;y++,pen.inc_y())
155 {yadj=-1; SR1=SR0=pen.y()[yadj];}
157 {yadj=0; SR1=SR0=pen.get_value(); }
159 for(x=0;x<w+1;x++,pen.inc_x())
162 Tmp1=pen[yadj][(w-x)-2];
174 pen[-1][-1]=(SC1[x]+Tmp2)/16;
184 //! 2D 3x3 pixel gaussian blur
185 template<typename _PEN> void
186 gaussian_blur_3x3(_PEN begin, _PEN end)
188 typename _PEN::difference_type size(end-begin);
189 gaussian_blur_3x3(begin,size.x,size.y);
192 //! 1D 3 pixel gaussian blur
193 template<typename I> void
194 gaussian_blur_3(I begin, I end, bool endpts = true)
196 // typedef typename I _itertype;
198 typename std::iterator_traits<I>::value_type Tmp1,Tmp2,SR0,SR1;
202 for(iter=begin;iter!=end;prev=iter++)
209 if(iter!=begin && ( endpts || (prev != begin) ))
224 //! 2D 3x1 pixel gaussian blur
225 template<typename _PEN> void
226 gaussian_blur_3x1(_PEN begin, _PEN end)
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);
233 //! 2D 1x3 pixel gaussian blur
234 template<typename _PEN> void
235 gaussian_blur_1x3(_PEN begin, _PEN end)
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);
242 template<typename T> void
243 gaussian_blur(T pen, int w, int h, int blur_x, int blur_y)
245 typename T::pointer SC0=new typename T::value_type[w+2];
246 typename T::pointer SC1=new typename T::value_type[w+2];
247 typename T::pointer SC2=new typename T::value_type[w+2];
248 typename T::pointer SC3=new typename T::value_type[w+2];
253 while(blur_x&&blur_y)
255 if(blur_x>=4 && blur_y>=4)
257 gaussian_blur_5x5_(pen,w,h,SC0,SC1,SC2,SC3);
260 else if(blur_x>=2 && blur_y>=2)
262 gaussian_blur_3x3(pen,w,h);
272 gaussian_blur_3x1(pen,T(pen).move(w,h));
282 gaussian_blur_1x3(pen,T(pen).move(w,h));
295 template<typename T> void
296 gaussian_blur(T begin, T end,int w, int h)
298 typename T::difference_type size(end-begin);
299 gaussian_blur(begin,size.x,size.y,w,h);
302 template<typename T> void
303 gaussian_blur(T begin, T end,int w)
305 typename T::difference_type size(end-begin);
306 gaussian_blur(begin,size.x,size.y,w,w);
311 /* === E X T E R N S ======================================================= */
313 /* === E N D =============================================================== */