pixel_numeric_operations.hpp 7.3 KB

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