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_MORPHO_ATTRIBUTE_VOLUME_HH
00027 # define MLN_MORPHO_ATTRIBUTE_VOLUME_HH
00028
00033
00034 # include <mln/accu/internal/base.hh>
00035 # include <mln/math/diff_abs.hh>
00036 # include <mln/util/pix.hh>
00037
00038
00039 namespace mln
00040 {
00041
00042
00043 namespace morpho {
00044 namespace attribute {
00045 template <typename I> class volume;
00046 }
00047 }
00048
00049
00050
00051
00052 namespace trait
00053 {
00054
00055 template <typename I>
00056 struct accumulator_< morpho::attribute::volume<I> >
00057 {
00058 typedef accumulator::has_untake::no has_untake;
00059 typedef accumulator::has_set_value::no has_set_value;
00060 typedef accumulator::has_stop::no has_stop;
00061 typedef accumulator::when_pix::use_v when_pix;
00062 };
00063
00064 }
00065
00066
00067 namespace morpho
00068 {
00069
00070 namespace attribute
00071 {
00072
00077 template <typename I>
00078 struct volume
00079 : public mln::accu::internal::base< unsigned , volume<I> >
00080 {
00081 typedef mln_value(I) argument;
00082
00083 volume();
00084
00087 void init();
00088
00089 void take(const mln_value(I)& v);
00090 void take(const util::pix<I>& px);
00091 void take(const volume<I>& other);
00092
00093 void take_as_init_(const mln_value(I)& v);
00094 void take_as_init_(const util::pix<I>& px);
00096
00098 unsigned to_result() const;
00099
00102 bool is_valid() const;
00103
00105 unsigned area() const;
00106
00107 protected:
00109 mln_value(I) cur_level_;
00111 unsigned area_;
00113 unsigned volume_;
00114 };
00115
00116
00117
00118 # ifndef MLN_INCLUDE_ONLY
00119
00120 template <typename I>
00121 inline
00122 volume<I>::volume()
00123 {
00124 init();
00125 }
00126
00127 template <typename I>
00128 inline
00129 void
00130 volume<I>::init()
00131 {
00132 volume_ = 0;
00133 }
00134
00135 template <typename I>
00136 inline
00137 void
00138 volume<I>::take(const mln_value(I)& v)
00139 {
00140 mln_invariant(volume_ != mln_max(unsigned));
00141 if (! is_valid())
00142 {
00143 take_as_init_(v);
00144 return;
00145 }
00146 ++area_;
00147 volume_ += 1 + math::diff_abs(v, cur_level_);
00148 cur_level_ = v;
00149 }
00150
00151 template <typename I>
00152 inline
00153 void
00154 volume<I>::take(const util::pix<I>& px)
00155 {
00156 mln_invariant(volume_ != mln_max(unsigned));
00157 take(px.v());
00158 }
00159
00160 template <typename I>
00161 inline
00162 void
00163 volume<I>::take(const volume<I>& other)
00164 {
00165 mln_invariant(volume_ != mln_max(unsigned));
00166 area_ += other.area_;
00167 volume_ +=
00168 other.volume_ +
00169 other.area_ * math::diff_abs(other.cur_level_, cur_level_);
00170
00171 }
00172
00173 template <typename I>
00174 inline
00175 void
00176 volume<I>::take_as_init_(const mln_value(I)& v)
00177 {
00178 cur_level_ = v;
00179 area_ = 1;
00180 volume_ = 1;
00181 }
00182
00183 template <typename I>
00184 inline
00185 void
00186 volume<I>::take_as_init_(const util::pix<I>& px)
00187 {
00188 take_as_init_(px.v());
00189 }
00190
00191 template <typename I>
00192 inline
00193 unsigned
00194 volume<I>::to_result() const
00195 {
00196 return volume_;
00197 }
00198
00199 template <typename I>
00200 inline
00201 unsigned
00202 volume<I>::area() const
00203 {
00204 return area_;
00205 }
00206
00207 template <typename I>
00208 inline
00209 bool
00210 volume<I>::is_valid() const
00211 {
00212 return volume_ != 0;
00213 }
00214
00215 # endif // ! MLN_INCLUDE_ONLY
00216
00217 }
00218
00219 }
00220
00221 }
00222
00223
00224 #endif // ! MLN_MORPHO_ATTRIBUTE_VOLUME_HH