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

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

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