]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/gil/extension/numeric/channel_numeric_operations.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / gil / extension / numeric / channel_numeric_operations.hpp
CommitLineData
92f5a8d4
TL
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_CHANNEL_NUMERIC_OPERATIONS_HPP
9#define BOOST_GIL_EXTENSION_NUMERIC_CHANNEL_NUMERIC_OPERATIONS_HPP
10
11#include <boost/gil/channel.hpp>
12
13namespace boost { namespace gil {
14
15// Function objects and utilities for channel-wise numeric operations.
16//
17// List of currently defined functors:
18// channel_plus_t (+)
19// channel_minus_t (-)
20// channel_multiplies_t (*)
21// channel_divides_t (/),
22// channel_plus_scalar_t (+s)
23// channel_minus_scalar_t (-s),
24// channel_multiplies_scalar_t (*s)
25// channel_divides_scalar_t (/s),
26// channel_halves_t (/=2)
27// channel_zeros_t (=0)
28// channel_assigns_t (=)
29
30/// \ingroup ChannelNumericOperations
31/// \brief Arithmetic operation of addition of two channel values.
32/// \note This is a generic implementation; user should specialize it for better performance.
33template <typename Channel1, typename Channel2, typename ChannelResult>
34struct channel_plus_t
35{
36 using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
37 using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
38 static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
39 "ChannelRef1 not convertible to ChannelResult");
40 static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
41 "ChannelRef2 not convertible to ChannelResult");
42
43 /// \param ch1 - first of the two addends (augend).
44 /// \param ch2 - second of the two addends.
45 auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
46 {
47 return ChannelResult(ch1) + ChannelResult(ch2);
48 }
49};
50
51/// \ingroup ChannelNumericOperations
52/// \brief Arithmetic operation of subtraction of two channel values.
53/// \note This is a generic implementation; user should specialize it for better performance.
54template <typename Channel1, typename Channel2, typename ChannelResult>
55struct channel_minus_t
56{
57 using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
58 using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
59 static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
60 "ChannelRef1 not convertible to ChannelResult");
61 static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
62 "ChannelRef2 not convertible to ChannelResult");
63
64 /// \param ch1 - minuend operand of the subtraction.
65 /// \param ch2 - subtrahend operand of the subtraction.
66 auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
67 {
68 return ChannelResult(ch1) - ChannelResult(ch2);
69 }
70};
71
72/// \ingroup ChannelNumericOperations
73/// \brief Arithmetic operation of multiplication of two channel values.
74/// \note This is a generic implementation; user should specialize it for better performance.
75template <typename Channel1, typename Channel2, typename ChannelResult>
76struct channel_multiplies_t
77{
78 using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
79 using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
80 static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
81 "ChannelRef1 not convertible to ChannelResult");
82 static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
83 "ChannelRef2 not convertible to ChannelResult");
84
85 /// \param ch1 - first of the two factors (multiplicand).
86 /// \param ch2 - second of the two factors (multiplier).
87 auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
88 {
89 return ChannelResult(ch1) * ChannelResult(ch2);
90 }
91};
92
93/// \ingroup ChannelNumericOperations
94/// \brief Arithmetic operation of division of two channel values.
95/// \note This is a generic implementation; user should specialize it for better performance.
96template <typename Channel1, typename Channel2, typename ChannelResult>
97struct channel_divides_t
98{
99 using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
100 using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
101 static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
102 "ChannelRef1 not convertible to ChannelResult");
103 static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
104 "ChannelRef2 not convertible to ChannelResult");
105
106 /// \param ch1 - dividend operand of the two division operation.
107 /// \param ch2 - divisor operand of the two division operation.
108 auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
109 {
110 return ChannelResult(ch1) / ChannelResult(ch2);
111 }
112};
113
114/// \ingroup ChannelNumericOperations
115/// \brief Arithmetic operation of adding scalar to channel value.
116/// \note This is a generic implementation; user should specialize it for better performance.
117template <typename Channel, typename Scalar, typename ChannelResult>
118struct channel_plus_scalar_t
119{
120 using ChannelRef = typename channel_traits<Channel>::const_reference;
121 static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
122 "ChannelRef not convertible to ChannelResult");
123 static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
124 static_assert(std::is_convertible<Scalar, ChannelResult>::value,
125 "Scalar not convertible to ChannelResult");
126
127 auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
128 {
129 return ChannelResult(channel) + ChannelResult(scalar);
130 }
131};
132
133/// \ingroup ChannelNumericOperations
134/// \brief Arithmetic operation of subtracting scalar from channel value.
135/// \note This is a generic implementation; user should specialize it for better performance.
136template <typename Channel, typename Scalar, typename ChannelResult>
137struct channel_minus_scalar_t
138{
139 using ChannelRef = typename channel_traits<Channel>::const_reference;
140 static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
141 "ChannelRef not convertible to ChannelResult");
142 static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
143 static_assert(std::is_convertible<Scalar, ChannelResult>::value,
144 "Scalar not convertible to ChannelResult");
145
146 /// \param channel - minuend operand of the subtraction.
147 /// \param scalar - subtrahend operand of the subtraction.
148 auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
149 {
150 // TODO: Convertion after subtraction vs conversion of operands in channel_minus_t?
151 return ChannelResult(channel - scalar);
152 }
153};
154
155/// \ingroup ChannelNumericOperations
156/// \brief Arithmetic operation of channel value by a scalar.
157/// \note This is a generic implementation; user should specialize it for better performance.
158template <typename Channel, typename Scalar, typename ChannelResult>
159struct channel_multiplies_scalar_t
160{
161 using ChannelRef = typename channel_traits<Channel>::const_reference;
162 static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
163 "ChannelRef not convertible to ChannelResult");
164 static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
165 static_assert(std::is_convertible<Scalar, ChannelResult>::value,
166 "Scalar not convertible to ChannelResult");
167
168 /// \param channel - first of the two factors (multiplicand).
169 /// \param scalar - second of the two factors (multiplier).
170 auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
171 {
172 return ChannelResult(channel) * ChannelResult(scalar);
173 }
174};
175
176/// \ingroup ChannelNumericOperations
177/// \brief Arithmetic operation of dividing channel value by scalar.
178/// \note This is a generic implementation; user should specialize it for better performance.
179template <typename Channel, typename Scalar, typename ChannelResult>
180struct channel_divides_scalar_t
181{
182 using ChannelRef = typename channel_traits<Channel>::const_reference;
183 static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
184 "ChannelRef not convertible to ChannelResult");
185 static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
186 static_assert(std::is_convertible<Scalar, ChannelResult>::value,
187 "Scalar not convertible to ChannelResult");
188
189 /// \param channel - dividend operand of the two division operation.
190 /// \param scalar - divisor operand of the two division operation.
191 auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
192 {
193 return ChannelResult(channel) / ChannelResult(scalar);
194 }
195};
196
197/// \ingroup ChannelNumericOperations
198/// \brief Arithmetic operation of dividing channel value by 2
199/// \note This is a generic implementation; user should specialize it for better performance.
200template <typename Channel>
201struct channel_halves_t
202{
203 using ChannelRef = typename channel_traits<Channel>::reference;
204
205 auto operator()(ChannelRef channel) const -> ChannelRef
206 {
207 // TODO: Split into steps: extract with explicit conversion to double, divide and assign?
208 //double const v = ch;
209 //ch = static_cast<Channel>(v / 2.0);
210 channel /= 2.0;
211 return channel;
212 }
213};
214
215/// \ingroup ChannelNumericOperations
216/// \brief Operation of setting channel value to zero
217/// \note This is a generic implementation; user should specialize it for better performance.
218template <typename Channel>
219struct channel_zeros_t
220{
221 using ChannelRef = typename channel_traits<Channel>::reference;
222
223 auto operator()(ChannelRef channel) const -> ChannelRef
224 {
225 channel = Channel(0);
226 return channel;
227 }
228};
229
230/// \ingroup ChannelNumericOperations
231/// structure for assigning one channel to another
232/// \note This is a generic implementation; user should specialize it for better performance.
233template <typename Channel1, typename Channel2>
234struct channel_assigns_t
235{
236 using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
237 using ChannelRef2 = typename channel_traits<Channel2>::reference;
238 static_assert(std::is_convertible<ChannelRef1, Channel2>::value,
239 "ChannelRef1 not convertible to Channel2");
240
241 /// \param ch1 - assignor side (input) of the assignment operation
242 /// \param ch2 - assignee side (output) of the assignment operation
243 auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelRef2
244 {
245 ch2 = Channel2(ch1);
246 return ch2;
247 }
248};
249
250}} // namespace boost::gil
251
252#endif