Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 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 // Tests. 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 // Functors. 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; // Help g++-2.95. 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 // Functors (fastest versions). 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 // Both dispatch and implementation (hum...) 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 } // end of namespace mln::accu::internal 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 } // end of namespace mln::accu 00470 00471 } // end of namespace mln 00472 00473 00474 #endif // ! MLN_ACCU_TRANSFORM_DIAGONAL_HH