_gaussian.h

Go to the documentation of this file.
00001 
00025 /* === S T A R T =========================================================== */
00026 
00027 #ifndef __ETL_GAUSSIAN_H
00028 #define __ETL_GAUSSIAN_H
00029 
00030 /* === H E A D E R S ======================================================= */
00031 
00032 #include <cstring>      // for memset()
00033 #include <iterator>
00034 
00035 /* === M A C R O S ========================================================= */
00036 
00037 /* === T Y P E D E F S ===================================================== */
00038 
00039 /* === C L A S S E S & S T R U C T S ======================================= */
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     //typename T::iterator_x iter;
00054 
00055     // Setup the row bufers
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             // Column Machine
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 //  typename T::iterator_x iter;
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     // Setup the row bufers
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 //  typedef typename I _itertype;
00197 //  int i;
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 /* === E X T E R N S ======================================================= */
00312 
00313 /* === E N D =============================================================== */
00314 
00315 #endif

Generated on Fri Jan 13 02:13:56 2006 for ETL by  doxygen 1.4.6