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

image2d.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_IMAGE_IMAGE2D_HH
00027 # define MLN_CORE_IMAGE_IMAGE2D_HH
00028 
00036 
00037 # include <mln/core/internal/image_primary.hh>
00038 # include <mln/core/internal/fixme.hh>
00039 # include <mln/core/alias/box2d.hh>
00040 # include <mln/core/routine/init.hh>
00041 
00042 # include <mln/border/thickness.hh>
00043 # include <mln/value/set.hh>
00044 # include <mln/fun/i2v/all_to.hh>
00045 // # include <mln/core/line_piter.hh> // FIXME
00046 
00047 
00048 
00049 // FIXME:
00050 
00051 // # include <mln/core/pixter2d.hh>
00052 // # include <mln/core/dpoints_pixter.hh>
00053 
00054 
00055 
00056 
00057 namespace mln
00058 {
00059 
00060   // Forward declaration.
00061   template <typename T> struct image2d;
00062 
00063 
00064   namespace internal
00065   {
00066 
00068     template <typename T>
00069     struct data< image2d<T> >
00070     {
00071       data(const box2d& b, unsigned bdr);
00072       ~data();
00073 
00074       T*  buffer_;
00075       T** array_;
00076 
00077       box2d b_;  // theoretical box
00078       unsigned bdr_;
00079       box2d vb_; // virtual box, i.e., box including the virtual border
00080 
00081       void update_vb_();
00082       void allocate_();
00083       void deallocate_();
00084       void swap_(data< image2d<T> >& other_);
00085       void reallocate_(unsigned new_border);
00086     };
00087 
00088   } // end of namespace mln::internal
00089 
00090 
00091   namespace trait
00092   {
00093 
00094     template <typename T>
00095     struct image_< image2d<T> > : default_image_< T, image2d<T> >
00096     {
00097       // misc
00098       typedef trait::image::category::primary category;
00099       typedef trait::image::speed::fastest    speed;
00100       typedef trait::image::size::regular     size;
00101 
00102       // value
00103       typedef trait::image::vw_io::none                    vw_io;
00104       typedef trait::image::vw_set::none                   vw_set;
00105       typedef trait::image::value_access::direct           value_access;
00106       typedef trait::image::value_storage::one_block       value_storage;
00107       typedef trait::image::value_browsing::site_wise_only value_browsing;
00108       typedef trait::image::value_alignment::with_grid     value_alignment;
00109       typedef trait::image::value_io::read_write           value_io;
00110 
00111       // site / domain
00112       typedef trait::image::pw_io::read_write        pw_io;
00113       typedef trait::image::localization::basic_grid localization;
00114       typedef trait::image::dimension::two_d         dimension;
00115 
00116       // extended domain
00117       typedef trait::image::ext_domain::extendable ext_domain;
00118       typedef trait::image::ext_value::multiple    ext_value;
00119       typedef trait::image::ext_io::read_write     ext_io;
00120     };
00121 
00122   } // end of namespace mln::trait
00123 
00124 
00125 
00133   //
00134   template <typename T>
00135   class image2d : public internal::image_primary< T, mln::box2d, image2d<T> >
00136   {
00137     typedef internal::image_primary< T, mln::box2d, image2d<T> > super_;
00138   public:
00139 
00141     typedef T         value;
00142 
00144     typedef const T& rvalue;
00145 
00147     typedef T&       lvalue;
00148 
00149 
00151     typedef image2d< tag::value_<T> > skeleton;
00152 
00153 
00155     image2d();
00156 
00159     image2d(int nrows, int ncols, unsigned bdr = border::thickness);
00160 
00163     image2d(const box2d& b, unsigned bdr = border::thickness);
00164 
00165 
00167     void init_(const box2d& b, unsigned bdr = border::thickness);
00168 
00169 
00171     bool has(const point2d& p) const;
00172 
00174     const box2d& domain() const;
00175 
00177     const box2d& bbox() const;
00178 
00180     const T& operator()(const point2d& p) const;
00181 
00183     T& operator()(const point2d& p);
00184 
00185 
00186     template <typename P>
00187     T& alt(const P& p)
00188     {
00189       typedef def::coord coord_t;
00190       mln_precondition(this->has(p));
00191 
00192 //       std::cout << (coord_t*)(&p.p_hook_()) << ' '
00193 //              << &(p.row()) << ' '
00194 //              << &(p.get_subject()) << ' '
00195 //              << &(p.to_site()) << std::endl;
00196 
00197       // return this->data_->array_[p.to_site().row()][p.to_site().col()];
00198       // return this->data_->array_[p.row()][p.col()];
00199       // return this->data_->array_[p.get_subject().row()][p.get_subject().col()];
00200       // return this->data_->array_ [*(coord_t*)(&p.get_subject())] [*((coord_t*)(&p.get_subject()) + 1)];
00201       return this->data_->array_ [*(coord_t*)(&p.p_hook_())] [*((coord_t*)(&p.p_hook_()) + 1)];
00202       // return this->data_->array_[0][0];;
00203     }
00204 
00205 
00206     // Specific methods:
00207     // -----------------
00208 
00210     const T& at_(mln::def::coord row, mln::def::coord col) const;
00211 
00213     T& at_(mln::def::coord row, mln::def::coord col);
00214 
00216     unsigned nrows() const;
00217 
00219     unsigned ncols() const;
00220 
00221 
00222     // As a fastest image:
00223     // -------------------
00224 
00225     // Give the index of a point.
00226     using super_::index_of_point;
00227 
00229     unsigned border() const;
00230 
00232     unsigned nelements() const;
00233 
00235     const T& element(unsigned i) const;
00236 
00238     T& element(unsigned i);
00239 
00241     int delta_index(const dpoint2d& dp) const;
00242 
00244     point2d point_at_index(unsigned i) const;
00245 
00247     const T* buffer() const;
00248 
00250     T* buffer();
00251 
00252 
00254     void resize_(unsigned new_border);
00255   };
00256 
00257 
00258 
00259   // Forward declaration
00260 
00261   template <typename T>
00262   void init_(tag::border_t, unsigned& bdr, const image2d<T>& model);
00263 
00264   template <typename T, typename J>
00265   void init_(tag::image_t, mln::image2d<T>& target, const J& model);
00266 
00267 
00268 
00269 # ifndef MLN_INCLUDE_ONLY
00270 
00271   // init_
00272 
00273   template <typename T>
00274   inline
00275   void init_(tag::border_t, unsigned& bdr, const image2d<T>& model)
00276   {
00277     bdr = model.border();
00278   }
00279 
00280   template <typename T, typename J>
00281   inline
00282   void init_(tag::image_t, image2d<T>& target, const J& model)
00283   {
00284     box2d b;
00285     init_(tag::bbox, b, model);
00286     unsigned bdr;
00287     init_(tag::border, bdr, model);
00288     target.init_(b, bdr);
00289   }
00290 
00291 
00292   // internal::data< image2d<T> >
00293 
00294   namespace internal
00295   {
00296     template <typename T>
00297     inline
00298     data< image2d<T> >::data(const box2d& b, unsigned bdr)
00299       : buffer_(0),
00300         array_ (0),
00301         b_     (b),
00302         bdr_   (bdr)
00303     {
00304       allocate_();
00305     }
00306 
00307     template <typename T>
00308     inline
00309     data< image2d<T> >::~data()
00310     {
00311       deallocate_();
00312     }
00313 
00314     template <typename T>
00315     inline
00316     void
00317     data< image2d<T> >::update_vb_()
00318     {
00319       vb_.pmin() = b_.pmin() - dpoint2d(all_to(bdr_));
00320       vb_.pmax() = b_.pmax() + dpoint2d(all_to(bdr_));
00321     }
00322 
00323     template <typename T>
00324     inline
00325     void
00326     data< image2d<T> >::allocate_()
00327     {
00328       update_vb_();
00329       unsigned
00330         nr = vb_.len(0),
00331         nc = vb_.len(1);
00332       buffer_ = new T[nr * nc];
00333       array_ = new T*[nr];
00334       T* buf = buffer_ - vb_.pmin().col();
00335       for (unsigned i = 0; i < nr; ++i)
00336         {
00337           array_[i] = buf;
00338           buf += nc;
00339         }
00340       array_ -= vb_.pmin().row();
00341       mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
00342       mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_);
00343     }
00344 
00345     template <typename T>
00346     inline
00347     void
00348     data< image2d<T> >::deallocate_()
00349     {
00350       if (buffer_)
00351         {
00352           delete[] buffer_;
00353           buffer_ = 0;
00354         }
00355       if (array_)
00356         {
00357           array_ += vb_.pmin().row();
00358           delete[] array_;
00359           array_ = 0;
00360         }
00361     }
00362 
00363     template <typename T>
00364     inline
00365     void
00366     data< image2d<T> >::swap_(data< image2d<T> >& other_)
00367     {
00368       data< image2d<T> > self_ = *this;
00369       *this = other_;
00370       other_ = self_;
00371     }
00372 
00373     template <typename T>
00374     inline
00375     void
00376     data< image2d<T> >::reallocate_(unsigned new_border)
00377     {
00378       data< image2d<T> >& tmp = *(new data< image2d<T> >(this->b_, new_border));
00379       this->swap_(tmp);
00380     }
00381 
00382 
00383   } // end of namespace mln::internal
00384 
00385 
00386   // image2d<T>
00387 
00388   template <typename T>
00389   inline
00390   image2d<T>::image2d()
00391   {
00392   }
00393 
00394   template <typename T>
00395   inline
00396   image2d<T>::image2d(int nrows, int ncols, unsigned bdr)
00397   {
00398     init_(make::box2d(nrows, ncols), bdr);
00399   }
00400 
00401   template <typename T>
00402   inline
00403   image2d<T>::image2d(const box2d& b, unsigned bdr)
00404   {
00405     init_(b, bdr);
00406   }
00407 
00408   template <typename T>
00409   inline
00410   void
00411   image2d<T>::init_(const box2d& b, unsigned bdr)
00412   {
00413     mln_precondition(! this->is_valid());
00414     this->data_ = new internal::data< image2d<T> >(b, bdr);
00415   }
00416 
00417   template <typename T>
00418   inline
00419   const box2d&
00420   image2d<T>::domain() const
00421   {
00422     mln_precondition(this->is_valid());
00423     return this->data_->b_;
00424   }
00425 
00426   template <typename T>
00427   inline
00428   const box2d&
00429   image2d<T>::bbox() const
00430   {
00431     mln_precondition(this->is_valid());
00432     return this->data_->b_;
00433   }
00434 
00435   template <typename T>
00436   inline
00437   bool
00438   image2d<T>::has(const point2d& p) const
00439   {
00440     mln_precondition(this->is_valid());
00441     return this->data_->vb_.has(p);
00442   }
00443 
00444   template <typename T>
00445   inline
00446   const T&
00447   image2d<T>::operator()(const point2d& p) const
00448   {
00449     mln_precondition(this->has(p));
00450     return this->data_->array_[p.row()][p.col()];
00451   }
00452 
00453   template <typename T>
00454   inline
00455   T&
00456   image2d<T>::operator()(const point2d& p)
00457   {
00458     mln_precondition(this->has(p));
00459     return this->data_->array_[p.row()][p.col()];
00460   }
00461 
00462 
00463   // Specific methods:
00464 
00465   template <typename T>
00466   inline
00467   const T&
00468   image2d<T>::at_(mln::def::coord row, mln::def::coord col) const
00469   {
00470     mln_precondition(this->has(point2d(row, col)));
00471     return this->data_->array_[row][col];
00472   }
00473 
00474   template <typename T>
00475   inline
00476   T&
00477   image2d<T>::at_(mln::def::coord row, mln::def::coord col)
00478   {
00479     mln_precondition(this->has(point2d(row, col)));
00480     return this->data_->array_[row][col];
00481   }
00482 
00483   template <typename T>
00484   inline
00485   unsigned
00486   image2d<T>::nrows() const
00487   {
00488     mln_precondition(this->is_valid());
00489     return this->data_->b_.len(0);
00490   }
00491 
00492   template <typename T>
00493   inline
00494   unsigned
00495   image2d<T>::ncols() const
00496   {
00497     mln_precondition(this->is_valid());
00498     return this->data_->b_.len(1);
00499   }
00500 
00501 
00502   // As a fastest image:
00503 
00504   template <typename T>
00505   inline
00506   unsigned
00507   image2d<T>::border() const
00508   {
00509     mln_precondition(this->is_valid());
00510     return this->data_->bdr_;
00511   }
00512 
00513   template <typename T>
00514   inline
00515   unsigned
00516   image2d<T>::nelements() const
00517   {
00518     mln_precondition(this->is_valid());
00519     return this->data_->vb_.nsites();
00520   }
00521 
00522   template <typename T>
00523   inline
00524   const T&
00525   image2d<T>::element(unsigned i) const
00526   {
00527     mln_precondition(i < nelements());
00528     return *(this->data_->buffer_ + i);
00529   }
00530 
00531   template <typename T>
00532   inline
00533   T&
00534   image2d<T>::element(unsigned i)
00535   {
00536     mln_precondition(i < nelements());
00537     return *(this->data_->buffer_ + i);
00538   }
00539 
00540   template <typename T>
00541   inline
00542   const T*
00543   image2d<T>::buffer() const
00544   {
00545     mln_precondition(this->is_valid());
00546     return this->data_->buffer_;
00547   }
00548 
00549   template <typename T>
00550   inline
00551   T*
00552   image2d<T>::buffer()
00553   {
00554     mln_precondition(this->is_valid());
00555     return this->data_->buffer_;
00556   }
00557 
00558   template <typename T>
00559   inline
00560   int
00561   image2d<T>::delta_index(const dpoint2d& dp) const
00562   {
00563     mln_precondition(this->is_valid());
00564     int o = dp[0] * this->data_->vb_.len(1) + dp[1];
00565     return o;
00566   }
00567 
00568   template <typename T>
00569   inline
00570   point2d
00571   image2d<T>::point_at_index(unsigned i) const
00572   {
00573     mln_precondition(i < nelements());
00574     def::coord
00575       row = static_cast<def::coord>(i / this->data_->vb_.len(1) + this->data_->vb_.min_row()),
00576       col = static_cast<def::coord>(i % this->data_->vb_.len(1) + this->data_->vb_.min_col());
00577     point2d p = point2d(row, col);
00578     mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i);
00579     return p;
00580   }
00581 
00582   // Extra.
00583 
00584   template <typename T>
00585   inline
00586   void
00587   image2d<T>::resize_(unsigned new_border)
00588   {
00589     mln_precondition(this->is_valid());
00590     this->data_->reallocate_(new_border);
00591   }
00592 
00593 # endif // ! MLN_INCLUDE_ONLY
00594 
00595 } // end of namespace mln
00596 
00597 
00598 
00599 # include <mln/core/trait/pixter.hh>
00600 # include <mln/core/dpoints_pixter.hh>
00601 # include <mln/core/pixter2d.hh>
00602 // # include <mln/core/w_window.hh>
00603 
00604 
00605 namespace mln
00606 {
00607 
00608   namespace trait
00609   {
00610 
00611     // pixter
00612 
00613     template <typename T>
00614     struct fwd_pixter< image2d<T> >
00615     {
00616       typedef fwd_pixter2d< image2d<T> > ret;
00617     };
00618 
00619     template <typename T>
00620     struct fwd_pixter< const image2d<T> >
00621     {
00622       typedef fwd_pixter2d< const image2d<T> > ret;
00623     };
00624 
00625     template <typename T>
00626     struct bkd_pixter< image2d<T> >
00627     {
00628       typedef bkd_pixter2d< image2d<T> > ret;
00629     };
00630 
00631     template <typename T>
00632     struct bkd_pixter< const image2d<T> >
00633     {
00634       typedef bkd_pixter2d< const image2d<T> > ret;
00635     };
00636 
00637     // qixter
00638 
00639     template <typename T, typename W>
00640     struct fwd_qixter< image2d<T>, W >
00641     {
00642       typedef dpoints_fwd_pixter< image2d<T> > ret;
00643     };
00644 
00645     template <typename T, typename W>
00646     struct fwd_qixter< const image2d<T>, W >
00647     {
00648       typedef dpoints_fwd_pixter< const image2d<T> > ret;
00649     };
00650 
00651     template <typename T, typename W>
00652     struct bkd_qixter< image2d<T>, W >
00653     {
00654       typedef dpoints_bkd_pixter< image2d<T> > ret;
00655     };
00656 
00657     template <typename T, typename W>
00658     struct bkd_qixter< const image2d<T>, W >
00659     {
00660       typedef dpoints_bkd_pixter< const image2d<T> > ret;
00661     };
00662 
00663     // nixter
00664 
00665     template <typename T, typename N>
00666     struct fwd_nixter< image2d<T>, N >
00667     {
00668       typedef dpoints_fwd_pixter< image2d<T> > ret;
00669     };
00670 
00671     template <typename T, typename N>
00672     struct fwd_nixter< const image2d<T>, N >
00673     {
00674       typedef dpoints_fwd_pixter< const image2d<T> > ret;
00675     };
00676 
00677     template <typename T, typename N>
00678     struct bkd_nixter< image2d<T>, N >
00679     {
00680       typedef dpoints_bkd_pixter< image2d<T> > ret;
00681     };
00682 
00683     template <typename T, typename N>
00684     struct bkd_nixter< const image2d<T>, N >
00685     {
00686       typedef dpoints_bkd_pixter< const image2d<T> > ret;
00687     };
00688 
00689   } // end of namespace mln::trait
00690 
00691 } // end of namespace mln
00692 
00693 
00694 # include <mln/make/image.hh>
00695 # include <mln/make/image2d.hh>
00696 
00697 
00698 #endif // ! MLN_CORE_IMAGE_IMAGE2D_HH

Generated on Thu Sep 8 2011 18:31:58 for Milena (Olena) by  doxygen 1.7.1