- Main Page
- Related Pages
- Classes
- Files

# _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