Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 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_CORE_CONCEPT_WINDOW_HH 00027 # define MLN_CORE_CONCEPT_WINDOW_HH 00028 00036 00037 # include <mln/core/concept/object.hh> 00038 # include <mln/core/concept/iterator.hh> 00039 # include <mln/trait/windows.hh> 00040 00041 # include <mln/core/site_set/p_array.hh> 00042 # include <mln/core/internal/geom_bbox.hh> // For use in convert::from_to. 00043 # include <mln/convert/from_to.hxx> 00044 # include <mln/util/array.hh> 00045 00046 00047 00048 # define mln_is_simple_window(W) \ 00049 \ 00050 mln::metal::and_< mlc_is(mln_trait_window_size(W), \ 00051 mln::trait::window::size::fixed), \ 00052 mln::metal::and_< mlc_is(mln_trait_window_support(W), \ 00053 mln::trait::window::support::regular), \ 00054 mlc_is(mln_trait_window_definition(W), \ 00055 mln::trait::window::definition::unique) > > 00056 00057 00058 # define mln_is_fastest_IW(I, W) \ 00059 \ 00060 mlc_and(mlc_is(mln_trait_image_speed(I), \ 00061 trait::image::speed::fastest), \ 00062 mln_is_simple_window(W)) 00063 00064 00065 00066 namespace mln 00067 { 00068 00069 // Forward declarations. 00070 template <typename E> struct Window; 00071 template <typename E> struct Image; 00072 00073 00074 // Window category flag type. 00075 template <> 00076 struct Window<void> 00077 { 00078 typedef Object<void> super; 00079 }; 00080 00081 00086 template <typename E> 00087 struct Window : public Object<E> 00088 { 00089 typedef Window<void> category; 00090 00091 /* 00092 typedef site; 00093 typedef psite; 00094 typedef dpsite; 00095 00096 typedef qiter; 00097 typedef fwd_qiter; 00098 typedef bkd_qiter; 00099 */ 00100 00101 protected: 00102 Window(); 00103 }; 00104 00105 00106 template <typename Wl, typename Wr> 00107 bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs); 00108 00109 00110 template <typename W> 00111 std::ostream& operator<<(std::ostream& ostr, const Window<W>& win); 00112 00113 00114 // FIXME: Move as a method of Image? 00115 template <typename I, typename W> 00116 util::array<int> 00117 offsets_wrt(const Image<I>& ima, const Window<W>& win); 00118 00119 template <typename I, typename W> 00120 util::array<int> 00121 positive_offsets_wrt(const Image<I>& ima, const Window<W>& win); 00122 00123 template <typename I, typename W> 00124 util::array<int> 00125 negative_offsets_wrt(const Image<I>& ima, const Window<W>& win); 00126 00127 00128 00129 namespace convert 00130 { 00131 00132 namespace over_load 00133 { 00134 00135 template <typename W, typename I> 00136 void 00137 from_to_(const Window<W>& from, Image<I>& to); 00138 00139 } // end of namespace mln::convert::over_load 00140 00141 } // end of namespace mln::convert 00142 00143 00144 00145 # ifndef MLN_INCLUDE_ONLY 00146 00147 namespace internal 00148 { 00149 00150 // size: fixed or unknown. 00151 00152 template <typename trait_size, typename E> 00153 struct window_size_check 00154 { 00155 static void run() { /* No requirement. */ } 00156 }; 00157 00158 template <typename E> 00159 struct window_size_check< mln::trait::window::size::fixed, E > 00160 { 00161 static void run() 00162 { 00163 unsigned (E::*m)() const = & E::size; 00164 m = 0; 00165 } 00166 }; 00167 00168 // support: regular or irregular. 00169 00170 template <typename trait_support, typename E> 00171 struct window_support_check 00172 { 00173 static void run() { /* No requirement. */ } 00174 }; 00175 00176 template <typename E> 00177 struct window_support_check< mln::trait::window::support::regular, E > 00178 { 00179 static void run_extra() 00180 { 00181 // Associated type. 00182 typedef mln_regular(E) regular; 00183 00184 // Methods. 00185 bool (E::*m1)() const = &E::is_centered; 00186 m1 = 0; 00187 bool (E::*m2)() const = &E::is_symmetric; 00188 m2 = 0; 00189 void (E::*m3)() = &E::sym; 00190 m3 = 0; 00191 unsigned (E::*m4)() const = &E::delta; 00192 m4 = 0; 00193 bool (E::*m5)() const = &E::is_valid; 00194 m5 = 0; 00195 } 00196 00197 static void run(mln::trait::window::definition::unique) 00198 { 00199 typedef mln_dpsite(E) D; 00200 const D& (E::*m1)(unsigned) const = &E::dp; 00201 m1 = 0; 00202 bool (E::*m2)(const D&) const = &E::has; 00203 m2 = 0; 00204 run_extra(); 00205 } 00206 00207 static void run(mln::trait::window::definition::n_ary) 00208 { 00209 run_extra(); 00210 } 00211 00212 static void run(mln::trait::window::definition::varying) 00213 { 00214 /* No requirement. */ 00215 } 00216 00217 static void run() 00218 { 00219 run(mln_trait_window_definition(E)()); 00220 } 00221 }; 00222 00223 // definition: unique, n_ary, or varying. 00224 00225 template <typename trait_definition, typename E> 00226 struct window_definition_check 00227 { 00228 static void run() { /* No requirement. */ } 00229 }; 00230 00231 template <typename E> 00232 struct window_definition_check< mln::trait::window::definition::multiple, E > 00233 { 00234 static void run() 00235 { 00236 typedef mln_element(E) W; 00237 void (E::*m1)(unsigned, const W&) = &E::set_window; 00238 m1 = 0; 00239 const W& (E::*m2)(unsigned) const = &E::window; 00240 m2 = 0; 00241 unsigned (E::*m3)() const = &E::nwindows; 00242 m3 = 0; 00243 } 00244 }; 00245 00246 } // end of namespace mln::internal 00247 00248 00249 template <typename E> 00250 inline 00251 Window<E>::Window() 00252 { 00253 // Check properties. 00254 mlc_not_equal( mln_trait_window_size(E), mln::trait::undef )::check(); 00255 mlc_not_equal( mln_trait_window_support(E), mln::trait::undef )::check(); 00256 mlc_not_equal( mln_trait_window_definition(E), mln::trait::undef )::check(); 00257 00258 // Check associated types. 00259 typedef mln_site(E) site; 00260 typedef mln_psite(E) psite; 00261 typedef mln_dpsite(E) dpsite; 00262 typedef mln_qiter(E) qiter; 00263 typedef mln_fwd_qiter(E) fwd_qiter; 00264 typedef mln_bkd_qiter(E) bkd_qiter; 00265 00266 // Check methods depending upon properties. 00267 internal::window_size_check < mln_trait_window_size(E), E >::run(); 00268 internal::window_support_check < mln_trait_window_support(E), E >::run(); 00269 internal::window_definition_check< mln_trait_window_definition(E), E >::run(); 00270 } 00271 00272 template <typename Wl, typename Wr> 00273 inline 00274 bool operator==(const Window<Wl>& lhs, const Window<Wr>& rhs) 00275 { 00276 return exact(lhs).std_vector() == exact(rhs).std_vector(); 00277 } 00278 00279 00280 // Operator <<. 00281 00282 namespace internal 00283 { 00284 00285 template <typename W> 00286 inline 00287 void print(trait::window::definition::unique, 00288 std::ostream& ostr, const W& win) // FIXME: Add Window<W> to win? 00289 { 00290 win.print(ostr); 00291 } 00292 00293 template <typename W> 00294 inline 00295 void print(trait::window::definition::multiple, 00296 std::ostream& ostr, const W& win) // FIXME: Add Window<W> to win? 00297 { 00298 ostr << "["; 00299 const unsigned nw = win.nwindows(); 00300 for (unsigned w = 0; w < nw; ++w) 00301 { 00302 ostr << " #" << w << ':'; 00303 win.window_(w).print(ostr); 00304 } 00305 ostr << " ]"; 00306 } 00307 00308 } // end of namespace mln::internal 00309 00310 template <typename W> 00311 inline 00312 std::ostream& operator<<(std::ostream& ostr, const Window<W>& win) 00313 { 00314 mlc_is(mln_trait_window_support(W), 00315 trait::window::support::regular)::check(); 00316 mlc_is_not(mln_trait_window_definition(W), 00317 trait::window::definition::varying)::check(); 00318 // FIXME: test on is_empty? 00319 internal::print(mln_trait_window_definition(W)(), 00320 ostr, exact(win)); 00321 return ostr; 00322 } 00323 00324 00325 template <typename I, typename W> 00326 inline 00327 util::array<int> 00328 offsets_wrt(const Image<I>& ima_, const Window<W>& win_) 00329 { 00330 mln_is_simple_window(W)::check(); 00331 00332 const I& ima = exact(ima_); 00333 const W& win = exact(win_); 00334 mln_precondition(ima.is_valid()); 00335 mln_precondition(win.is_valid()); 00336 00337 util::array<int> arr; 00338 unsigned n = win.size(); 00339 00340 for (unsigned i = 0; i < n; ++i) 00341 arr.append(ima.delta_index(win.dp(i))); 00342 00343 return arr; 00344 } 00345 00346 00347 template <typename I, typename W> 00348 inline 00349 util::array<int> 00350 positive_offsets_wrt(const Image<I>& ima_, const Window<W>& win_) 00351 { 00352 mln_is_simple_window(W)::check(); 00353 00354 const I& ima = exact(ima_); 00355 const W& win = exact(win_); 00356 mln_precondition(ima.is_valid()); 00357 mln_precondition(win.is_valid()); 00358 00359 util::array<int> arr; 00360 unsigned n = win.size(); 00361 00362 for (unsigned i = 0; i < n; ++i) 00363 { 00364 int offset = ima.delta_index(win.dp(i)); 00365 if (offset > 0) 00366 arr.append(offset); 00367 } 00368 00369 return arr; 00370 } 00371 00372 00373 template <typename I, typename W> 00374 inline 00375 util::array<int> 00376 negative_offsets_wrt(const Image<I>& ima_, const Window<W>& win_) 00377 { 00378 mln_is_simple_window(W)::check(); 00379 00380 const I& ima = exact(ima_); 00381 const W& win = exact(win_); 00382 mln_precondition(ima.is_valid()); 00383 mln_precondition(win.is_valid()); 00384 00385 util::array<int> arr; 00386 unsigned n = win.size(); 00387 00388 for (unsigned i = 0; i < n; ++i) 00389 { 00390 int offset = ima.delta_index(win.dp(i)); 00391 if (offset < 0) 00392 arr.append(offset); 00393 } 00394 00395 return arr; 00396 } 00397 00398 00399 namespace convert 00400 { 00401 00402 namespace over_load 00403 { 00404 00405 template <typename W, typename I> 00406 void 00407 from_to_(const Window<W>& win_, Image<I>& ima_) 00408 { 00409 mln_is_simple_window(W)::check(); 00410 typedef mln_psite(I) P; 00411 mlc_converts_to(mln_dpsite(W), mln_delta(P))::check(); 00412 mlc_equal(mln_value(I), bool)::check(); 00413 00414 const W& win = exact(win_); 00415 I& ima = exact(ima_); 00416 00417 mln_precondition(win.is_valid()); 00418 mln_precondition(! ima.is_valid()); 00419 00420 // Hack (below) to avoid circular dependency. 00421 ima.init_(mln::internal::geom_bbox(win)); 00422 { 00423 // data::fill(ima, false) is: 00424 mln_piter(I) p(ima.domain()); 00425 for_all(p) 00426 ima(p) = false; 00427 } 00428 unsigned n = win.size(); 00429 for (unsigned i = 0; i < n; ++i) 00430 ima(convert::to<P>(win.dp(i))) = true; 00431 } 00432 00433 } // end of namespace mln::convert::over_load 00434 00435 } // end of namespace mln::convert 00436 00437 # endif // ! MLN_INCLUDE_ONLY 00438 00439 } // end of namespace mln 00440 00441 00442 #endif // ! MLN_CORE_CONCEPT_WINDOW_HH