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_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>
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
00070 template <typename E> struct Window;
00071 template <typename E> struct Image;
00072
00073
00074
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
00093
00094
00095
00096
00097
00098
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
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 }
00140
00141 }
00142
00143
00144
00145 # ifndef MLN_INCLUDE_ONLY
00146
00147 namespace internal
00148 {
00149
00150
00151
00152 template <typename trait_size, typename E>
00153 struct window_size_check
00154 {
00155 static void run() { }
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
00169
00170 template <typename trait_support, typename E>
00171 struct window_support_check
00172 {
00173 static void run() { }
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
00182 typedef mln_regular(E) regular;
00183
00184
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
00215 }
00216
00217 static void run()
00218 {
00219 run(mln_trait_window_definition(E)());
00220 }
00221 };
00222
00223
00224
00225 template <typename trait_definition, typename E>
00226 struct window_definition_check
00227 {
00228 static void run() { }
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 }
00247
00248
00249 template <typename E>
00250 inline
00251 Window<E>::Window()
00252 {
00253
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
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
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
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)
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)
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 }
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
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
00421 ima.init_(mln::internal::geom_bbox(win));
00422 {
00423
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 }
00434
00435 }
00436
00437 # endif // ! MLN_INCLUDE_ONLY
00438
00439 }
00440
00441
00442 #endif // ! MLN_CORE_CONCEPT_WINDOW_HH