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 #ifndef MLN_ACCU_TRANSFORM_DIAGONAL_HH
00027 # define MLN_ACCU_TRANSFORM_DIAGONAL_HH
00028
00036
00037
00038 #include <mln/core/concept/image.hh>
00039 #include <mln/core/concept/meta_accumulator.hh>
00040 #include <mln/core/alias/window2d.hh>
00041 #include <mln/win/diff.hh>
00042 #include <mln/win/shift.hh>
00043 #include <mln/geom/delta.hh>
00044 #include <mln/extension/adjust.hh>
00045
00046 #include <mln/win/diag2d.hh>
00047 #include <mln/canvas/browsing/diagonal2d.hh>
00048
00049 #include <mln/win/backdiag2d.hh>
00050 #include <mln/canvas/browsing/backdiagonal2d.hh>
00051
00052
00053
00054 namespace mln
00055 {
00056
00057 namespace accu
00058 {
00059
00060
00061 template <typename A, typename I, typename W>
00062 mln_ch_value(I, mln_result(A))
00063 transform_diagonal(const Accumulator<A>& a,
00064 const Image<I>& input, const Window<W>& win);
00065
00066
00067 template <typename A, typename I, typename W>
00068 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00069 transform_diagonal(const Meta_Accumulator<A>& a,
00070 const Image<I>& input, const Window<W>& win);
00071
00072
00073
00074 # ifndef MLN_INCLUDE_ONLY
00075
00076 namespace internal
00077 {
00078
00079
00080
00081
00082
00083 template <typename I, typename W>
00084 void transform_diagonal_tests(const Image<I>& input_, const Window<W>& win_)
00085 {
00086 const I& input = exact(input_);
00087 const W& win = exact(win_);
00088
00089 mln_precondition(input.is_valid());
00090 mln_precondition(win.is_valid());
00091 mln_precondition(! win.is_empty());
00092
00093 (void) input;
00094 (void) win;
00095 }
00096
00097
00098
00099
00100
00101
00102 template <typename I_, typename W, typename A>
00103 struct diagonal_functor
00104 {
00105 typedef I_ I;
00106 typedef mln_deduce(I, psite, delta) dpsite;
00107
00108 const I& input;
00109 const W& win;
00110 mln_ch_value(I, mln_result(A)) output;
00111 A accu;
00112
00113 mln_psite(I) p;
00114 typedef mln_site(I) S;
00115 enum { dim = S::dim };
00116
00117 window2d win_left, win_right;
00118
00119 mln_qiter(window2d) q_l, q_r;
00120
00121 diagonal_functor(const I& input, const W& win, const A& a)
00122 : input(input),
00123 win(win),
00124 accu(a),
00125 win_left(win::shift(win, dpsite(1, -1)) - win),
00126 win_right(win - win::shift(win, dpsite(1, -1))),
00127 q_l(win_left, p),
00128 q_r(win_right, p)
00129 {
00130 }
00131
00132 void init()
00133 {
00134 initialize(output, input);
00135 }
00136
00137 void next()
00138 {
00139 for_all(q_l)
00140 accu.untake(input(q_l));
00141 for_all(q_r)
00142 accu.take(input(q_r));
00143 output(p) = accu;
00144 }
00145
00146
00147 void init_diag()
00148 {
00149 accu.init();
00150 p = p - dpsite(-1, 1);
00151 mln_qiter(W) q(win, p);
00152 for_all(q)
00153 accu.take(input(q));
00154 p = p + dpsite(-1, 1);
00155 }
00156
00157 void final()
00158 {
00159 }
00160
00161 };
00162
00163
00164
00165 template <typename I_, typename W, typename A>
00166 struct backdiagonal_functor
00167 {
00168 typedef I_ I;
00169 typedef mln_deduce(I, psite, delta) dpsite;
00170
00171 const I& input;
00172 const W& win;
00173 mln_ch_value(I, mln_result(A)) output;
00174 A accu;
00175
00176 mln_psite(I) p;
00177 typedef mln_site(I) S;
00178 enum { dim = S::dim };
00179
00180 window2d win_left, win_right;
00181
00182 mln_qiter(window2d) q_l, q_r;
00183
00184 backdiagonal_functor(const I& input, const W& win, const A& a)
00185 : input(input),
00186 win(win),
00187 accu(a),
00188 win_left(win::shift(win, dpsite(-1, -1)) - win),
00189 win_right(win - win::shift(win, dpsite(-1, -1))),
00190 q_l(win_left, p),
00191 q_r(win_right, p)
00192 {
00193 }
00194
00195 void init()
00196 {
00197 initialize(output, input);
00198 }
00199
00200 void next()
00201 {
00202 for_all(q_l)
00203 accu.untake(input(q_l));
00204 for_all(q_r)
00205 accu.take(input(q_r));
00206 output(p) = accu;
00207 }
00208
00209
00210 void init_diag()
00211 {
00212 accu.init();
00213 p = p - dpsite(1, 1);
00214 mln_qiter(W) q(win, p);
00215 for_all(q)
00216 accu.take(input(q));
00217 p = p + dpsite(1, 1);
00218 }
00219
00220 void final()
00221 {
00222 }
00223
00224 };
00225
00226
00227
00228
00229
00230
00231 template <typename I_, typename W, typename A>
00232 struct diagonal_fastest_functor
00233 {
00234 typedef I_ I;
00235 typedef mln_deduce(I, psite, delta) dpsite;
00236
00237 const I& input;
00238 const W& win;
00239 mln_ch_value(I, mln_result(A)) output;
00240 A accu;
00241
00242 mln_psite(I) p;
00243 typedef mln_site(I) S;
00244 enum { dim = S::dim };
00245
00246 window2d win_left, win_right;
00247
00248 mln_qixter(const I, window2d) q_l, q_r;
00249
00250 diagonal_fastest_functor(const I& input, const W& win, const A& a)
00251 : input(input),
00252 win(win),
00253 accu(a),
00254 win_left(win::shift(win, dpsite(1, -1)) - win),
00255 win_right(win - win::shift(win, dpsite(1, -1))),
00256 q_l(input, win_left, p),
00257 q_r(input, win_right, p)
00258 {
00259 }
00260
00261 void init()
00262 {
00263 initialize(output, input);
00264 }
00265
00266 void next()
00267 {
00268 for_all(q_l)
00269 accu.untake(q_l.val());
00270 for_all(q_r)
00271 accu.take(q_r.val());
00272 output(p) = accu;
00273 }
00274
00275
00276 void init_diag()
00277 {
00278 accu.init();
00279 p = p - dpsite(-1, 1);
00280 mln_qixter(const I, W) q(input, win, p);
00281 for_all(q)
00282 accu.take(q.val());
00283 p = p + dpsite(-1, 1);
00284 }
00285
00286 void final()
00287 {
00288 }
00289
00290 };
00291
00292
00293 template <typename I_, typename W, typename A>
00294 struct backdiagonal_fastest_functor
00295 {
00296 typedef I_ I;
00297 typedef mln_deduce(I, psite, delta) dpsite;
00298
00299 const I& input;
00300 const W& win;
00301 mln_ch_value(I, mln_result(A)) output;
00302 A accu;
00303
00304 mln_psite(I) p;
00305 typedef mln_site(I) S;
00306 enum { dim = S::dim };
00307
00308 window2d win_left, win_right;
00309
00310 mln_qixter(const I, window2d) q_l, q_r;
00311
00312 backdiagonal_fastest_functor(const I& input, const W& win, const A& a)
00313 : input(input),
00314 win(win),
00315 accu(a),
00316 win_left(win::shift(win, dpsite(-1, -1)) - win),
00317 win_right(win - win::shift(win, dpsite(-1, -1))),
00318 q_l(input, win_left, p),
00319 q_r(input, win_right, p)
00320 {
00321 }
00322
00323 void init()
00324 {
00325 initialize(output, input);
00326 }
00327
00328 void next()
00329 {
00330 for_all(q_l)
00331 accu.untake(q_l.val());
00332 for_all(q_r)
00333 accu.take(q_r.val());
00334 output(p) = accu;
00335 }
00336
00337
00338 void init_diag()
00339 {
00340 accu.init();
00341 p = p - dpsite(1, 1);
00342 mln_qixter(const I, W) q(input, win, p);
00343 for_all(q)
00344 accu.take(q.val());
00345 p = p + dpsite(1, 1);
00346 }
00347
00348 void final()
00349 {
00350 }
00351
00352 };
00353
00354
00355
00356
00357
00358
00359 template <typename A, typename I>
00360 inline
00361 mln_ch_value(I, mln_result(A))
00362 transform_diagonal_dispatch(metal::false_,
00363 const Accumulator<A>& a,
00364 const Image<I>& input, const win::diag2d& win)
00365 {
00366 typedef diagonal_functor<I, win::diag2d, A> F;
00367 F f(exact(input), win, exact(a));
00368 canvas::browsing::diagonal2d(f);
00369 return f.output;
00370 }
00371
00372 template <typename B, typename A, typename I>
00373 inline
00374 mln_ch_value(I, mln_result(A))
00375 transform_diagonal_dispatch(metal::false_,
00376 const Accumulator<A>& a,
00377 const Image<I>& input, const win::backdiag2d& win)
00378 {
00379 typedef backdiagonal_functor<I, win::backdiag2d, A> F;
00380 F f(exact(input), win, exact(a));
00381 canvas::browsing::backdiagonal2d(f);
00382 return f.output;
00383 }
00384
00385 template <typename A, typename I>
00386 inline
00387 mln_ch_value(I, mln_result(A))
00388 transform_diagonal_dispatch(metal::true_,
00389 const Accumulator<A>& a,
00390 const Image<I>& input, const win::diag2d& win)
00391 {
00392 typedef diagonal_fastest_functor<I, win::diag2d, A> F;
00393 F f(exact(input), win, exact(a));
00394 canvas::browsing::diagonal2d(f);
00395 return f.output;
00396 }
00397
00398 template <typename A, typename I>
00399 inline
00400 mln_ch_value(I, mln_result(A))
00401 transform_diagonal_dispatch(metal::true_,
00402 const Accumulator<A>& a,
00403 const Image<I>& input, const win::backdiag2d& win)
00404 {
00405 typedef backdiagonal_fastest_functor<I, win::backdiag2d, A> F;
00406 F f(exact(input), win, exact(a));
00407 canvas::browsing::backdiagonal2d(f);
00408 return f.output;
00409 }
00410
00411 template <typename A, typename I, typename W>
00412 inline
00413 mln_ch_value(I, mln_result(A))
00414 transform_diagonal_dispatch(const Accumulator<A>& a,
00415 const Image<I>& input, const Window<W>& win)
00416 {
00417 return transform_diagonal_dispatch(mln_is_fastest_IW(I, W)(),
00418 a, input, exact(win));
00419 }
00420
00421 }
00422
00423
00424
00425
00426 template <typename A, typename I, typename W>
00427 inline
00428 mln_ch_value(I, mln_result(A))
00429 transform_diagonal(const Accumulator<A>& a,
00430 const Image<I>& input, const Window<W>& win)
00431 {
00432 trace::entering("accu::transform_diagonal");
00433
00434 internal::transform_diagonal_tests(input, win);
00435
00436 extension::adjust(input, geom::delta(win) + 1);
00437 mln_ch_value(I, mln_result(A)) output;
00438 output = internal::transform_diagonal_dispatch(a, input, win);
00439
00440 trace::exiting("accu::transform_diagonal");
00441 return output;
00442 }
00443
00444
00445 template <typename A, typename I, typename W>
00446 inline
00447 mln_ch_value(I, mln_meta_accu_result(A, mln_value(I)))
00448 transform_diagonal(const Meta_Accumulator<A>& a,
00449 const Image<I>& input, const Window<W>& win)
00450 {
00451 trace::entering("accu::transform_diagonal");
00452
00453 internal::transform_diagonal_tests(input, win);
00454
00455 typedef mln_accu_with(A, mln_value(I)) A_;
00456 A_ a_ = accu::unmeta(exact(a), mln_value(I)());
00457
00458 extension::adjust(input, geom::delta(win) + 1);
00459 mln_ch_value(I, mln_result(A_)) output;
00460 output = internal::transform_diagonal_dispatch(a_, input, win);
00461
00462 trace::exiting("accu::transform_diagonal");
00463 return output;
00464 }
00465
00466
00467 # endif // ! MLN_INCLUDE_ONLY
00468
00469 }
00470
00471 }
00472
00473
00474 #endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH