00001
00025
00026
00027 #ifndef __ETL__BOXBLUR_H
00028 #define __ETL__BOXBLUR_H
00029
00030
00031
00032
00033
00034
00035
00036
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
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 length=min(h-1,length);
00125
00126 const float divisor(1.0f/(length*2+1));
00127
00128
00129
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
00140
00141
00142
00143
00144 for (y=0;y<length && iter!=end;y++)
00145 {
00146 tot+=iter[y];
00147
00148 }
00149 iter=pen.y();
00150
00151
00152
00153 biter = iter+(-length-1);
00154 eiter = iter+length;
00155
00156
00157
00158 for (y=0;y<h && iter!=end;y++,++iter,++biter,++eiter,outpen.inc_y())
00159 {
00160
00161
00162 if (y>length)
00163 {
00164 typename T1::value_type &v = *biter;
00165
00166
00167
00168 tot -= v;
00169
00170 }
00171 else
00172 {
00173 tot -= bval;
00174
00175 }
00176
00177 if (y+length<h)
00178 {
00179 typename T1::value_type &v = *eiter;
00180
00181
00182
00183 tot += v;
00184
00185 }
00186 else
00187 {
00188 tot += eval;
00189
00190 }
00191
00192
00193
00194
00195
00196
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
00243
00244
00245
00246 #endif