1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #ifndef BOOST_GIL_EXTENSION_NUMERIC_PIXEL_NUMERIC_OPERATIONS_HPP
9 #define BOOST_GIL_EXTENSION_NUMERIC_PIXEL_NUMERIC_OPERATIONS_HPP
10
11 #include <boost/gil/extension/numeric/channel_numeric_operations.hpp>
12
13 #include <boost/gil/color_base_algorithm.hpp>
14 #include <boost/gil/pixel.hpp>
15
16 namespace boost { namespace gil {
17
18 // Function objects and utilities for pixel-wise numeric operations.
19 //
20 // List of currently defined functors:
21 // pixel_plus_t (+)
22 // pixel_minus_t (-)
23 // pixel_multiplies_scalar_t (*)
24 // pixel_divides_scalar_t (/)
25 // pixel_halves_t (/=2),
26 // pixel_zeros_t (=0)
27 // pixel_assigns_t (=)
28
29 /// \ingroup PixelNumericOperations
30 /// \brief Performs channel-wise addition of two pixels.
31 /// \tparam PixelRef1 - models PixelConcept
32 /// \tparam PixelRef2 - models PixelConcept
33 /// \tparam PixelResult - models PixelValueConcept
34 template <typename PixelRef1, typename PixelRef2, typename PixelResult>
35 struct pixel_plus_t
36 {
operator ()boost::gil::pixel_plus_t37 auto operator()(PixelRef1 const& p1, PixelRef2 const& p2) const -> PixelResult
38 {
39 PixelResult result;
40 static_transform(p1, p2, result,
41 channel_plus_t
42 <
43 typename channel_type<PixelRef1>::type,
44 typename channel_type<PixelRef2>::type,
45 typename channel_type<PixelResult>::type
46 >());
47 return result;
48 }
49 };
50
51 /// \ingroup PixelNumericOperations
52 /// \brief Performs channel-wise subtraction of two pixels.
53 /// \tparam PixelRef1 - models PixelConcept
54 /// \tparam PixelRef2 - models PixelConcept
55 /// \tparam PixelResult - models PixelValueConcept
56 template <typename PixelRef1, typename PixelRef2, typename PixelResult>
57 struct pixel_minus_t
58 {
operator ()boost::gil::pixel_minus_t59 auto operator()(PixelRef1 const& p1, PixelRef2 const& p2) const -> PixelResult
60 {
61 PixelResult result;
62 static_transform(p1, p2, result,
63 channel_minus_t
64 <
65 typename channel_type<PixelRef1>::type,
66 typename channel_type<PixelRef2>::type,
67 typename channel_type<PixelResult>::type
68 >());
69 return result;
70 }
71 };
72
73 /// \ingroup PixelNumericOperations
74 /// \brief Performs channel-wise multiplication of pixel elements by scalar.
75 /// \tparam PixelRef - models PixelConcept
76 /// \tparam Scalar - models a scalar type
77 /// \tparam PixelResult - models PixelValueConcept
78 template <typename PixelRef, typename Scalar, typename PixelResult>
79 struct pixel_multiplies_scalar_t
80 {
operator ()boost::gil::pixel_multiplies_scalar_t81 auto operator()(PixelRef const& p, Scalar const& s) const -> PixelResult
82 {
83 PixelResult result;
84 static_transform(p, result,
85 std::bind(
86 channel_multiplies_scalar_t<typename channel_type<PixelRef>::type,
87 Scalar,
88 typename channel_type<PixelResult>::type>(),
89 std::placeholders::_1, s));
90 return result;
91 }
92 };
93
94 /// \ingroup PixelNumericOperations
95 /// \brief Performs channel-wise multiplication of two pixels.
96 /// \tparam PixelRef1 - models PixelConcept
97 /// \tparam PixelRef1 - models PixelConcept
98 /// \tparam PixelResult - models PixelValueConcept
99 template <typename PixelRef1, typename PixelRef2, typename PixelResult>
100 struct pixel_multiply_t
101 {
operator ()boost::gil::pixel_multiply_t102 auto operator()(PixelRef1 const& p1, PixelRef2 const& p2) const -> PixelResult
103 {
104 PixelResult result;
105 static_transform(p1, p2, result,
106 channel_multiplies_t
107 <
108 typename channel_type<PixelRef1>::type,
109 typename channel_type<PixelRef2>::type,
110 typename channel_type<PixelResult>::type
111 >());
112 return result;
113 }
114 };
115
116 /// \ingroup PixelNumericOperations
117 /// \brief Performs channel-wise division of pixel elements by scalar.
118 /// \tparam PixelRef - models PixelConcept
119 /// \tparam Scalar - models a scalar type
120 /// \tparam PixelResult - models PixelValueConcept
121 template <typename PixelRef, typename Scalar, typename PixelResult>
122 struct pixel_divides_scalar_t
123 {
operator ()boost::gil::pixel_divides_scalar_t124 auto operator()(PixelRef const& p, Scalar const& s) const -> PixelResult
125 {
126 PixelResult result;
127 static_transform(p, result,
128 std::bind(channel_divides_scalar_t<typename channel_type<PixelRef>::type,
129 Scalar,
130 typename channel_type<PixelResult>::type>(),
131 std::placeholders::_1, s));
132 return result;
133 }
134 };
135
136 /// \ingroup PixelNumericOperations
137 /// \brief Performs channel-wise division of two pixels.
138 /// \tparam PixelRef1 - models PixelConcept
139 /// \tparam PixelRef1 - models PixelConcept
140 /// \tparam PixelResult - models PixelValueConcept
141 template <typename PixelRef1, typename PixelRef2, typename PixelResult>
142 struct pixel_divide_t
143 {
operator ()boost::gil::pixel_divide_t144 auto operator()(PixelRef1 const& p1, PixelRef2 const& p2) const -> PixelResult
145 {
146 PixelResult result;
147 static_transform(p1, p2, result,
148 channel_divides_t
149 <
150 typename channel_type<PixelRef1>::type,
151 typename channel_type<PixelRef2>::type,
152 typename channel_type<PixelResult>::type
153 >());
154 return result;
155 }
156 };
157
158 /// \ingroup PixelNumericOperations
159 /// \brief Performs channel-wise division by 2
160 /// \tparam PixelRef - models PixelConcept
161 template <typename PixelRef>
162 struct pixel_halves_t
163 {
operator ()boost::gil::pixel_halves_t164 auto operator()(PixelRef& p) const -> PixelRef&
165 {
166 static_for_each(p, channel_halves_t<typename channel_type<PixelRef>::type>());
167 return p;
168 }
169 };
170
171 /// \ingroup PixelNumericOperations
172 /// \brief Sets pixel elements to zero (for whatever zero means)
173 /// \tparam PixelRef - models PixelConcept
174 template <typename PixelRef>
175 struct pixel_zeros_t
176 {
operator ()boost::gil::pixel_zeros_t177 auto operator()(PixelRef& p) const -> PixelRef&
178 {
179 static_for_each(p, channel_zeros_t<typename channel_type<PixelRef>::type>());
180 return p;
181 }
182 };
183
184 /// \brief Sets pixel elements to zero (for whatever zero means)
185 /// \tparam Pixel - models PixelConcept
186 template <typename Pixel>
zero_channels(Pixel & p)187 void zero_channels(Pixel& p)
188 {
189 static_for_each(p, channel_zeros_t<typename channel_type<Pixel>::type>());
190 }
191
192 /// \ingroup PixelNumericOperations
193 /// \brief Casts and assigns a pixel to another
194 ///
195 /// A generic implementation for casting and assigning a pixel to another.
196 /// User should specialize it for better performance.
197 ///
198 /// \tparam PixelRef - models PixelConcept
199 /// \tparam PixelResult - models PixelValueConcept
200 template <typename PixelRef, typename PixelResult>
201 struct pixel_assigns_t
202 {
operator ()boost::gil::pixel_assigns_t203 auto operator()(PixelRef const& src, PixelResult& dst) const -> PixelResult
204 {
205 static_for_each(src, dst,
206 channel_assigns_t
207 <
208 typename channel_type<PixelRef>::type,
209 typename channel_type<PixelResult>::type
210 >());
211 return dst;
212 }
213 };
214
215 }} // namespace boost::gil
216
217 #endif
218