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_ACCU_SHAPE_VOLUME_HH
00027 # define MLN_ACCU_SHAPE_VOLUME_HH
00028 
00032 
00043 # include <mln/accu/internal/base.hh>
00044 # include <mln/core/concept/meta_accumulator.hh>
00045 # include <mln/math/diff_abs.hh>
00046 
00047 # include <mln/util/pix.hh>
00048 # include <mln/literal/zero.hh>
00049 
00050 namespace mln
00051 {
00052 
00053   namespace accu
00054   {
00055 
00056     namespace shape
00057     {
00058 
00065       template <typename I>
00066       struct volume
00067         : public mln::accu::internal::base< unsigned , volume<I> >
00068       {
00076         typedef util::pix<I> argument;
00078         typedef typename argument::value value;
00079 
00080         volume();
00081 
00084         void init();
00085         void take(const argument& pixel);
00086         void take(const volume<I>& other);
00087 
00089         void set_value(unsigned v);
00091 
00093         unsigned to_result() const;
00094 
00097         bool is_valid() const;
00098 
00099       protected:
00101         value ref_level__;
00103         unsigned area__;
00105         unsigned volume_;
00106       };
00107 
00108 
00109     } 
00110 
00111 
00112     namespace meta
00113     {
00114 
00115       namespace shape
00116       {
00117 
00119 
00120         struct volume : public Meta_Accumulator< volume >
00121         {
00122           template <typename I>
00123           struct with
00124           {
00125             typedef accu::shape::volume<I> ret;
00126           };
00127         };
00128 
00129       } 
00130 
00131     } 
00132 
00133 # ifndef MLN_INCLUDE_ONLY
00134 
00135     namespace shape
00136     {
00137 
00138       template <typename I>
00139       inline
00140       volume<I>::volume()
00141       {
00142         init();
00143       }
00144 
00145       template <typename I>
00146       inline
00147       void
00148       volume<I>::init()
00149       {
00150         ref_level__ = literal::zero;
00151         volume_ = 0;
00152         area__ = 0;
00153       }
00154 
00155       template <typename I>
00156       inline
00157       void
00158       volume<I>::take(const argument& pixel)
00159       {
00160         
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173         ref_level__ = pixel.v();
00174         ++area__;
00175         ++volume_;
00176       }
00177 
00178       template <typename I>
00179       inline
00180       void
00181       volume<I>::take(const volume<I>& other)
00182       {
00183         area__ += other.area__;
00184         
00185 
00186 
00187         volume_ +=
00188           other.volume_  +
00189           other.area__ * mln::math::diff_abs(other.ref_level__, ref_level__);
00190         
00191       }
00192 
00193       template <typename I>
00194       inline
00195       unsigned
00196       volume<I>::to_result() const
00197       {
00198         return volume_;
00199       }
00200 
00201       template <typename I>
00202       inline
00203       void
00204       volume<I>::set_value(unsigned v)
00205       {
00206         volume_ = v;
00207         
00208         ref_level__ = literal::zero;
00209         area__ = 0;
00210       }
00211 
00212       template <typename I>
00213       inline
00214       bool
00215       volume<I>::is_valid() const
00216       {
00217         return true;
00218       }
00219 
00220     } 
00221 
00222 # endif // ! MLN_INCLUDE_ONLY
00223 
00224   } 
00225 
00226 } 
00227 
00228 
00229 #endif // ! MLN_ACCU_SHAPE_VOLUME_HH