Milena (Olena)
User documentation 2.0a Id
|
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