ETL  0.04.19
_boxblur.h
Go to the documentation of this file.
1 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __ETL__BOXBLUR_H
28 #define __ETL__BOXBLUR_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 /* === M A C R O S ========================================================= */
33 
34 /* === T Y P E D E F S ===================================================== */
35 
36 /* === C L A S S E S & S T R U C T S ======================================= */
37 
39 
40 template<typename T1,typename T2> void
41 hbox_blur(T1 pen,int w, int h, int length, T2 outpen)
42 {
43  int x,y;
44  typename T1::iterator_x iter, end;
45 
46  length=std::min(w,length);
47  const float divisor(1.0f/(length*2+1));
48 
49  for(y=0;y<h;y++,pen.inc_y(),outpen.inc_y())
50  {
51  iter=pen.x();
52  end=pen.end_x();
53 
54  typename T1::accumulator_type tot((typename T1::accumulator_type)(*iter)*(length+1));
55 
56  for (x=0;x<length && iter!=end;x++,++iter) tot+=*iter;
57  iter=pen.x();
58 
59  for (x=0;x<w && iter!=end;x++,++iter,outpen.inc_x())
60  {
61  tot -= (x>length) ?
62  (typename T1::accumulator_type)(iter[-length-1]) :
63  (typename T1::accumulator_type)(*pen.x());
64  tot += ((x+length)<w) ?
65  (typename T1::accumulator_type)(iter[length]) :
66  (typename T1::accumulator_type)(end[-1]);
67 
68  outpen.put_value((typename T2::value_type)(tot*divisor));
69  }
70  outpen.dec_x(x);
71  }
72 }
73 
74 #if 1
75 template<typename T1,typename T2> void
76 vbox_blur(T1 pen,const int w, const int h, int length, T2 outpen)
77 {
78  int x,y;
79  typename T1::iterator_y iter, end;
80 
81  length=std::min(h,length);
82  const float divisor(1.0f/(length*2+1));
83 
84  for(x=0;x<w;x++,pen.inc_x(),outpen.inc_x())
85  {
86  iter=pen.y();
87  end=pen.end_y();
88 
89  typename T1::accumulator_type tot((typename T1::accumulator_type)(*iter)*(length+1));
90 
91  for (y=0;y<length && iter!=end;y++,++iter) tot+=*iter;
92  iter=pen.y();
93 
94  for (y=0;y<h && iter!=end;y++,++iter,outpen.inc_y())
95  {
96  tot -= (y>length) ?
97  (typename T1::accumulator_type)(iter[-length-1]) :
98  (typename T1::accumulator_type)(*pen.y());
99  tot += ((y+length)<h) ?
100  (typename T1::accumulator_type)(iter[length]) :
101  (typename T1::accumulator_type)(end[-1]);
102 
103  outpen.put_value((typename T2::value_type)(tot*divisor));
104  }
105  outpen.dec_y(y);
106  }
107 }
108 
109 #else
110 
111 template<typename T1,typename T2> void
112 vbox_blur(T1 pen,int w, int h, int length,T2 outpen)
113 {
114  int x,y;
115  typename T1::iterator_y iter, end, biter,eiter;
116 
117  //print out the info I need to figure out if this is somehow a buffer overrun...
118  /*char *beginptr=0,*endptr=0;
119  {
120  T1 ypen = pen;
121  T1 endpen = pen;
122  endpen.move(w,h);
123  ypen.inc_y();
124 
125  T2 open = outpen,
126  oepen = outpen;
127  oepen.move(w,h);
128  printf("V Blur (%d,%d,s-%d) in(%p,%p,st %d) out(%p,%p)\n",
129  w,h,length,(char*)pen.x(),(char*)endpen.x(),(char*)ypen.x()-(char*)pen.x(),
130  (char*)open.x(),(char*)oepen.x());
131  }*/
132  length=min(h-1,length);
133 
134  const float divisor(1.0f/(length*2+1));
135  //const int div = (length*2+1);
136 
137  //since the filter range is 2*length+1 we need h-1
138  for(x=0;x<w;x++,pen.inc_x(),outpen.inc_x())
139  {
140  iter=pen.y();
141  end=pen.end_y();
142 
143  const typename T1::value_type bval = *iter;
144  const typename T1::value_type eval = end[-1];
145 
146  typename T1::accumulator_type tot(bval*(length+1));
147  //beginptr = (char*)&*iter; endptr = (char*)&*end;
148 
149  //printf("\nx line %d (%p,%p)\n",x,beginptr,endptr);
150 
151  //printf("Init %.3f - ",tot);
152  for (y=0;y<length && iter!=end;y++)
153  {
154  tot+=iter[y];
155  //printf("(%d,%p,+%.3f->%.3f),",y,&iter[y],iter[y],tot);
156  }
157  iter=pen.y();
158 
159  //printf(" tot=%.3f\n",tot);
160 
161  biter = iter+(-length-1); //get the first one...
162  eiter = iter+length;
163 
164  //y will always be > length
165  //T2 open = outpen;
166  for (y=0;y<h && iter!=end;y++,++iter,++biter,++eiter,outpen.inc_y())
167  {
168  //printf("y line %d - (%f) ",y,tot);
169 
170  if (y>length)
171  {
172  typename T1::value_type &v = *biter;
173  /*if( (char*)&v < beginptr ||
174  (char*)&v >= endptr)
175  printf("crap! %d (%p off %p)\n",y,(char*)&v,(char*)&*iter);*/
176  tot -= v;
177  //printf("[%.3f,",v);
178  }
179  else
180  {
181  tot -= bval;
182  //printf("[%.3f,",bval);
183  }
184 
185  if (y+length<h)
186  {
187  typename T1::value_type &v = *eiter;
188  /*if( (char*)&v < beginptr ||
189  (char*)&v >= endptr)
190  printf("crap! %d (%p off %p)\n",y,(char*)&v,(char*)&*iter);*/
191  tot += v;
192  //printf("%.3f]",v);
193  }
194  else
195  {
196  tot += eval;
197  //printf("%.3f]",eval);
198  }
199 
200  //test handled in the previous case...
201  //tot -= (y>length) ? *biter : bval;
202  //tot += (y+length<h) ? *eiter : eval;
203 
204  //printf(" - %.3f\n",tot);
205  outpen.put_value(tot*divisor);
206  }
207  outpen.dec_y(y);
208  }
209 }
210 #endif
211 
212 template<typename T1,typename T2> void
213 box_blur(T1 pen,int w, int h, int blur_w, int blur_h, T2 outpen)
214  { hbox_blur(pen,w,h,blur_w,outpen); vbox_blur(pen,w,h,blur_h,outpen); }
215 
216 template<typename T1,typename T2> void
217 box_blur(T1 pen,int w, int h, int size, T2 outpen)
218  { hbox_blur(pen,w,h,size,outpen); vbox_blur(pen,w,h,size,outpen); }
219 
220 template<typename T1,typename T2> void
221 hbox_blur(T1 begin,T1 end, int len,T2 outpen)
222 {
223  typename T1::difference_type size(end-begin);
224  hbox_blur(begin,size.x,size.y,len,outpen);
225 }
226 
227 template<typename T1,typename T2> void
228 vbox_blur(T1 begin,T1 end, int len,T2 outpen)
229 {
230  typename T1::difference_type size(end-begin);
231  vbox_blur(begin,size.x,size.y,len,outpen);
232 }
233 
234 template<typename T1,typename T2> void
235 box_blur(T1 begin,T1 end, int blur_w, int blur_h,T2 outpen)
236 {
237  typename T1::difference_type size(end-begin);
238  hbox_blur(begin,size.x,size.y,blur_w,outpen); vbox_blur(begin,size.x,size.y,blur_h,outpen);
239 }
240 
241 template<typename T1,typename T2> void
242 box_blur(T1 begin,T1 end, int blursize,T2 outpen)
243 {
244  typename T1::difference_type size(end-begin);
245  hbox_blur(begin,size.x,size.y,blursize,outpen); vbox_blur(begin,size.x,size.y,blursize,outpen);
246 }
247 
249 
250 /* === E X T E R N S ======================================================= */
251 
252 /* === E N D =============================================================== */
253 
254 #endif