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