Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / gil / extension / numeric / pixel_numeric_operations.hpp
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 {
37     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 {
59     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 {
81     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 {
102     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 {
124     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 {
144     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 {
164     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 {
177     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>
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 {
203     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