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 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
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
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 }
00381
00382
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 }
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
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
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
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 }
00688
00689 }
00690
00691
00692 #endif // ! MLN_CORE_IMAGE_IMAGE3D_HH