00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
00028 # define MLN_ACCU_TRANSFORM_DIRECTIONAL_HH
00029
00037
00038
00039 # include <mln/core/concept/image.hh>
00040 # include <mln/core/concept/meta_accumulator.hh>
00041 # include <mln/core/alias/window2d.hh>
00042 # include <mln/win/diff.hh>
00043 # include <mln/win/shift.hh>
00044 # include <mln/geom/delta.hh>
00045 # include <mln/literal/zero.hh>
00046 # include <mln/extension/adjust.hh>
00047 # include <mln/canvas/browsing/directional.hh>
00048
00049
00050
00051 namespace mln
00052 {
00053
00054 namespace accu
00055 {
00056
00057
00058 template <typename A, typename I, typename W>
00059 mln_ch_value(I, mln_result(A))
00060 transform_directional(const Accumulator<A>& a,
00061 const Image<I>& input, const Window<W>& win,
00062 unsigned dir);
00063
00064
00065 template <typename A, typename I, typename W>
00066 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00067 transform_directional(const Meta_Accumulator<A>& a,
00068 const Image<I>& input, const Window<W>& win,
00069 unsigned dir);
00070
00071
00072
00073 # ifndef MLN_INCLUDE_ONLY
00074
00075 namespace internal
00076 {
00077
00078
00079
00080
00081
00082 template <typename I, typename W>
00083 void transform_directional_tests(const Image<I>& input_, const Window<W>& win_)
00084 {
00085 const I& input = exact(input_);
00086 const W& win = exact(win_);
00087
00088 mln_precondition(input.is_valid());
00089 mln_precondition(win.is_valid());
00090 mln_precondition(! win.is_empty());
00091
00092 (void) input;
00093 (void) win;
00094 }
00095
00096
00097
00098
00099
00100
00101 template <typename Dp>
00102 Dp dp_directional(int dir)
00103 {
00104 Dp dp = literal::zero;
00105 dp[dir] = 1;
00106 return dp;
00107 }
00108
00109
00110
00111
00112
00113
00114 template <typename I_, typename W, typename A>
00115 struct directional_functor
00116 {
00117 typedef I_ I;
00118 typedef mln_deduce(I, psite, delta) dpsite;
00119
00120 const I& input;
00121 const W& win;
00122 mln_ch_value(I, mln_result(A)) output;
00123 A accu;
00124
00125 typedef mln_site(I) S;
00126 enum { dim = S::dim };
00127
00128 mln_psite(I) p;
00129 unsigned dir;
00130
00131 window2d
00132 win_left,
00133 win_right;
00134
00135 mln_qiter(window2d)
00136 q_l,
00137 q_r;
00138
00139 directional_functor(const I& input, const W& win, const A& a, int dir)
00140 : input(input),
00141 win(win),
00142 accu(a),
00143 dir(dir),
00144 win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
00145 win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
00146 q_l(win_left, p),
00147 q_r(win_right, p)
00148 {
00149
00150 }
00151
00152 void init()
00153 {
00154 initialize(output, input);
00155 }
00156
00157 void init_run()
00158 {
00159 accu.init();
00160 p[dir]--;
00161 mln_qiter(W) q(win, p);
00162 for_all(q) if (input.has(q))
00163 accu.take(input(q));
00164 p[dir]++;
00165 }
00166
00167 void next()
00168 {
00169 for_all(q_l) if (input.has(q_l))
00170 accu.untake(input(q_l));
00171 for_all(q_r) if (input.has(q_r))
00172 accu.take(input(q_r));
00173 output(p) = accu;
00174 }
00175
00176 void final()
00177 {
00178 }
00179
00180 };
00181
00182
00183
00184
00185
00186
00187 template <typename I_, typename W, typename A>
00188 struct directional_fastest_functor
00189 {
00190 typedef I_ I;
00191 typedef mln_deduce(I, psite, delta) dpsite;
00192
00193 const I& input;
00194 const W& win;
00195 mln_ch_value(I, mln_result(A)) output;
00196 A accu;
00197
00198 mln_psite(I) p;
00199 typedef mln_site(I) S;
00200 enum { dim = S::dim };
00201 unsigned dir;
00202
00203 window2d win_left, win_right;
00204
00205 mln_qixter(const I, window2d) q_l, q_r;
00206
00207 directional_fastest_functor(const I& input, const W& win, const A& a, unsigned dir)
00208 : input(input),
00209 win(win),
00210 accu(a),
00211 dir(dir),
00212 win_left(win::shift(win, -dp_directional<dpsite>(dir)) - win),
00213 win_right(win - win::shift(win, -dp_directional<dpsite>(dir))),
00214 q_l(input, win_left, p),
00215 q_r(input, win_right, p)
00216 {
00217 }
00218
00219 void init()
00220 {
00221 initialize(output, input);
00222 }
00223
00224 void next()
00225 {
00226 for_all(q_l)
00227 accu.untake(q_l.val());
00228 for_all(q_r)
00229 accu.take(q_r.val());
00230 output(p) = accu;
00231 }
00232
00233
00234 void init_run()
00235 {
00236 accu.init();
00237 p[dir]--;
00238 mln_qixter(const I, W) q(input, win, p);
00239 for_all(q)
00240 accu.take(q.val());
00241 p[dir]++;
00242 }
00243
00244 void final()
00245 {
00246 }
00247
00248 };
00249
00250
00251
00252
00253
00254
00255 template <typename A, typename I, typename W>
00256 inline
00257 mln_ch_value(I, mln_result(A))
00258 transform_directional_dispatch(metal::false_,
00259 const Accumulator<A>& a,
00260 const Image<I>& input, const Window<W>& win,
00261 unsigned dir)
00262 {
00263 typedef directional_functor<I, W, A> F;
00264 F f(exact(input), exact(win), exact(a), dir);
00265 canvas::browsing::directional(f);
00266 return f.output;
00267 }
00268
00269 template <typename A, typename I, typename W>
00270 inline
00271 mln_ch_value(I, mln_result(A))
00272 transform_directional_dispatch(metal::true_,
00273 const Accumulator<A>& a,
00274 const Image<I>& input, const Window<W>& win,
00275 unsigned dir)
00276 {
00277 typedef directional_fastest_functor<I, W, A> F;
00278 F f(exact(input), exact(win), exact(a), dir);
00279 canvas::browsing::directional(f);
00280 return f.output;
00281 }
00282
00283 template <typename A, typename I, typename W>
00284 inline
00285 mln_ch_value(I, mln_result(A))
00286 transform_directional_dispatch(const Accumulator<A>& a,
00287 const Image<I>& input, const Window<W>& win,
00288 unsigned dir)
00289 {
00290 return transform_directional_dispatch(mln_is_fastest_IW(I, W)(),
00291 a, input, win, dir);
00292 }
00293
00294 }
00295
00296
00297
00298
00299 template <typename A, typename I, typename W>
00300 inline
00301 mln_ch_value(I, mln_result(A))
00302 transform_directional(const Accumulator<A>& a,
00303 const Image<I>& input, const Window<W>& win,
00304 unsigned dir)
00305 {
00306 trace::entering("accu::transform_directional");
00307
00308 internal::transform_directional_tests(input, win);
00309
00310 extension::adjust(input, geom::delta(win) + 1);
00311 mln_ch_value(I, mln_result(A)) output;
00312 output = internal::transform_directional_dispatch(a, input, win, dir);
00313
00314 trace::exiting("accu::transform_directional");
00315 return output;
00316 }
00317
00318
00319 template <typename A, typename I, typename W>
00320 inline
00321 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00322 transform_directional(const Meta_Accumulator<A>& a,
00323 const Image<I>& input, const Window<W>& win,
00324 unsigned dir)
00325 {
00326 trace::entering("accu::transform_directional");
00327
00328 internal::transform_directional_tests(input, win);
00329
00330 typedef mln_accu_with(A, mln_value(I)) A_;
00331 A_ a_ = accu::unmeta(exact(a), mln_value(I)());
00332
00333 extension::adjust(input, geom::delta(win) + 1);
00334 mln_ch_value(I, mln_result(A_)) output;
00335 output = internal::transform_directional_dispatch(a_, input, win, dir);
00336
00337 trace::exiting("accu::transform_directional");
00338 return output;
00339 }
00340
00341
00342 # endif // ! MLN_INCLUDE_ONLY
00343
00344 }
00345
00346 }
00347
00348
00349 #endif // ! MLN_ACCU_TRANSFORM_DIRECTIONAL_HH