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

image3d.hh

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

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