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

image3d.hh

00001 // Copyright (C) 2007, 2008, 2009, 2010 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_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 nslices, 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     unsigned border() const;
00186 
00188     unsigned nelements() const;
00189 
00191     const T& operator()(const point3d& p) const;
00192 
00194     T& operator()(const point3d& p);
00195 
00197     const T& element(unsigned i) const;
00198 
00200     T& element(unsigned i);
00201 
00204     const T& at_(def::coord sli, def::coord row, def::coord col) const;
00205 
00208     T& at_(def::coord sli, def::coord row, def::coord col);
00209 
00210 
00212     unsigned nslices() const;
00213 
00215     unsigned nrows() const;
00216 
00218     unsigned ncols() const;
00219 
00220 
00222 
00224     int delta_index(const dpoint3d& dp) const;
00225 
00227     point3d point_at_index(unsigned o) const;
00228 
00230     const T* buffer() const;
00231 
00233     T* buffer();
00234 
00236     using super_::data_;
00237 
00238 
00239 
00241     void resize_(unsigned new_border);
00242 
00243   };
00244 
00245   template <typename T, typename J>
00246   void init_(tag::image_t, mln::image3d<T>& target, const J& model);
00247 
00248 
00249 
00250 # ifndef MLN_INCLUDE_ONLY
00251 
00252   // init_
00253 
00254   template <typename T>
00255   inline
00256   void init_(tag::border_t, unsigned& b, const image3d<T>& model)
00257   {
00258     b = model.border();
00259   }
00260 
00261   template <typename T, typename J>
00262   inline
00263   void init_(tag::image_t, image3d<T>& target, const J& model)
00264   {
00265     box3d b;
00266     init_(tag::bbox, b, model);
00267     unsigned bdr;
00268     init_(tag::border, bdr, model);
00269     target.init_(b, bdr);
00270   }
00271 
00272 
00273   // internal::data< image3d<T> >
00274 
00275   namespace internal
00276   {
00277 
00278     template <typename T>
00279     inline
00280     data< image3d<T> >::data(const box3d& b, unsigned bdr)
00281       : buffer_(0),
00282         array_ (0),
00283         b_     (b),
00284         bdr_   (bdr)
00285     {
00286       allocate_();
00287     }
00288 
00289     template <typename T>
00290     inline
00291     data< image3d<T> >::~data()
00292     {
00293       deallocate_();
00294     }
00295 
00296     template <typename T>
00297     inline
00298     void
00299     data< image3d<T> >::update_vb_()
00300     {
00301       vb_.pmin() = b_.pmin() - dpoint3d(all_to(bdr_));
00302       vb_.pmax() = b_.pmax() + dpoint3d(all_to(bdr_));
00303     }
00304 
00305     template <typename T>
00306     inline
00307     void
00308     data< image3d<T> >::allocate_()
00309     {
00310       update_vb_();
00311       unsigned
00312         ns = vb_.len(0),
00313         nr = vb_.len(1),
00314         nc = vb_.len(2);
00315       buffer_ = new T[nr * nc * ns];
00316       array_ = new T**[ns];
00317       T* buf = buffer_ - vb_.pmin().col();
00318       for (unsigned i = 0; i < ns; ++i)
00319       {
00320         T** tmp = new T*[nr];
00321         array_[i] = tmp;
00322         for (unsigned j = 0; j < nr; ++j)
00323         {
00324           array_[i][j] = buf;
00325           buf += nc;
00326         }
00327         array_[i] -= vb_.pmin().row();
00328       }
00329       array_ -= vb_.pmin().sli();
00330       mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
00331     }
00332 
00333     template <typename T>
00334     inline
00335     void
00336     data< image3d<T> >::deallocate_()
00337     {
00338       if (buffer_)
00339       {
00340         delete[] buffer_;
00341         buffer_ = 0;
00342       }
00343       for (typename point3d::coord i = vb_.pmin().sli(); i <= vb_.pmax().sli(); ++i)
00344       {
00345         if (array_[i])
00346         {
00347           array_[i] += vb_.pmin().row();
00348           delete[] array_[i];
00349           array_[i] = 0;
00350         }
00351       }
00352       if (array_)
00353       {
00354         array_ += vb_.pmin().sli();
00355         delete[] array_;
00356         array_ = 0;
00357       }
00358     }
00359 
00360     template <typename T>
00361     inline
00362     void
00363     data< image3d<T> >::swap_(data< image3d<T> >& other_)
00364     {
00365       data< image3d<T> > self_ = *this;
00366       *this = other_;
00367       other_ = self_;
00368     }
00369 
00370     template <typename T>
00371     inline
00372     void
00373     data< image3d<T> >::reallocate_(unsigned new_border)
00374     {
00375       data< image3d<T> >& tmp = *(new data< image3d<T> >(this->b_, new_border));
00376       this->swap_(tmp);
00377     }
00378 
00379 
00380   } // end of namespace mln::internal
00381 
00382   // image3d<T>
00383 
00384   template <typename T>
00385   inline
00386   image3d<T>::image3d()
00387   {
00388   }
00389 
00390   template <typename T>
00391   inline
00392   image3d<T>::image3d(const box3d& b, unsigned bdr)
00393   {
00394     init_(b, bdr);
00395   }
00396 
00397   template <typename T>
00398   inline
00399   image3d<T>::image3d(int nslices, int nrows, int ncols, unsigned bdr)
00400   {
00401     init_(make::box3d(nslices, nrows, ncols), bdr);
00402   }
00403 
00404   template <typename T>
00405   inline
00406   void
00407   image3d<T>::init_(const box3d& b, unsigned bdr)
00408   {
00409     mln_precondition(! this->is_valid());
00410     this->data_ = new internal::data< image3d<T> >(b, bdr);
00411   }
00412 
00413   template <typename T>
00414   inline
00415   const box3d&
00416   image3d<T>::domain() const
00417   {
00418     mln_precondition(this->is_valid());
00419     return data_->b_;
00420   }
00421 
00422   template <typename T>
00423   inline
00424   const box3d&
00425   image3d<T>::bbox() const
00426   {
00427     mln_precondition(this->is_valid());
00428     return data_->b_;
00429   }
00430 
00431   template <typename T>
00432   inline
00433   unsigned
00434   image3d<T>::border() const
00435   {
00436     mln_precondition(this->is_valid());
00437     return data_->bdr_;
00438   }
00439 
00440   template <typename T>
00441   inline
00442   unsigned
00443   image3d<T>::nelements() const
00444   {
00445     mln_precondition(this->is_valid());
00446     return data_->vb_.nsites();
00447   }
00448 
00449   template <typename T>
00450   inline
00451   bool
00452   image3d<T>::has(const point3d& p) const
00453   {
00454     mln_precondition(this->is_valid());
00455     return data_->vb_.has(p);
00456   }
00457 
00458   template <typename T>
00459   inline
00460   const T&
00461   image3d<T>::operator()(const point3d& p) const
00462   {
00463     mln_precondition(this->has(p));
00464     return data_->array_[p.sli()][p.row()][p.col()];
00465   }
00466 
00467   template <typename T>
00468   inline
00469   T&
00470   image3d<T>::operator()(const point3d& p)
00471   {
00472     mln_precondition(this->has(p));
00473     return data_->array_[p.sli()][p.row()][p.col()];
00474   }
00475 
00476   template <typename T>
00477   inline
00478   const T&
00479   image3d<T>::element(unsigned i) const
00480   {
00481     mln_precondition(i < nelements());
00482     return *(data_->buffer_ + i);
00483   }
00484 
00485   template <typename T>
00486   inline
00487   T&
00488   image3d<T>::element(unsigned i)
00489   {
00490     mln_precondition(i < nelements());
00491     return *(data_->buffer_ + i);
00492   }
00493 
00494   template <typename T>
00495   inline
00496   const T&
00497   image3d<T>::at_(def::coord sli, def::coord row, def::coord col) const
00498   {
00499     mln_precondition(this->has(point3d(sli, row, col)));
00500     return data_->array_[sli][row][col];
00501   }
00502 
00503   template <typename T>
00504   inline
00505   T&
00506   image3d<T>::at_(def::coord sli, def::coord row, def::coord col)
00507   {
00508     mln_precondition(this->has(point3d(sli, row, col)));
00509     return data_->array_[sli][row][col];
00510   }
00511 
00512   template <typename T>
00513   inline
00514   unsigned
00515   image3d<T>::nslices() const
00516   {
00517     mln_precondition(this->is_valid());
00518     return this->data_->b_.len(0);
00519   }
00520 
00521   template <typename T>
00522   inline
00523   unsigned
00524   image3d<T>::nrows() const
00525   {
00526     mln_precondition(this->is_valid());
00527     return this->data_->b_.len(1);
00528   }
00529 
00530   template <typename T>
00531   inline
00532   unsigned
00533   image3d<T>::ncols() const
00534   {
00535     mln_precondition(this->is_valid());
00536     return this->data_->b_.len(2);
00537   }
00538 
00539   template <typename T>
00540   inline
00541   const T*
00542   image3d<T>::buffer() const
00543   {
00544     mln_precondition(this->is_valid());
00545     return data_->buffer_;
00546   }
00547 
00548   template <typename T>
00549   inline
00550   T*
00551   image3d<T>::buffer()
00552   {
00553     mln_precondition(this->is_valid());
00554     return data_->buffer_;
00555   }
00556 
00557   template <typename T>
00558   inline
00559   int
00560   image3d<T>::delta_index(const dpoint3d& dp) const
00561   {
00562     mln_precondition(this->is_valid());
00563     int o = (dp[0] * this->data_->vb_.len(1)
00564              + dp[1]) * this->data_->vb_.len(2) + dp[2];
00565     return o;
00566   }
00567 
00568   template <typename T>
00569   inline
00570   point3d
00571   image3d<T>::point_at_index(unsigned o) const
00572   {
00573     mln_precondition(o < nelements());
00574     def::coord
00575       sli = static_cast<def::coord>(o / (data_->vb_.len(1) * data_->vb_.len(2)) + data_->vb_.min_sli()),
00576       row = static_cast<def::coord>((o % (data_->vb_.len(1) * data_->vb_.len(2))) / data_->vb_.len(2) + data_->vb_.min_row()),
00577       col = static_cast<def::coord>(o % data_->vb_.len(2) + data_->vb_.min_col());
00578     point3d p = point3d(sli, row, col);
00579     mln_postcondition(& this->operator()(p) == this->data_->buffer_ + o);
00580     return p;
00581   }
00582 
00583   template <typename T>
00584   inline
00585   void
00586   image3d<T>::resize_(unsigned new_border)
00587   {
00588     this->data_->reallocate_(new_border);
00589   }
00590 
00591 # endif // ! MLN_INCLUDE_ONLY
00592 
00593 } // end of namespace mln
00594 
00595 
00596 
00597 # include <mln/core/trait/pixter.hh>
00598 # include <mln/core/dpoints_pixter.hh>
00599 # include <mln/core/pixter3d.hh>
00600 # include <mln/core/w_window.hh>
00601 
00602 
00603 namespace mln
00604 {
00605 
00606   namespace trait
00607   {
00608 
00609     // pixter
00610 
00611     template <typename T>
00612     struct fwd_pixter< image3d<T> >
00613     {
00614       typedef fwd_pixter3d< image3d<T> > ret;
00615     };
00616 
00617     template <typename T>
00618     struct fwd_pixter< const image3d<T> >
00619     {
00620       typedef fwd_pixter3d< const image3d<T> > ret;
00621     };
00622 
00623     template <typename T>
00624     struct bkd_pixter< image3d<T> >
00625     {
00626       typedef bkd_pixter3d< image3d<T> > ret;
00627     };
00628 
00629     template <typename T>
00630     struct bkd_pixter< const image3d<T> >
00631     {
00632       typedef bkd_pixter3d< const image3d<T> > ret;
00633     };
00634 
00635     // qixter
00636 
00637     template <typename T, typename W>
00638     struct fwd_qixter< image3d<T>, W >
00639     {
00640       typedef dpoints_fwd_pixter< image3d<T> > ret;
00641     };
00642 
00643     template <typename T, typename W>
00644     struct fwd_qixter< const image3d<T>, W >
00645     {
00646       typedef dpoints_fwd_pixter< const image3d<T> > ret;
00647     };
00648 
00649     template <typename T, typename W>
00650     struct bkd_qixter< image3d<T>, W >
00651     {
00652       typedef dpoints_bkd_pixter< image3d<T> > ret;
00653     };
00654 
00655     template <typename T, typename W>
00656     struct bkd_qixter< const image3d<T>, W >
00657     {
00658       typedef dpoints_bkd_pixter< const image3d<T> > ret;
00659     };
00660 
00661     // nixter
00662 
00663     template <typename T, typename W>
00664     struct fwd_nixter< image3d<T>, W >
00665     {
00666       typedef dpoints_fwd_pixter< image3d<T> > ret;
00667     };
00668 
00669     template <typename T, typename W>
00670     struct fwd_nixter< const image3d<T>, W >
00671     {
00672       typedef dpoints_fwd_pixter< const image3d<T> > ret;
00673     };
00674 
00675     template <typename T, typename W>
00676     struct bkd_nixter< image3d<T>, W >
00677     {
00678       typedef dpoints_bkd_pixter< image3d<T> > ret;
00679     };
00680 
00681     template <typename T, typename W>
00682     struct bkd_nixter< const image3d<T>, W >
00683     {
00684       typedef dpoints_bkd_pixter< const image3d<T> > ret;
00685     };
00686 
00687   } // end of namespace mln::trait
00688 
00689 } // end of namespace mln
00690 
00691 
00692 #endif // ! MLN_CORE_IMAGE_IMAGE3D_HH

Generated on Fri Oct 19 2012 04:15:54 for Milena (Olena) by  doxygen 1.7.1