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