• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

window.hh

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

Generated on Tue Oct 4 2011 15:25:09 for Milena (Olena) by  doxygen 1.7.1