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

image2d.hh

00001 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
00002 // Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_CORE_IMAGE_IMAGE2D_HH
00028 # define MLN_CORE_IMAGE_IMAGE2D_HH
00029 
00037 
00038 # include <mln/core/internal/image_primary.hh>
00039 # include <mln/core/internal/fixme.hh>
00040 # include <mln/core/alias/box2d.hh>
00041 # include <mln/core/routine/init.hh>
00042 
00043 # include <mln/border/thickness.hh>
00044 # include <mln/value/set.hh>
00045 # include <mln/fun/i2v/all_to.hh>
00046 // # include <mln/core/line_piter.hh> // FIXME
00047 
00048 
00049 
00050 // FIXME:
00051 
00052 // # include <mln/core/pixter2d.hh>
00053 // # include <mln/core/dpoints_pixter.hh>
00054 
00055 
00056 
00057 
00058 namespace mln
00059 {
00060 
00061   // Forward declaration.
00062   template <typename T> struct image2d;
00063 
00064 
00065   namespace internal
00066   {
00067 
00069     template <typename T>
00070     struct data< image2d<T> >
00071     {
00072       data(const box2d& b, unsigned bdr);
00073       ~data();
00074 
00075       T*  buffer_;
00076       T** array_;
00077 
00078       box2d b_;  // theoretical box
00079       unsigned bdr_;
00080       box2d vb_; // virtual box, i.e., box including the virtual border
00081 
00082       void update_vb_();
00083       void allocate_();
00084       void deallocate_();
00085       void swap_(data< image2d<T> >& other_);
00086       void reallocate_(unsigned new_border);
00087     };
00088 
00089   } // end of namespace mln::internal
00090 
00091 
00092   namespace trait
00093   {
00094 
00095     template <typename T>
00096     struct image_< image2d<T> > : default_image_< T, image2d<T> >
00097     {
00098       // misc
00099       typedef trait::image::category::primary category;
00100       typedef trait::image::speed::fastest    speed;
00101       typedef trait::image::size::regular     size;
00102 
00103       // value
00104       typedef trait::image::vw_io::none                    vw_io;
00105       typedef trait::image::vw_set::none                   vw_set;
00106       typedef trait::image::value_access::direct           value_access;
00107       typedef trait::image::value_storage::one_block       value_storage;
00108       typedef trait::image::value_browsing::site_wise_only value_browsing;
00109       typedef trait::image::value_alignment::with_grid     value_alignment;
00110       typedef trait::image::value_io::read_write           value_io;
00111 
00112       // site / domain
00113       typedef trait::image::pw_io::read_write        pw_io;
00114       typedef trait::image::localization::basic_grid localization;
00115       typedef trait::image::dimension::two_d         dimension;
00116 
00117       // extended domain
00118       typedef trait::image::ext_domain::extendable ext_domain;
00119       typedef trait::image::ext_value::multiple    ext_value;
00120       typedef trait::image::ext_io::read_write     ext_io;
00121     };
00122 
00123   } // end of namespace mln::trait
00124 
00125 
00126 
00134   //
00135   template <typename T>
00136   class image2d : public internal::image_primary< T, mln::box2d, image2d<T> >
00137   {
00138     typedef internal::image_primary< T, mln::box2d, image2d<T> > super_;
00139   public:
00140 
00142     typedef T         value;
00143 
00145     typedef const T& rvalue;
00146 
00148     typedef T&       lvalue;
00149 
00150 
00152     typedef image2d< tag::value_<T> > skeleton;
00153 
00154 
00156     image2d();
00157 
00160     image2d(int nrows, int ncols, unsigned bdr = border::thickness);
00161 
00164     image2d(const box2d& b, unsigned bdr = border::thickness);
00165 
00166 
00168     void init_(const box2d& b, unsigned bdr = border::thickness);
00169 
00170 
00172     bool has(const point2d& p) const;
00173 
00175     const box2d& domain() const;
00176 
00178     const box2d& bbox() const;
00179 
00180     // virtual box, i.e., box including the virtual border
00181     const box2d& vbbox() const;
00182 
00184     const T& operator()(const point2d& p) const;
00185 
00187     T& operator()(const point2d& p);
00188 
00189 
00190     template <typename P>
00191     T& alt(const P& p)
00192     {
00193       typedef def::coord coord_t;
00194       mln_precondition(this->has(p));
00195 
00196 //       std::cout << (coord_t*)(&p.p_hook_()) << ' '
00197 //              << &(p.row()) << ' '
00198 //              << &(p.get_subject()) << ' '
00199 //              << &(p.to_site()) << std::endl;
00200 
00201       // return this->data_->array_[p.to_site().row()][p.to_site().col()];
00202       // return this->data_->array_[p.row()][p.col()];
00203       // return this->data_->array_[p.get_subject().row()][p.get_subject().col()];
00204       // return this->data_->array_ [*(coord_t*)(&p.get_subject())] [*((coord_t*)(&p.get_subject()) + 1)];
00205       return this->data_->array_ [*(coord_t*)(&p.p_hook_())] [*((coord_t*)(&p.p_hook_()) + 1)];
00206       // return this->data_->array_[0][0];;
00207     }
00208 
00209 
00210     // Specific methods:
00211     // -----------------
00212 
00214     const T& at_(mln::def::coord row, mln::def::coord col) const;
00215 
00217     T& at_(mln::def::coord row, mln::def::coord col);
00218 
00220     unsigned nrows() const;
00221 
00223     unsigned ncols() const;
00224 
00225 
00226     // As a fastest image:
00227     // -------------------
00228 
00229     // Give the index of a point.
00230     using super_::index_of_point;
00231 
00233     unsigned border() const;
00234 
00236     unsigned nelements() const;
00237 
00239     const T& element(unsigned i) const;
00240 
00242     T& element(unsigned i);
00243 
00245     int delta_index(const dpoint2d& dp) const;
00246 
00248     point2d point_at_index(unsigned i) const;
00249 
00251     const T* buffer() const;
00252 
00254     T* buffer();
00255 
00256 
00258     void resize_(unsigned new_border);
00259   };
00260 
00261 
00262 
00263   // Forward declaration
00264 
00265   template <typename T>
00266   void init_(tag::border_t, unsigned& bdr, const image2d<T>& model);
00267 
00268   template <typename T, typename J>
00269   void init_(tag::image_t, mln::image2d<T>& target, const J& model);
00270 
00271 
00272 
00273 # ifndef MLN_INCLUDE_ONLY
00274 
00275   // init_
00276 
00277   template <typename T>
00278   inline
00279   void init_(tag::border_t, unsigned& bdr, const image2d<T>& model)
00280   {
00281     bdr = model.border();
00282   }
00283 
00284   template <typename T, typename J>
00285   inline
00286   void init_(tag::image_t, image2d<T>& target, const J& model)
00287   {
00288     box2d b;
00289     init_(tag::bbox, b, model);
00290     unsigned bdr;
00291     init_(tag::border, bdr, model);
00292     target.init_(b, bdr);
00293   }
00294 
00295 
00296   // internal::data< image2d<T> >
00297 
00298   namespace internal
00299   {
00300     template <typename T>
00301     inline
00302     data< image2d<T> >::data(const box2d& b, unsigned bdr)
00303       : buffer_(0),
00304         array_ (0),
00305         b_     (b),
00306         bdr_   (bdr)
00307     {
00308       allocate_();
00309     }
00310 
00311     template <typename T>
00312     inline
00313     data< image2d<T> >::~data()
00314     {
00315       deallocate_();
00316     }
00317 
00318     template <typename T>
00319     inline
00320     void
00321     data< image2d<T> >::update_vb_()
00322     {
00323       vb_.pmin() = b_.pmin() - dpoint2d(all_to(bdr_));
00324       vb_.pmax() = b_.pmax() + dpoint2d(all_to(bdr_));
00325     }
00326 
00327     template <typename T>
00328     inline
00329     void
00330     data< image2d<T> >::allocate_()
00331     {
00332       update_vb_();
00333       unsigned
00334         nr = vb_.len(0),
00335         nc = vb_.len(1);
00336       buffer_ = new T[nr * nc];
00337       array_ = new T*[nr];
00338       T* buf = buffer_ - vb_.pmin().col();
00339       for (unsigned i = 0; i < nr; ++i)
00340         {
00341           array_[i] = buf;
00342           buf += nc;
00343         }
00344       array_ -= vb_.pmin().row();
00345       mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
00346       mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_);
00347     }
00348 
00349     template <typename T>
00350     inline
00351     void
00352     data< image2d<T> >::deallocate_()
00353     {
00354       if (buffer_)
00355         {
00356           delete[] buffer_;
00357           buffer_ = 0;
00358         }
00359       if (array_)
00360         {
00361           array_ += vb_.pmin().row();
00362           delete[] array_;
00363           array_ = 0;
00364         }
00365     }
00366 
00367     template <typename T>
00368     inline
00369     void
00370     data< image2d<T> >::swap_(data< image2d<T> >& other_)
00371     {
00372       data< image2d<T> > self_ = *this;
00373       *this = other_;
00374       other_ = self_;
00375     }
00376 
00377     template <typename T>
00378     inline
00379     void
00380     data< image2d<T> >::reallocate_(unsigned new_border)
00381     {
00382       data< image2d<T> >& tmp = *(new data< image2d<T> >(this->b_, new_border));
00383       this->swap_(tmp);
00384     }
00385 
00386 
00387   } // end of namespace mln::internal
00388 
00389 
00390   // image2d<T>
00391 
00392   template <typename T>
00393   inline
00394   image2d<T>::image2d()
00395   {
00396   }
00397 
00398   template <typename T>
00399   inline
00400   image2d<T>::image2d(int nrows, int ncols, unsigned bdr)
00401   {
00402     init_(make::box2d(nrows, ncols), bdr);
00403   }
00404 
00405   template <typename T>
00406   inline
00407   image2d<T>::image2d(const box2d& b, unsigned bdr)
00408   {
00409     init_(b, bdr);
00410   }
00411 
00412   template <typename T>
00413   inline
00414   void
00415   image2d<T>::init_(const box2d& b, unsigned bdr)
00416   {
00417     mln_precondition(! this->is_valid());
00418     this->data_ = new internal::data< image2d<T> >(b, bdr);
00419   }
00420 
00421   template <typename T>
00422   inline
00423   const box2d&
00424   image2d<T>::domain() const
00425   {
00426     mln_precondition(this->is_valid());
00427     return this->data_->b_;
00428   }
00429 
00430   template <typename T>
00431   inline
00432   const box2d&
00433   image2d<T>::bbox() const
00434   {
00435     mln_precondition(this->is_valid());
00436     return this->data_->b_;
00437   }
00438 
00439   template <typename T>
00440   inline
00441   const box2d&
00442   image2d<T>::vbbox() const
00443   {
00444     mln_precondition(this->is_valid());
00445     return this->data_->vb_;
00446   }
00447 
00448   template <typename T>
00449   inline
00450   bool
00451   image2d<T>::has(const point2d& p) const
00452   {
00453     mln_precondition(this->is_valid());
00454     return this->data_->vb_.has(p);
00455   }
00456 
00457   template <typename T>
00458   inline
00459   const T&
00460   image2d<T>::operator()(const point2d& p) const
00461   {
00462     mln_precondition(this->has(p));
00463     return this->data_->array_[p.row()][p.col()];
00464   }
00465 
00466   template <typename T>
00467   inline
00468   T&
00469   image2d<T>::operator()(const point2d& p)
00470   {
00471     mln_precondition(this->has(p));
00472     return this->data_->array_[p.row()][p.col()];
00473   }
00474 
00475 
00476   // Specific methods:
00477 
00478   template <typename T>
00479   inline
00480   const T&
00481   image2d<T>::at_(mln::def::coord row, mln::def::coord col) const
00482   {
00483     mln_precondition(this->has(point2d(row, col)));
00484     return this->data_->array_[row][col];
00485   }
00486 
00487   template <typename T>
00488   inline
00489   T&
00490   image2d<T>::at_(mln::def::coord row, mln::def::coord col)
00491   {
00492     mln_precondition(this->has(point2d(row, col)));
00493     return this->data_->array_[row][col];
00494   }
00495 
00496   template <typename T>
00497   inline
00498   unsigned
00499   image2d<T>::nrows() const
00500   {
00501     mln_precondition(this->is_valid());
00502     return this->data_->b_.len(0);
00503   }
00504 
00505   template <typename T>
00506   inline
00507   unsigned
00508   image2d<T>::ncols() const
00509   {
00510     mln_precondition(this->is_valid());
00511     return this->data_->b_.len(1);
00512   }
00513 
00514 
00515   // As a fastest image:
00516 
00517   template <typename T>
00518   inline
00519   unsigned
00520   image2d<T>::border() const
00521   {
00522     mln_precondition(this->is_valid());
00523     return this->data_->bdr_;
00524   }
00525 
00526   template <typename T>
00527   inline
00528   unsigned
00529   image2d<T>::nelements() const
00530   {
00531     mln_precondition(this->is_valid());
00532     return this->data_->vb_.nsites();
00533   }
00534 
00535   template <typename T>
00536   inline
00537   const T&
00538   image2d<T>::element(unsigned i) const
00539   {
00540     mln_precondition(i < nelements());
00541     return *(this->data_->buffer_ + i);
00542   }
00543 
00544   template <typename T>
00545   inline
00546   T&
00547   image2d<T>::element(unsigned i)
00548   {
00549     mln_precondition(i < nelements());
00550     return *(this->data_->buffer_ + i);
00551   }
00552 
00553   template <typename T>
00554   inline
00555   const T*
00556   image2d<T>::buffer() const
00557   {
00558     mln_precondition(this->is_valid());
00559     return this->data_->buffer_;
00560   }
00561 
00562   template <typename T>
00563   inline
00564   T*
00565   image2d<T>::buffer()
00566   {
00567     mln_precondition(this->is_valid());
00568     return this->data_->buffer_;
00569   }
00570 
00571   template <typename T>
00572   inline
00573   int
00574   image2d<T>::delta_index(const dpoint2d& dp) const
00575   {
00576     mln_precondition(this->is_valid());
00577     int o = dp[0] * this->data_->vb_.len(1) + dp[1];
00578     return o;
00579   }
00580 
00581   template <typename T>
00582   inline
00583   point2d
00584   image2d<T>::point_at_index(unsigned i) const
00585   {
00586     mln_precondition(i < nelements());
00587     def::coord
00588       row = static_cast<def::coord>(i / this->data_->vb_.len(1) + this->data_->vb_.min_row()),
00589       col = static_cast<def::coord>(i % this->data_->vb_.len(1) + this->data_->vb_.min_col());
00590     point2d p = point2d(row, col);
00591     mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i);
00592     return p;
00593   }
00594 
00595   // Extra.
00596 
00597   template <typename T>
00598   inline
00599   void
00600   image2d<T>::resize_(unsigned new_border)
00601   {
00602     mln_precondition(this->is_valid());
00603     this->data_->reallocate_(new_border);
00604   }
00605 
00606 # endif // ! MLN_INCLUDE_ONLY
00607 
00608 } // end of namespace mln
00609 
00610 
00611 
00612 # include <mln/core/trait/pixter.hh>
00613 # include <mln/core/dpoints_pixter.hh>
00614 # include <mln/core/pixter2d.hh>
00615 // # include <mln/core/w_window.hh>
00616 
00617 
00618 namespace mln
00619 {
00620 
00621   namespace trait
00622   {
00623 
00624     // pixter
00625 
00626     template <typename T>
00627     struct fwd_pixter< image2d<T> >
00628     {
00629       typedef fwd_pixter2d< image2d<T> > ret;
00630     };
00631 
00632     template <typename T>
00633     struct fwd_pixter< const image2d<T> >
00634     {
00635       typedef fwd_pixter2d< const image2d<T> > ret;
00636     };
00637 
00638     template <typename T>
00639     struct bkd_pixter< image2d<T> >
00640     {
00641       typedef bkd_pixter2d< image2d<T> > ret;
00642     };
00643 
00644     template <typename T>
00645     struct bkd_pixter< const image2d<T> >
00646     {
00647       typedef bkd_pixter2d< const image2d<T> > ret;
00648     };
00649 
00650     // qixter
00651 
00652     template <typename T, typename W>
00653     struct fwd_qixter< image2d<T>, W >
00654     {
00655       typedef dpoints_fwd_pixter< image2d<T> > ret;
00656     };
00657 
00658     template <typename T, typename W>
00659     struct fwd_qixter< const image2d<T>, W >
00660     {
00661       typedef dpoints_fwd_pixter< const image2d<T> > ret;
00662     };
00663 
00664     template <typename T, typename W>
00665     struct bkd_qixter< image2d<T>, W >
00666     {
00667       typedef dpoints_bkd_pixter< image2d<T> > ret;
00668     };
00669 
00670     template <typename T, typename W>
00671     struct bkd_qixter< const image2d<T>, W >
00672     {
00673       typedef dpoints_bkd_pixter< const image2d<T> > ret;
00674     };
00675 
00676     // nixter
00677 
00678     template <typename T, typename N>
00679     struct fwd_nixter< image2d<T>, N >
00680     {
00681       typedef dpoints_fwd_pixter< image2d<T> > ret;
00682     };
00683 
00684     template <typename T, typename N>
00685     struct fwd_nixter< const image2d<T>, N >
00686     {
00687       typedef dpoints_fwd_pixter< const image2d<T> > ret;
00688     };
00689 
00690     template <typename T, typename N>
00691     struct bkd_nixter< image2d<T>, N >
00692     {
00693       typedef dpoints_bkd_pixter< image2d<T> > ret;
00694     };
00695 
00696     template <typename T, typename N>
00697     struct bkd_nixter< const image2d<T>, N >
00698     {
00699       typedef dpoints_bkd_pixter< const image2d<T> > ret;
00700     };
00701 
00702   } // end of namespace mln::trait
00703 
00704 } // end of namespace mln
00705 
00706 
00707 # include <mln/make/image.hh>
00708 # include <mln/make/image2d.hh>
00709 
00710 
00711 #endif // ! MLN_CORE_IMAGE_IMAGE2D_HH

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