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 #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
00042
00043
00044
00045
00046
00047
00048
00049 namespace mln
00050 {
00051
00052
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_;
00071 unsigned bdr_;
00072 box3d vb_;
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 }
00082
00083
00084
00085 namespace trait
00086 {
00087
00088 template <typename T>
00089 struct image_< image3d<T> > : default_image_< T, image3d<T> >
00090 {
00091
00092 typedef trait::image::category::primary category;
00093 typedef trait::image::speed::fastest speed;
00094 typedef trait::image::size::regular size;
00095
00096
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
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
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 }
00117
00118
00119
00127
00128 template <typename T>
00129 struct image3d : public internal::image_primary< T, box3d, image3d<T> >
00130 {
00131
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
00139
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
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
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 }
00380
00381
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 }
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
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
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
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 }
00687
00688 }
00689
00690
00691 #endif // ! MLN_CORE_IMAGE_IMAGE3D_HH