Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
compute_attribute_image.hh
1 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
28 # define MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
29 
35 
36 # include <mln/core/routine/duplicate.hh>
37 # include <mln/core/concept/image.hh>
38 # include <mln/morpho/tree/data.hh>
39 # include <mln/trait/accumulators.hh>
40 # include <mln/util/pix.hh>
41 # include <mln/data/fill.hh>
42 
43 
44 namespace mln
45 {
46 
47  namespace morpho
48  {
49 
50  namespace tree
51  {
52 
80  template <typename A, typename T>
81  mln_ch_value(typename T::function, mln_result(A))
82  compute_attribute_image(const Accumulator<A>& a,
83  const T& t,
84  mln_ch_value(typename T::function, A)* accu_image = 0);
85 
86 
87 
98  template <typename A, typename T, typename V>
99  mln_ch_value(typename T::function, mln_result(A))
100  compute_attribute_image_from(const Accumulator<A>& a,
101  const T& t,
102  const Image<V>& values,
103  mln_ch_value(typename T::function, A)* accu_image = 0);
104 
105 
106 
107 # ifndef MLN_INCLUDE_ONLY
108  // Take_as_init specialization
109 
110  namespace internal
111  {
112  template <typename A, typename I, typename P>
113  void take_as_init (trait::accumulator::when_pix::use_none, A& accu,
114  const I& input, const P& p)
115  {
116  (void)input;
117  (void)p;
118  accu.take_as_init();
119  }
120 
121  template <typename A, typename I, typename P>
122  void take_as_init (trait::accumulator::when_pix::use_pix, A& accu,
123  const I& input, const P& p)
124  {
125  accu.take_as_init(make::pix(input, p));
126  }
127 
128  template <typename A, typename I, typename P>
129  void take_as_init (trait::accumulator::when_pix::use_v, A& accu,
130  const I& input, const P& p)
131  {
132  accu.take_as_init(input(p));
133  }
134 
135  template <typename A, typename I, typename P>
136  void take_as_init (trait::accumulator::when_pix::use_p, A& accu,
137  const I& input, const P& p)
138  {
139  (void) input;
140  accu.take_as_init(p);
141  }
142 
143 
144  template <typename A, typename I, typename P>
145  void take_as_init (A& accu, const I& input, const P& p)
146  {
147  take_as_init (mln_trait_accumulator_when_pix(A)(), accu, input, p);
148  }
149 
150 
151  template <typename A, typename T, typename V>
152  inline
153  mln_ch_value(typename T::function, mln_result(A))
154  compute_attribute_image(const A& a,
155  const T& t,
156  const V& values,
157  mln_ch_value(typename T::function, A)* accu_image = 0)
158  {
159 
160  typedef typename T::function I;
161  mln_ch_value(I, A) acc;
162  initialize(acc, t.f());
163 
164  {
165  // Transmit "dynamic data" (state) of 'a' to every values of
166  // 'acc'. It is usually a no-op (so useless) except for a
167  // few accumulators, e.g., for accu::stat::rank which has the 'k'
168  // attribute.
169  mln::data::fill(acc, a);
170  }
171 
172  {
173  // Initialize every attribute with the corresponding pixel.
174  mln_site_piter(T) p(t);
175  for_all(p)
176  take_as_init(acc(p), values, p);
177  }
178 
179  {
180  mln_up_site_piter(T) p(t);
181  // Propagate attribute from a site to its parent.
182  for_all(p)
183  if (! t.is_root(p))
184  acc(t.parent(p)).take(acc(p));
185 
186  // Back-propagate attribute from a node to sites of its
187  // component. Below, p is a non-node component site and
188  // parent(p) is a node, that is, the site representative of
189  // the component p belongs to.
190  for_all(p)
191  if (! t.is_a_node(p))
192  {
193  mln_assertion(t.is_a_node(t.parent(p)));
194  acc(p) = acc(t.parent(p));
195  }
196  }
197 
198 
199  // Store accumulator image.
200  if (accu_image)
201  *accu_image = duplicate(acc);
202 
203  typedef typename T::function I;
204  mln_ch_value(I, mln_result(A)) output;
205  initialize(output, acc);
206  mln::data::fill(output, acc);
207 
208  return output;
209  }
210  }
211 
212  // Facade.
213 
214  template <typename A, typename T>
215  inline
216  mln_ch_value(typename T::function, mln_result(A))
218  const T& t,
219  mln_ch_value(typename T::function, A)* accu_image)
220  {
221  trace::entering("morpho::tree::compute_attribute_image");
222 
223  mln_ch_value(typename T::function, mln_result(A)) output;
224  output = internal::compute_attribute_image(exact(a_), t, t.f(),
225  accu_image);
226 
227  trace::exiting("morpho::tree::compute_attribute_image");
228  return (output);
229  }
230 
231  template <typename A, typename T, typename V>
232  inline
233  mln_ch_value(typename T::function, mln_result(A))
235  const T& t,
236  const Image<V>& values,
237  mln_ch_value(typename T::function, A)* accu_image)
238  {
239  trace::entering("morpho::tree::compute_attribute_image_from");
240 
241 
242  mln_ch_value(typename T::function, mln_result(A)) output;
243  output = internal::compute_attribute_image(exact(a_), t, exact(values),
244  accu_image);
245 
246  trace::exiting("morpho::tree::compute_attribute_image_from");
247  return output;
248  }
249 
250 
251 
252 
253 # endif // ! MLN_INCLUDE_ONLY
254 
255  } // end of namespace mln::morpho::tree
256 
257  } // end of namespace mln::morpho
258 
259 } // end of namespace mln
260 
261 
262 #endif // ! MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH