Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
transform_inplace.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_DATA_TRANSFORM_INPLACE_HH
27 # define MLN_DATA_TRANSFORM_INPLACE_HH
28 
34 
35 # include <mln/core/concept/image.hh>
36 # include <mln/core/concept/function.hh>
37 # include <mln/value/set.hh>
38 # include <mln/value/lut_vec.hh>
39 # include <mln/opt/value.hh>
40 
41 
42 namespace mln
43 {
44 
45  namespace data
46  {
47 
57  template <typename I, typename F>
58  void
59  transform_inplace(Image<I>& ima, const Function_v2v<F>& f);
60 
61 
72  template <typename I1, typename I2, typename F>
73  void
74  transform_inplace(Image<I1>& ima, const Image<I2>& aux,
75  const Function_vv2v<F>& f);
76 
77 
78 
79 # ifndef MLN_INCLUDE_ONLY
80 
81 
82  // Tests.
83 
84  namespace internal
85  {
86 
87  template <typename I, typename F>
88  inline
89  void transform_inplace_tests(const Image<I>& ima,
90  const Function_v2v<F>& f)
91  {
92  // Properties checks.
93  mlc_or(mlc_is(mln_trait_image_pw_io(I),
94  trait::image::pw_io::read_write),
95  mlc_is(mln_trait_image_vw_io(I),
96  trait::image::vw_io::read_write))::check();
97  mlc_converts_to(mln_result(F), mln_value(I))::check();
98 
99  // Dynamic test.
100  mln_precondition(exact(ima).is_valid());
101 
102  // Avoid a warning.
103  (void) ima;
104  (void) f;
105  }
106 
107  template <typename I1, typename I2, typename F>
108  inline
109  void transform_inplace_tests(Image<I1>& ima,
110  const Image<I2>& aux,
111  const Function_vv2v<F>& f)
112  {
113  // Properties checks.
114  mlc_or(mlc_is(mln_trait_image_pw_io(I1),
115  trait::image::pw_io::read_write),
116  mlc_is(mln_trait_image_vw_io(I1),
117  trait::image::vw_io::read_write))::check();
118  mlc_converts_to(mln_result(F), mln_value(I1))::check();
119 
120  // Dynamic test.
121  mln_precondition(exact(ima).is_valid());
122  mln_precondition(exact(aux).is_valid());
123  mln_precondition(exact(aux).domain() == exact(ima).domain());
124 
125  // Avoid warnings.
126  (void) ima;
127  (void) aux;
128  (void) f;
129  }
130 
131  } // end of namespace mln::data::internal
132 
133 
134  namespace impl
135  {
136 
137  // Generic implementations.
138 
139  namespace generic
140  {
141 
146  //
147  template <typename I, typename F>
148  void
150  {
151  trace::entering("data::impl::generic::transform_inplace");
152 
153  mlc_is(mln_trait_image_pw_io(I),
154  trait::image::pw_io::read_write)::check();
155 
156  I& ima = exact(ima_);
157  const F& f = exact(f_);
158 
159  internal::transform_inplace_tests(ima, f);
160 
161  mln_piter(I) p(ima.domain());
162  for_all(p)
163  ima(p) = f(ima(p));
164 
165  trace::exiting("data::impl::generic::transform_inplace");
166  }
167 
173  //
174  template <typename I1, typename I2, typename F>
175  void
177  const Function_vv2v<F>& f_)
178  {
179  trace::entering("data::impl::generic::transform_inplace");
180 
181  mlc_is(mln_trait_image_pw_io(I1),
182  trait::image::pw_io::read_write)::check();
183 
184  I1& ima = exact(ima_);
185  const I2& aux = exact(aux_);
186  const F& f = exact(f_);
187 
188  internal::transform_inplace_tests(ima, aux, f);
189 
190  mln_piter(I1) p(ima.domain());
191  for_all(p)
192  ima(p) = f(ima(p), aux(p));
193 
194  trace::exiting("data::impl::generic::transform_inplace");
195  }
196 
197  } // end of namespace mln::data::impl::generic
198 
200 
201  template <typename I, typename F>
202  void
204  const Function_v2v<F>& f_)
205  {
206  trace::entering("data::impl::transform_inplace_lowq");
207 
208  mlc_is(mln_trait_image_pw_io(I),
209  trait::image::pw_io::read_write)::check();
210 
211  I& input = exact(input_);
212  const F& f = exact(f_);
213 
214  internal::transform_inplace_tests(input, f);
215 
217  lut(input.values_eligible(), f);
218 
219  mln_piter(I) p(input.domain());
220  for_all(p)
221  input(p) = lut(input(p));
222 
223  trace::exiting("data::impl::transform_inplace_lowq");
224  }
225 
226  template <typename I, typename F>
227  void
228  transform_inplace_taken(Image<I>& input_,
229  const Function_v2v<F>& f_)
230  {
231  trace::entering("data::impl::transform_inplace_taken");
232 
233  mlc_is(mln_trait_image_pw_io(I),
234  trait::image::pw_io::read_write)::check();
235 
236  I& input = exact(input_);
237  const F& f = exact(f_);
238 
239  internal::transform_inplace_tests(input, f);
240 
242  lut(input.taken_values(), f);
243 
244  mln_piter(I) p(input.domain());
245  for_all(p)
246  input(p) = lut(input(p));
247 
248  trace::exiting("data::impl::transform_inplace_taken");
249  }
250 
251 
252  template <typename I, typename F>
253  void
254  transform_inplace_singleton(Image<I>& input_,
255  const Function_v2v<F>& f_)
256  {
257  trace::entering("data::impl::transform_inplace_singleton");
258 
259  I& input = exact(input_);
260  const F& f = exact(f_);
261 
262  internal::transform_inplace_tests(input, f);
263 
264  opt::value(input) = f(opt::value(input));
265 
266  trace::exiting("data::impl::transform_inplace_singleton");
267  }
268 
269  template <typename I, typename F>
270  void
271  transform_inplace_fastest(Image<I>& ima_, const Function_v2v<F>& f_)
272  {
273  trace::entering("data::impl::transform_inplace_fastest");
274 
275  I& ima = exact(ima_);
276  const F& f = exact(f_);
277 
278  internal::transform_inplace_tests(ima, f);
279 
280  mln_pixter(I) p(ima);
281  for_all(p)
282  p.val() = f(p.val());
283 
284  trace::exiting("data::impl::transform_inplace_fastest");
285  }
286 
287 
288  template <typename I, typename F>
289  void
290  transform_inplace_fastest_lowq(Image<I>& input_,
291  const Function_v2v<F>& f_)
292  {
293  trace::entering("data::impl::transform_inplace_fastest_lowq");
294 
295  I& input = exact(input_);
296  const F& f = exact(f_);
297 
298  internal::transform_inplace_tests(input, f);
299 
301  lut(input.values_eligible(), f);
302 
303  mln_pixter(I) pi(input);
304  for_all(pi)
305  pi.val() = lut(pi.val());
306 
307  trace::exiting("data::impl::transform_inplace_fastest_lowq");
308  }
309 
310 
311  template <typename I1, typename I2, typename F>
312  void
313  transform_inplace_fastest(Image<I1>& ima_, const Image<I2>& aux_,
314  const Function_vv2v<F>& f_)
315  {
316  trace::entering("data::impl::transform_inplace_fastest");
317 
318  mlc_is(mln_trait_image_pw_io(I1),
319  trait::image::pw_io::read_write)::check();
320 
321  I1& ima = exact(ima_);
322  const I2& aux = exact(aux_);
323  const F& f = exact(f_);
324 
325  internal::transform_inplace_tests(ima, aux, f);
326 
327  mln_pixter(I1) pi(ima);
328  mln_pixter(const I2) pa(aux);
329  for_all_2(pi, pa)
330  pi.val() = f(pi.val(), pa.val());
331 
332  trace::exiting("data::impl::transform_inplace_fastest");
333  }
334 
335 
336  } // end of namespace mln::data::impl
337 
338 
339 
340  // Dispatch.
341 
342  namespace internal
343  {
344 
345  // (ima, f) version.
346 
348  template <typename I, typename F>
349  void
350  transform_inplace_dispatch(trait::image::vw_set::any,
351  trait::image::quant::any,
352  Image<I>& ima, const Function_v2v<F>& f)
353  {
355  }
356 
357  template <typename I, typename F>
358  void
359  transform_inplace_dispatch(trait::image::vw_set::uni,
360  trait::image::quant::any,
361  Image<I>& ima, const Function_v2v<F>& f)
362  {
363  data::impl::transform_inplace_taken(ima, f);
364  }
365 
366  template <typename I, typename F>
367  void
368  transform_inplace_dispatch(trait::image::vw_set::any,
369  trait::image::quant::low,
370  Image<I>& ima, const Function_v2v<F>& f)
371  {
373  }
374 
375 
376 
378  template <typename I, typename F>
379  void
380  transform_inplace_dispatch_fast(trait::image::quant::any,
381  Image<I>& ima, const Function_v2v<F>& f)
382  {
383  data::impl::transform_inplace_fastest(ima, f);
384  }
385 
386  template <typename I, typename F>
387  void
388  transform_inplace_dispatch_fast(trait::image::quant::low,
389  Image<I>& ima, const Function_v2v<F>& f)
390  {
391  data::impl::transform_inplace_fastest_lowq(ima, f);
392  }
393 
394 
395 
396 
398  template <typename I, typename F>
399  void
400  transform_inplace_dispatch(trait::image::value_storage::any,
401  trait::image::value_access::any,
402  Image<I>& ima, const Function_v2v<F>& f)
403  {
404  transform_inplace_dispatch(mln_trait_image_vw_set(I)(),
405  mln_trait_image_quant(I)(),
406  ima, f);
407  }
408 
409  template <typename I, typename F>
410  void
411  transform_inplace_dispatch(trait::image::value_storage::singleton,
412  trait::image::value_access::any,
413  Image<I>& ima, const Function_v2v<F>& f)
414  {
415  data::impl::transform_inplace_singleton(ima, f);
416  }
417 
418 
419  template <typename I, typename F>
420  void
421  transform_inplace_dispatch(trait::image::value_storage::one_block,
422  trait::image::value_access::direct,
423  Image<I>& ima, const Function_v2v<F>& f)
424  {
425  transform_inplace_dispatch_fast(mln_trait_image_quant(I)(),
426  ima, f);
427  }
428 
429 
430 
431 
433  template <typename I, typename F>
434  void
435  transform_inplace_dispatch(Image<I>& ima, const Function_v2v<F>& f)
436  {
437  transform_inplace_dispatch(mln_trait_image_value_storage(I)(),
438  mln_trait_image_value_access(I)(),
439  ima, f);
440  }
441 
442 
443 
444  // (ima, aux, f) version.
445 
446  template <typename I1, typename I2, typename F>
447  void
448  transform_inplace_dispatch(trait::image::value_alignment::any,
449  trait::image::value_alignment::any,
450  trait::image::speed::any,
451  trait::image::speed::any,
452  Image<I1>& ima, const Image<I2>& aux,
453  const Function_vv2v<F>& f)
454  {
456  }
457 
458  template <typename I1, typename I2, typename F>
459  void
460  transform_inplace_dispatch(trait::image::value_alignment::with_grid,
461  trait::image::value_alignment::with_grid,
462  trait::image::speed::fastest,
463  trait::image::speed::fastest,
464  Image<I1>& ima, const Image<I2>& aux,
465  const Function_vv2v<F>& f)
466  {
467  data::impl::transform_inplace_fastest(ima, aux, f);
468  }
469 
470  template <typename I1, typename I2, typename F>
471  void
472  transform_inplace_dispatch(Image<I1>& ima, const Image<I2>& aux,
473  const Function_vv2v<F>& f)
474  {
475  transform_inplace_dispatch(mln_trait_image_value_alignment(I1)(),
476  mln_trait_image_value_alignment(I2)(),
477  mln_trait_image_speed(I1)(),
478  mln_trait_image_speed(I2)(),
479  ima, aux, f);
480  }
481 
482  } // end of namespace mln::data::internal
483 
484 
485 
486  // Facades.
487 
488  template <typename I, typename F>
489  void
491  {
492  trace::entering("data::transform_inplace");
493 
494  internal::transform_inplace_tests(ima, f);
495  internal::transform_inplace_dispatch(ima, f);
496 
497  trace::exiting("data::transform_inplace");
498  }
499 
500  template <typename I1, typename I2, typename F>
501  void
503  const Function_vv2v<F>& f)
504  {
505  trace::entering("data::transform_inplace");
506 
507  internal::transform_inplace_tests(ima, aux, f);
508  internal::transform_inplace_dispatch(ima, aux, f);
509 
510  trace::exiting("data::transform_inplace");
511  }
512 
513 
514 # endif // ! MLN_INCLUDE_ONLY
515 
516  } // end of namespace mln::data
517 
518 } // end of namespace mln
519 
520 
521 #endif // ! MLN_DATA_TRANSFORM_INPLACE_HH