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_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
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 namespace mln
00059 {
00060
00061
00062 template <typename T> struct 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_;
00079 unsigned bdr_;
00080 box2d vb_;
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 }
00090
00091
00092 namespace trait
00093 {
00094
00095 template <typename T>
00096 struct image_< image2d<T> > : default_image_< T, image2d<T> >
00097 {
00098
00099 typedef trait::image::category::primary category;
00100 typedef trait::image::speed::fastest speed;
00101 typedef trait::image::size::regular size;
00102
00103
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
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
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 }
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
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
00197
00198
00199
00200
00201
00202
00203
00204
00205 return this->data_->array_ [*(coord_t*)(&p.p_hook_())] [*((coord_t*)(&p.p_hook_()) + 1)];
00206
00207 }
00208
00209
00210
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
00227
00228
00229
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
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
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
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 }
00388
00389
00390
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
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
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
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 }
00609
00610
00611
00612 # include <mln/core/trait/pixter.hh>
00613 # include <mln/core/dpoints_pixter.hh>
00614 # include <mln/core/pixter2d.hh>
00615
00616
00617
00618 namespace mln
00619 {
00620
00621 namespace trait
00622 {
00623
00624
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
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
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 }
00703
00704 }
00705
00706
00707 # include <mln/make/image.hh>
00708 # include <mln/make/image2d.hh>
00709
00710
00711 #endif // ! MLN_CORE_IMAGE_IMAGE2D_HH