00001
00025
00026
00027 #ifndef __ETL_GAUSSIAN_H
00028 #define __ETL_GAUSSIAN_H
00029
00030
00031
00032 #include <cstring>
00033 #include <iterator>
00034
00035
00036
00037
00038
00039
00040
00041 _ETL_BEGIN_NAMESPACE
00042
00043 template<typename T> void
00044 gaussian_blur_5x5_(T pen,int w, int h,
00045 typename T::pointer SC0,
00046 typename T::pointer SC1,
00047 typename T::pointer SC2,
00048 typename T::pointer SC3)
00049 {
00050 int x,y;
00051 typename T::value_type Tmp1,Tmp2,SR0,SR1,SR2,SR3;
00052
00053
00054
00055
00056 for(x=0;x<w;x++)SC0[x+2]=pen.x()[x]*24;
00057 memset(SC1,0,(w+2)*sizeof(typename T::value_type));
00058 memset(SC2,0,(w+2)*sizeof(typename T::value_type));
00059 memset(SC3,0,(w+2)*sizeof(typename T::value_type));
00060
00061 for(y=0;y<h+2;y++,pen.inc_y())
00062 {
00063 int yadj;
00064 if(y>=h)
00065 {yadj=(h-y)-1; SR0=pen.y()[yadj]*1.35;}
00066 else
00067 {yadj=0; SR0=pen.get_value()*1.35; }
00068
00069 SR1=SR2=SR3=typename T::value_type();
00070 for(x=0;x<w+2;x++,pen.inc_x())
00071 {
00072 if(x>=w)
00073 Tmp1=pen[yadj][(w-x)-1];
00074 else
00075 Tmp1=*pen[yadj];
00076
00077 Tmp2=SR0+Tmp1;
00078 SR0=Tmp1;
00079 Tmp1=SR1+Tmp2;
00080 SR1=Tmp2;
00081 Tmp2=SR2+Tmp1;
00082 SR2=Tmp1;
00083 Tmp1=SR3+Tmp2;
00084 SR3=Tmp2;
00085
00086
00087 Tmp2=SC0[x]+Tmp1;
00088 SC0[x]=Tmp1;
00089 Tmp1=SC1[x]+Tmp2;
00090 SC1[x]=Tmp2;
00091 Tmp2=SC2[x]+Tmp1;
00092 SC2[x]=Tmp1;
00093 if(y>1&&x>1)
00094 pen[-2][-2]=(SC3[x]+Tmp2)/256;
00095 SC3[x]=Tmp2;
00096 }
00097 pen.dec_x(x);
00098 }
00099
00100 }
00101
00102 template<typename T> void
00103 gaussian_blur_5x5(T pen, int w, int h)
00104 {
00105 typename T::pointer SC0=new typename T::value_type[w+2];
00106 typename T::pointer SC1=new typename T::value_type[w+2];
00107 typename T::pointer SC2=new typename T::value_type[w+2];
00108 typename T::pointer SC3=new typename T::value_type[w+2];
00109
00110 gaussian_blur_5x5_(pen,w,h,SC0,SC1,SC2,SC3);
00111
00112 delete [] SC0;
00113 delete [] SC1;
00114 delete [] SC2;
00115 delete [] SC3;
00116 }
00117
00118 template<typename T> void
00119 gaussian_blur_5x5(T begin, T end)
00120 {
00121 typename T::difference_type size(end-begin);
00122
00123 typename T::pointer SC0=new typename T::value_type[size.x+2];
00124 typename T::pointer SC1=new typename T::value_type[size.x+2];
00125 typename T::pointer SC2=new typename T::value_type[size.x+2];
00126 typename T::pointer SC3=new typename T::value_type[size.x+2];
00127
00128 gaussian_blur_5x5_(begin,size.x,size.y,SC0,SC1,SC2,SC3);
00129
00130 delete [] SC0;
00131 delete [] SC1;
00132 delete [] SC2;
00133 delete [] SC3;
00134 }
00135
00136 template<typename T> void
00137 gaussian_blur_3x3(T pen,int w, int h)
00138 {
00139 int x,y;
00140 typename T::value_type Tmp1,Tmp2,SR0,SR1;
00141
00142
00143
00144 typename T::pointer SC0=new typename T::value_type[w+1];
00145 typename T::pointer SC1=new typename T::value_type[w+1];
00146
00147
00148 for(x=0;x<w;x++)SC0[x+1]=pen.x()[x]*4;
00149 memset(SC1,0,(w+1)*sizeof(typename T::value_type));
00150
00151 for(y=0;y<h+1;y++,pen.inc_y())
00152 {
00153 int yadj;
00154 if(y>=h)
00155 {yadj=-1; SR1=SR0=pen.y()[yadj];}
00156 else
00157 {yadj=0; SR1=SR0=pen.get_value(); }
00158
00159 for(x=0;x<w+1;x++,pen.inc_x())
00160 {
00161 if(x>=w)
00162 Tmp1=pen[yadj][(w-x)-2];
00163 else
00164 Tmp1=*pen[yadj];
00165
00166 Tmp2=SR0+Tmp1;
00167 SR0=Tmp1;
00168 Tmp1=SR1+Tmp2;
00169 SR1=Tmp2;
00170
00171 Tmp2=SC0[x]+Tmp1;
00172 SC0[x]=Tmp1;
00173 if(y&&x)
00174 pen[-1][-1]=(SC1[x]+Tmp2)/16;
00175 SC1[x]=Tmp2;
00176 }
00177 pen.dec_x(x);
00178 }
00179
00180 delete [] SC0;
00181 delete [] SC1;
00182 }
00183
00185 template<typename _PEN> void
00186 gaussian_blur_3x3(_PEN begin, _PEN end)
00187 {
00188 typename _PEN::difference_type size(end-begin);
00189 gaussian_blur_3x3(begin,size.x,size.y);
00190 }
00191
00193 template<typename I> void
00194 gaussian_blur_3(I begin, I end, bool endpts = true)
00195 {
00196
00197
00198 typename std::iterator_traits<I>::value_type Tmp1,Tmp2,SR0,SR1;
00199
00200 SR0=SR1=*begin;
00201 I iter,prev=begin;
00202 for(iter=begin;iter!=end;prev=iter++)
00203 {
00204 Tmp1=*iter;
00205 Tmp2=SR0+Tmp1;
00206 SR0=Tmp1;
00207 Tmp1=SR1+Tmp2;
00208 SR1=Tmp2;
00209 if(iter!=begin && ( endpts || (prev != begin) ))
00210 *prev=(Tmp1)/4;
00211 }
00212
00213 if(endpts)
00214 {
00215 Tmp1=*prev;
00216 Tmp2=SR0+Tmp1;
00217 SR0=Tmp1;
00218 Tmp1=SR1+Tmp2;
00219 SR1=Tmp2;
00220 *prev=(Tmp1)/4;
00221 }
00222 }
00223
00225 template<typename _PEN> void
00226 gaussian_blur_3x1(_PEN begin, _PEN end)
00227 {
00228 typename _PEN::difference_type size=end-begin;
00229 for(;size.y>0;size.y--, begin.inc_y())
00230 gaussian_blur_3(begin.x(),begin.x()+size.x);
00231 }
00232
00234 template<typename _PEN> void
00235 gaussian_blur_1x3(_PEN begin, _PEN end)
00236 {
00237 typename _PEN::difference_type size=end-begin;
00238 for(;size.x>0;size.x--,begin.inc_x())
00239 gaussian_blur_3(begin.y(),begin.y()+size.y);
00240 }
00241
00242 template<typename T> void
00243 gaussian_blur(T pen, int w, int h, int blur_x, int blur_y)
00244 {
00245 typename T::pointer SC0=new typename T::value_type[w+2];
00246 typename T::pointer SC1=new typename T::value_type[w+2];
00247 typename T::pointer SC2=new typename T::value_type[w+2];
00248 typename T::pointer SC3=new typename T::value_type[w+2];
00249
00250 blur_x--;
00251 blur_y--;
00252
00253 while(blur_x&&blur_y)
00254 {
00255 if(blur_x>=4 && blur_y>=4)
00256 {
00257 gaussian_blur_5x5_(pen,w,h,SC0,SC1,SC2,SC3);
00258 blur_x-=4,blur_y-=4;
00259 }
00260 else if(blur_x>=2 && blur_y>=2)
00261 {
00262 gaussian_blur_3x3(pen,w,h);
00263 blur_x-=2,blur_y-=2;
00264 }
00265 else
00266 blur_x--,blur_y--;
00267 }
00268 while(blur_x)
00269 {
00270 if(blur_x>=2)
00271 {
00272 gaussian_blur_3x1(pen,T(pen).move(w,h));
00273 blur_x-=2;
00274 }
00275 else
00276 blur_x--;
00277 }
00278 while(blur_y)
00279 {
00280 if(blur_y>=2)
00281 {
00282 gaussian_blur_1x3(pen,T(pen).move(w,h));
00283 blur_y-=2;
00284 }
00285 else
00286 blur_y--;
00287 }
00288
00289 delete [] SC0;
00290 delete [] SC1;
00291 delete [] SC2;
00292 delete [] SC3;
00293 }
00294
00295 template<typename T> void
00296 gaussian_blur(T begin, T end,int w, int h)
00297 {
00298 typename T::difference_type size(end-begin);
00299 gaussian_blur(begin,size.x,size.y,w,h);
00300 }
00301
00302 template<typename T> void
00303 gaussian_blur(T begin, T end,int w)
00304 {
00305 typename T::difference_type size(end-begin);
00306 gaussian_blur(begin,size.x,size.y,w,w);
00307 }
00308
00309 _ETL_END_NAMESPACE
00310
00311
00312
00313
00314
00315 #endif