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_DMORPH_P2P_IMAGE_HH
00027 # define MLN_CORE_IMAGE_DMORPH_P2P_IMAGE_HH
00028
00032
00033 # include <mln/core/internal/image_domain_morpher.hh>
00034 # include <mln/core/concept/function.hh>
00035 # include <mln/accu/shape/bbox.hh>
00036
00037
00038 namespace mln
00039 {
00040
00041
00042 template <typename I, typename F> struct p2p_image;
00043
00044
00045 namespace internal
00046 {
00047
00049 template <typename I, typename F>
00050 struct data< p2p_image<I,F> >
00051 {
00052 data(I& ima, const F& f);
00053
00054 I ima_;
00055 F f_;
00056 mln_domain(I) b_;
00057 };
00058
00059 }
00060
00061
00062 namespace trait
00063 {
00064
00065 template <typename I, typename F>
00066 struct image_< p2p_image<I,F> > : default_image_morpher< I,
00067 mln_value(I),
00068 p2p_image<I,F> >
00069 {
00070 typedef trait::image::category::domain_morpher category;
00071
00072 typedef trait::image::ext_domain::none ext_domain;
00073 typedef trait::image::ext_value::irrelevant ext_value;
00074 typedef trait::image::ext_io::irrelevant ext_io;
00075
00076 typedef trait::image::vw_io::none vw_io;
00077 typedef trait::image::vw_set::none vw_set;
00078 typedef trait::image::value_alignment::not_aligned value_alignment;
00079 typedef trait::image::value_storage::disrupted value_storage;
00080 };
00081
00082 }
00083
00084
00085
00089 template <typename I, typename F>
00090 struct p2p_image : public internal::image_domain_morpher< I,
00091 mln_domain(I),
00092 p2p_image<I, F> >
00093 {
00095 typedef p2p_image< tag::image_<I>, tag::function_<F> > skeleton;
00096
00098 p2p_image();
00099
00101 p2p_image(I& ima, const F& f);
00102
00103 void init_(I& ima, const F& f);
00104
00106 const mln_domain(I)& domain() const;
00107
00109 const F& fun() const;
00110
00112 mln_rvalue(I) operator()(const mln_psite(I)& p) const;
00113
00115 mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
00116 };
00117
00118
00119
00121 template <typename I, typename F>
00122 p2p_image<I,F>
00123 apply_p2p(Image<I>& ima, const Function_v2v<F>& f);
00124
00126 template <typename I, typename F>
00127 p2p_image<const I,F>
00128 apply_p2p(const Image<I>& ima, const Function_v2v<F>& f);
00129
00130
00131
00132 # ifndef MLN_INCLUDE_ONLY
00133
00134
00135
00136 template <typename I, typename F>
00137 void init_(tag::function_t, F& f, const p2p_image<I,F>& model)
00138 {
00139 f = model.fun();
00140 }
00141
00142 template <typename I, typename F, typename J>
00143 void init_(tag::image_t, p2p_image<I,F>& target, const J& model)
00144 {
00145 I ima;
00146 init_(tag::image, ima, exact(model));
00147 F f;
00148 init_(tag::function, f, exact(model));
00149 target.init_(ima, f);
00150 }
00151
00152
00153
00154 namespace internal
00155 {
00156
00157 template <typename I, typename F>
00158 inline
00159 data< p2p_image<I,F> >::data(I& ima, const F& f)
00160 : ima_(ima),
00161 f_(f)
00162 {
00163 accu::shape::bbox<mln_site(I)> a;
00164 mln_domain(I) b = ima.domain();
00165 a.take(f(b.pmin()));
00166 a.take(f(b.pmax()));
00167 b_ = a.to_result();
00168 mln_invariant(b_.nsites() == b.nsites());
00169 }
00170
00171 }
00172
00173
00174
00175
00176 template <typename I, typename F>
00177 inline
00178 p2p_image<I,F>::p2p_image()
00179 {
00180 }
00181
00182 template <typename I, typename F>
00183 inline
00184 p2p_image<I,F>::p2p_image(I& ima, const F& f)
00185 {
00186 init_(ima, f);
00187 }
00188
00189 template <typename I, typename F>
00190 inline
00191 void
00192 p2p_image<I,F>::init_(I& ima, const F& f)
00193 {
00194 mln_precondition(! this->is_valid());
00195 this->data_ = new internal::data< p2p_image<I,F> >(ima, f);
00196 }
00197
00198 template <typename I, typename F>
00199 inline
00200 const mln_domain(I)&
00201 p2p_image<I,F>::domain() const
00202 {
00203 mln_precondition(this->is_valid());
00204 return this->data_->b_;
00205 }
00206
00207 template <typename I, typename F>
00208 inline
00209 const F&
00210 p2p_image<I,F>::fun() const
00211 {
00212 mln_precondition(this->is_valid());
00213 return this->data_->f_;
00214 }
00215
00216 template <typename I, typename F>
00217 inline
00218 mln_rvalue(I)
00219 p2p_image<I,F>::operator()(const mln_psite(I)& p) const
00220 {
00221 mln_precondition(this->has(p));
00222 mln_invariant(this->data_->ima_.has(this->data_->f_.inverse(p)));
00223 return this->data_->ima_(this->data_->f_.inverse(p));
00224 }
00225
00226 template <typename I, typename F>
00227 inline
00228 mln_morpher_lvalue(I)
00229 p2p_image<I,F>::operator()(const mln_psite(I)& p)
00230 {
00231 mln_precondition(this->has(p));
00232 mln_invariant(this->data_->ima_.has(this->data_->f_.inverse(p)));
00233 return this->data_->ima_(this->data_->f_.inverse(p));
00234 }
00235
00236
00237
00238
00239 template <typename I, typename F>
00240 inline
00241 p2p_image<I,F>
00242 apply_p2p(Image<I>& ima_, const Function_v2v<F>& f)
00243 {
00244 mlc_is_a(mln_domain(I), Box)::check();
00245
00246 I& ima = exact(ima_);
00247 mln_precondition(ima.is_valid());
00248
00249 p2p_image<I,F> tmp(ima, exact(f));
00250 return tmp;
00251 }
00252
00253 template <typename I, typename F>
00254 inline
00255 p2p_image<const I, F>
00256 apply_p2p(const Image<I>& ima_, const Function_v2v<F>& f)
00257 {
00258 mlc_is_a(mln_domain(I), Box)::check();
00259
00260 const I& ima = exact(ima_);
00261 mln_precondition(ima.is_valid());
00262
00263 p2p_image<const I, F> tmp(ima, exact(f));
00264 return tmp;
00265 }
00266
00267
00268 # endif // ! MLN_INCLUDE_ONLY
00269
00270 }
00271
00272
00273
00274 #endif // ! MLN_CORE_IMAGE_DMORPH_P2P_IMAGE_HH