Boost GIL


channel_numeric_operations.hpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 // Copyright 2021 Pranam Lashkari <plashkari628@gmail.com>
4 //
5 // Distributed under the Boost Software License, Version 1.0
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 //
9 #ifndef BOOST_GIL_CHANNEL_NUMERIC_OPERATIONS_HPP
10 #define BOOST_GIL_CHANNEL_NUMERIC_OPERATIONS_HPP
11 
12 #include <boost/gil/channel.hpp>
13 
14 namespace boost { namespace gil {
15 
16 // Function objects and utilities for channel-wise numeric operations.
17 //
18 // List of currently defined functors:
19 // channel_plus_t (+)
20 // channel_minus_t (-)
21 // channel_multiplies_t (*)
22 // channel_divides_t (/),
23 // channel_plus_scalar_t (+s)
24 // channel_minus_scalar_t (-s),
25 // channel_multiplies_scalar_t (*s)
26 // channel_divides_scalar_t (/s),
27 // channel_halves_t (/=2)
28 // channel_zeros_t (=0)
29 // channel_assigns_t (=)
30 
34 template <typename Channel1, typename Channel2, typename ChannelResult>
36 {
37  using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
38  using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
39  static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
40  "ChannelRef1 not convertible to ChannelResult");
41  static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
42  "ChannelRef2 not convertible to ChannelResult");
43 
46  auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
47  {
48  return ChannelResult(ch1) + ChannelResult(ch2);
49  }
50 };
51 
55 template <typename Channel1, typename Channel2, typename ChannelResult>
57 {
58  using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
59  using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
60  static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
61  "ChannelRef1 not convertible to ChannelResult");
62  static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
63  "ChannelRef2 not convertible to ChannelResult");
64 
67  auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
68  {
69  return ChannelResult(ch1) - ChannelResult(ch2);
70  }
71 };
72 
76 template <typename Channel1, typename Channel2, typename ChannelResult>
78 {
79  using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
80  using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
81  static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
82  "ChannelRef1 not convertible to ChannelResult");
83  static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
84  "ChannelRef2 not convertible to ChannelResult");
85 
88  auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
89  {
90  return ChannelResult(ch1) * ChannelResult(ch2);
91  }
92 };
93 
97 template <typename Channel1, typename Channel2, typename ChannelResult>
99 {
100  using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
101  using ChannelRef2 = typename channel_traits<Channel2>::const_reference;
102  static_assert(std::is_convertible<ChannelRef1, ChannelResult>::value,
103  "ChannelRef1 not convertible to ChannelResult");
104  static_assert(std::is_convertible<ChannelRef2, ChannelResult>::value,
105  "ChannelRef2 not convertible to ChannelResult");
106 
109  auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
110  {
111  return ChannelResult(ch1) / ChannelResult(ch2);
112  }
113 };
114 
118 template <typename Channel, typename Scalar, typename ChannelResult>
120 {
121  using ChannelRef = typename channel_traits<Channel>::const_reference;
122  static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
123  "ChannelRef not convertible to ChannelResult");
124  static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
125  static_assert(std::is_convertible<Scalar, ChannelResult>::value,
126  "Scalar not convertible to ChannelResult");
127 
128  auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
129  {
130  return ChannelResult(channel) + ChannelResult(scalar);
131  }
132 };
133 
137 template <typename Channel, typename Scalar, typename ChannelResult>
139 {
140  using ChannelRef = typename channel_traits<Channel>::const_reference;
141  static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
142  "ChannelRef not convertible to ChannelResult");
143  static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
144  static_assert(std::is_convertible<Scalar, ChannelResult>::value,
145  "Scalar not convertible to ChannelResult");
146 
149  auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
150  {
151  // TODO: Conversion after subtraction vs conversion of operands in channel_minus_t?
152  return ChannelResult(channel - scalar);
153  }
154 };
155 
159 template <typename Channel, typename Scalar, typename ChannelResult>
161 {
162  using ChannelRef = typename channel_traits<Channel>::const_reference;
163  static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
164  "ChannelRef not convertible to ChannelResult");
165  static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
166  static_assert(std::is_convertible<Scalar, ChannelResult>::value,
167  "Scalar not convertible to ChannelResult");
168 
171  auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
172  {
173  return ChannelResult(channel) * ChannelResult(scalar);
174  }
175 };
176 
180 template <typename Channel, typename Scalar, typename ChannelResult>
182 {
183  using ChannelRef = typename channel_traits<Channel>::const_reference;
184  static_assert(std::is_convertible<ChannelRef, ChannelResult>::value,
185  "ChannelRef not convertible to ChannelResult");
186  static_assert(std::is_scalar<Scalar>::value, "Scalar not a scalar");
187  static_assert(std::is_convertible<Scalar, ChannelResult>::value,
188  "Scalar not convertible to ChannelResult");
189 
192  auto operator()(ChannelRef channel, Scalar const& scalar) const -> ChannelResult
193  {
194  return ChannelResult(channel) / ChannelResult(scalar);
195  }
196 };
197 
201 template <typename Channel>
203 {
204  using ChannelRef = typename channel_traits<Channel>::reference;
205 
206  auto operator()(ChannelRef channel) const -> ChannelRef
207  {
208  // TODO: Split into steps: extract with explicit conversion to double, divide and assign?
209  //double const v = ch;
210  //ch = static_cast<Channel>(v / 2.0);
211  channel /= 2.0;
212  return channel;
213  }
214 };
215 
219 template <typename Channel>
221 {
222  using ChannelRef = typename channel_traits<Channel>::reference;
223 
224  auto operator()(ChannelRef channel) const -> ChannelRef
225  {
226  channel = Channel(0);
227  return channel;
228  }
229 };
230 
234 template <typename Channel1, typename Channel2>
236 {
237  using ChannelRef1 = typename channel_traits<Channel1>::const_reference;
238  using ChannelRef2 = typename channel_traits<Channel2>::reference;
239  static_assert(std::is_convertible<ChannelRef1, Channel2>::value,
240  "ChannelRef1 not convertible to Channel2");
241 
244  auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelRef2
245  {
246  ch2 = Channel2(ch1);
247  return ch2;
248  }
249 };
250 
251 }} // namespace boost::gil
252 
253 #endif
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36
Definition: channel_numeric_operations.hpp:236
auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelRef2
Definition: channel_numeric_operations.hpp:244
Arithmetic operation of dividing channel value by scalar.
Definition: channel_numeric_operations.hpp:182
auto operator()(ChannelRef channel, Scalar const &scalar) const -> ChannelResult
Definition: channel_numeric_operations.hpp:192
Arithmetic operation of division of two channel values.
Definition: channel_numeric_operations.hpp:99
auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
Definition: channel_numeric_operations.hpp:109
Arithmetic operation of dividing channel value by 2.
Definition: channel_numeric_operations.hpp:203
Arithmetic operation of subtracting scalar from channel value.
Definition: channel_numeric_operations.hpp:139
auto operator()(ChannelRef channel, Scalar const &scalar) const -> ChannelResult
Definition: channel_numeric_operations.hpp:149
Arithmetic operation of subtraction of two channel values.
Definition: channel_numeric_operations.hpp:57
auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
Definition: channel_numeric_operations.hpp:67
Arithmetic operation of channel value by a scalar.
Definition: channel_numeric_operations.hpp:161
auto operator()(ChannelRef channel, Scalar const &scalar) const -> ChannelResult
Definition: channel_numeric_operations.hpp:171
Arithmetic operation of multiplication of two channel values.
Definition: channel_numeric_operations.hpp:78
auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
Definition: channel_numeric_operations.hpp:88
Arithmetic operation of adding scalar to channel value.
Definition: channel_numeric_operations.hpp:120
Arithmetic operation of addition of two channel values.
Definition: channel_numeric_operations.hpp:36
auto operator()(ChannelRef1 ch1, ChannelRef2 ch2) const -> ChannelResult
Definition: channel_numeric_operations.hpp:46
Operation of setting channel value to zero.
Definition: channel_numeric_operations.hpp:221