00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00043
00044
00045
00046
00047
00048
00049
00050 namespace mln
00051 {
00052
00053
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_;
00072 unsigned bdr_;
00073 box3d vb_;
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 }
00083
00084
00085
00086 namespace trait
00087 {
00088
00089 template <typename T>
00090 struct image_< image3d<T> > : default_image_< T, image3d<T> >
00091 {
00092
00093 typedef trait::image::category::primary category;
00094 typedef trait::image::speed::fastest speed;
00095 typedef trait::image::size::regular size;
00096
00097
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
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
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 }
00118
00119
00120
00128
00129 template <typename T>
00130 struct image3d : public internal::image_primary< T, box3d, image3d<T> >
00131 {
00132
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
00140
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
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
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 }
00384
00385
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 }
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
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
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
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 }
00700
00701 }
00702
00703
00704 #endif // ! MLN_CORE_IMAGE_IMAGE3D_HH