_boxblur.h

Go to the documentation of this file.
00001 
00025 /* === S T A R T =========================================================== */
00026 
00027 #ifndef __ETL_BOXBLUR_H
00028 #define __ETL_BOXBLUR_H
00029 
00030 /* === H E A D E R S ======================================================= */
00031 
00032 /* === M A C R O S ========================================================= */
00033 
00034 /* === T Y P E D E F S ===================================================== */
00035 
00036 /* === C L A S S E S & S T R U C T S ======================================= */
00037 
00038 _ETL_BEGIN_NAMESPACE
00039 
00040 template<typename T1,typename T2> void
00041 hbox_blur(T1 pen,int w, int h, int length, T2 outpen)
00042 {
00043     int x,y;
00044     typename T1::iterator_x iter, end;
00045 
00046     length=std::min(w,length);
00047     const float divisor(1.0f/(length*2+1));
00048     
00049     for(y=0;y<h;y++,pen.inc_y(),outpen.inc_y())
00050     {
00051         iter=pen.x();
00052         end=pen.end_x();
00053         
00054         typename T1::accumulator_type tot(*iter*(length+1));
00055 
00056         for (x=0;x<length && iter!=end;x++,++iter) tot+=*iter;
00057         iter=pen.x();
00058 
00059         for (x=0;x<w && iter!=end;x++,++iter,outpen.inc_x())
00060         {           
00061             tot -= (x>length) ? iter[-length-1] : *pen.x();
00062             tot += ((x+length)<w) ? iter[length] : end[-1];
00063 
00064             outpen.put_value(tot*divisor);
00065         }
00066         outpen.dec_x(x);
00067     }
00068 }
00069 
00070 #if 1
00071 template<typename T1,typename T2> void
00072 vbox_blur(T1 pen,const int w, const int h, int length, T2 outpen)
00073 {
00074     int x,y;
00075     typename T1::iterator_y iter, end;
00076 
00077     length=std::min(h,length);
00078     const float divisor(1.0f/(length*2+1));
00079     
00080     for(x=0;x<w;x++,pen.inc_x(),outpen.inc_x())
00081     {
00082         iter=pen.y();
00083         end=pen.end_y();
00084         
00085         typename T1::accumulator_type tot(*iter*(length+1));
00086 
00087         for (y=0;y<length && iter!=end;y++,++iter) tot+=*iter;
00088         iter=pen.y();
00089 
00090         for (y=0;y<h && iter!=end;y++,++iter,outpen.inc_y())
00091         {           
00092             tot -= (y>length) ? iter[-length-1] : *pen.y();
00093             tot += ((y+length)<h) ? iter[length] : end[-1];
00094 
00095             outpen.put_value(tot*divisor);
00096         }
00097         outpen.dec_y(y);
00098     }
00099 }
00100 
00101 #else
00102 
00103 template<typename T1,typename T2> void
00104 vbox_blur(T1 pen,int w, int h, int length,T2 outpen)
00105 {
00106     int x,y;
00107     typename T1::iterator_y iter, end, biter,eiter;
00108 
00109     //print out the info I need to figure out if this is somehow a buffer overrun...
00110     /*char *beginptr=0,*endptr=0;
00111     {
00112         T1 ypen = pen;
00113         T1 endpen = pen;
00114         endpen.move(w,h);
00115         ypen.inc_y();
00116         
00117         T2  open = outpen,
00118             oepen = outpen;
00119         oepen.move(w,h);
00120         printf("V Blur (%d,%d,s-%d) in(%p,%p,st %d) out(%p,%p)\n",
00121                 w,h,length,(char*)pen.x(),(char*)endpen.x(),(char*)ypen.x()-(char*)pen.x(),
00122                 (char*)open.x(),(char*)oepen.x());
00123     }*/
00124     length=min(h-1,length);
00125     
00126     const float divisor(1.0f/(length*2+1));
00127     //const int div = (length*2+1);
00128 
00129     //since the filter range is 2*length+1 we need h-1
00130     for(x=0;x<w;x++,pen.inc_x(),outpen.inc_x())
00131     {
00132         iter=pen.y();
00133         end=pen.end_y();
00134         
00135         const typename T1::value_type bval = *iter;
00136         const typename T1::value_type eval = end[-1];
00137         
00138         typename T1::accumulator_type tot(bval*(length+1));
00139         //beginptr = (char*)&*iter; endptr = (char*)&*end;
00140         
00141         //printf("\nx line %d (%p,%p)\n",x,beginptr,endptr);
00142         
00143         //printf("Init %.3f - ",tot);
00144         for (y=0;y<length && iter!=end;y++)
00145         {
00146             tot+=iter[y];
00147             //printf("(%d,%p,+%.3f->%.3f),",y,&iter[y],iter[y],tot);
00148         }
00149         iter=pen.y();
00150         
00151         //printf(" tot=%.3f\n",tot);
00152         
00153         biter = iter+(-length-1); //get the first one...
00154         eiter = iter+length;
00155         
00156         //y will always be > length
00157         //T2 open = outpen;
00158         for (y=0;y<h && iter!=end;y++,++iter,++biter,++eiter,outpen.inc_y())
00159         {           
00160             //printf("y line %d - (%f) ",y,tot);
00161             
00162             if (y>length) 
00163             {
00164                 typename T1::value_type &v = *biter;
00165                 /*if( (char*)&v < beginptr ||
00166                     (char*)&v >= endptr)
00167                     printf("crap! %d (%p off %p)\n",y,(char*)&v,(char*)&*iter);*/
00168                 tot -= v;
00169                 //printf("[%.3f,",v);
00170             }
00171             else
00172             {
00173                 tot -= bval;
00174                 //printf("[%.3f,",bval);
00175             }
00176 
00177             if (y+length<h) 
00178             {
00179                 typename T1::value_type &v = *eiter;
00180                 /*if( (char*)&v < beginptr || 
00181                     (char*)&v >= endptr)
00182                     printf("crap! %d (%p off %p)\n",y,(char*)&v,(char*)&*iter);*/
00183                 tot += v;
00184                 //printf("%.3f]",v);
00185             }
00186             else 
00187             {
00188                 tot += eval;
00189                 //printf("%.3f]",eval);
00190             }
00191             
00192             //test handled in the previous case...
00193             //tot -= (y>length) ? *biter : bval;
00194             //tot += (y+length<h) ? *eiter : eval;
00195             
00196             //printf(" - %.3f\n",tot);
00197             outpen.put_value(tot*divisor);
00198         }
00199         outpen.dec_y(y);
00200     }
00201 }
00202 #endif
00203 
00204 template<typename T1,typename T2> void
00205 box_blur(T1 pen,int w, int h, int blur_w, int blur_h, T2 outpen)
00206     { hbox_blur(pen,w,h,blur_w,outpen); vbox_blur(pen,w,h,blur_h,outpen); }
00207 
00208 template<typename T1,typename T2> void
00209 box_blur(T1 pen,int w, int h, int size, T2 outpen)
00210     { hbox_blur(pen,w,h,size,outpen); vbox_blur(pen,w,h,size,outpen); }
00211 
00212 template<typename T1,typename T2> void
00213 hbox_blur(T1 begin,T1 end, int len,T2 outpen)
00214 {
00215     typename T1::difference_type size(end-begin);
00216     hbox_blur(begin,size.x,size.y,len,outpen);
00217 }
00218 
00219 template<typename T1,typename T2> void
00220 vbox_blur(T1 begin,T1 end, int len,T2 outpen)
00221 {
00222     typename T1::difference_type size(end-begin);
00223     vbox_blur(begin,size.x,size.y,len,outpen);
00224 }
00225 
00226 template<typename T1,typename T2> void
00227 box_blur(T1 begin,T1 end, int blur_w, int blur_h,T2 outpen)
00228 {
00229     typename T1::difference_type size(end-begin);
00230     hbox_blur(begin,size.x,size.y,blur_w,outpen); vbox_blur(begin,size.x,size.y,blur_h,outpen);
00231 }
00232 
00233 template<typename T1,typename T2> void
00234 box_blur(T1 begin,T1 end, int blursize,T2 outpen)
00235 {
00236     typename T1::difference_type size(end-begin);
00237     hbox_blur(begin,size.x,size.y,blursize,outpen); vbox_blur(begin,size.x,size.y,blursize,outpen);
00238 }
00239 
00240 _ETL_END_NAMESPACE
00241 
00242 /* === E X T E R N S ======================================================= */
00243 
00244 /* === E N D =============================================================== */
00245 
00246 #endif

Generated on Thu Jan 12 22:17:43 2006 for ETL by  doxygen 1.4.6