transform.hpp 3.26 KB
Newer Older
Edwin Carlinet's avatar
Edwin Carlinet committed
1
2
3
4
5
#ifndef MLN_CORE_ALGORITHM_TRANSFORM_HPP
# define MLN_CORE_ALGORITHM_TRANSFORM_HPP

# include <mln/core/image/image.hpp>

Edwin Carlinet's avatar
Edwin Carlinet committed
6
/// \file
Edwin Carlinet's avatar
Edwin Carlinet committed
7

Edwin Carlinet's avatar
Edwin Carlinet committed
8
namespace mln {
Edwin Carlinet's avatar
Edwin Carlinet committed
9

Edwin Carlinet's avatar
Edwin Carlinet committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  /// \ingroup Algorithms
  /// \brief Transform the value of an image through a function.
  ///
  /// This is equivalent to the following code.
  /// \code
  /// mln_iter(vout, out.values())
  /// mln_iter(vin, in.values())
  /// mln_forall(vin, vout)
  ///    *vout = f(*vin)
  ///
  /// \endcode
  ///
  /// \tparam InputImage A model of :concept:ref:`forward_image`
  /// \tparam OutputImage A model of Writable :concept:ref:`forward_image`
  /// \tparam UnaryFunction A mondel of unary function.
  /// \param input The input image.
  /// \param f The unary function.
  /// \param output The output image.
  /// \see mln::imtransform
Edwin Carlinet's avatar
Edwin Carlinet committed
29
30
31
32
  template <typename InputImage, typename OutputImage, class UnaryFunction>
  OutputImage&
  transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>& output);

Edwin Carlinet's avatar
Edwin Carlinet committed
33
  /// \overload
Edwin Carlinet's avatar
Edwin Carlinet committed
34
35
36
37
  template <typename InputImage, typename OutputImage, class UnaryFunction>
  OutputImage&&
  transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>&& output);

38
39
40
  template <typename InputImage, class UnaryFunction>
  unary_image_expr<UnaryFunction, InputImage>
  lazy_transform(InputImage&& input, UnaryFunction f);
Edwin Carlinet's avatar
Edwin Carlinet committed
41

Edwin Carlinet's avatar
Edwin Carlinet committed
42
  /// \overload
Edwin Carlinet's avatar
Edwin Carlinet committed
43
  template <typename InputImage, class UnaryFunction>
44
45
46
47
48
  mln_ch_value(InputImage,
	       typename std::decay<
		 typename std::result_of<UnaryFunction(mln_value(InputImage))>::type
		 >::type)
  transform(const Image<InputImage>& input, UnaryFunction f);
Edwin Carlinet's avatar
Edwin Carlinet committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62


/******************************************/
/****          Implementation          ****/
/******************************************/

  namespace impl
  {
    template <typename I, typename J, class UnaryFunction>
    void
    transform(const I& input, UnaryFunction f, J& output)
    {
      mln_viter(vin, vout, input, output);
      mln_forall(vin, vout)
Edwin Carlinet's avatar
Edwin Carlinet committed
63
        *vout = f(*vin);
Edwin Carlinet's avatar
Edwin Carlinet committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    }

  }


  template <typename InputImage, typename OutputImage, class UnaryFunction>
  OutputImage&
  transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>& output)
  {
    OutputImage& out = exact(output);
    impl::transform(exact(input), f, exact(output));
    return out;
  }

  template <typename InputImage, typename OutputImage, class UnaryFunction>
  OutputImage&&
  transform(const Image<InputImage>& input, UnaryFunction f, Image<OutputImage>&& output)
  {
Edwin Carlinet's avatar
Edwin Carlinet committed
82
    mln::transform(input, f, output);
Edwin Carlinet's avatar
Edwin Carlinet committed
83
84
85
86
87
    return move_exact(output);
  }


  template <typename InputImage, class UnaryFunction>
88
89
90
91
  mln_ch_value(InputImage,
	       typename std::decay<
		 typename std::result_of<UnaryFunction(mln_value(InputImage))>::type
		 >::type)
Edwin Carlinet's avatar
Edwin Carlinet committed
92
93
    transform(const Image<InputImage>& input, UnaryFunction f)
  {
94
95
96
97
    typedef typename std::decay<
      typename std::result_of<UnaryFunction(mln_value(InputImage))>::type
      >::type T;

Edwin Carlinet's avatar
Edwin Carlinet committed
98
99
100
    mln_ch_value(InputImage, T) out;
    resize(out, input);

Edwin Carlinet's avatar
Edwin Carlinet committed
101
    mln::transform(input, f, out);
Edwin Carlinet's avatar
Edwin Carlinet committed
102
103
104
    return out;
  }

105
106
107
108
109
110
111
112
  template <typename InputImage, class UnaryFunction>
  unary_image_expr<UnaryFunction, InputImage>
  lazy_transform(InputImage&& input, UnaryFunction f)
  {
    return make_unary_image_expr(std::forward<InputImage>(input), f);
  }


Edwin Carlinet's avatar
Edwin Carlinet committed
113
114
115
116
117
}



#endif // ! MLN_CORE_ALGORITHM_TRANSFORM_HPP