pixel_numeric_operations.hpp 6.9 KB

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