pixel_numeric_operations.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. // Structures for pixel-wise numeric operations
  15. // Currently defined structures:
  16. // pixel_plus_t (+), pixel_minus_t (-)
  17. // pixel_multiplies_scalar_t (*), pixel_divides_scalar_t (/)
  18. // pixel_halves_t (/=2), pixel_zeros_t (=0)
  19. // pixel_assigns_t (=)
  20. /// \ingroup PixelNumericOperations
  21. /// \brief construct for adding two pixels
  22. template <typename PixelRef1, // models pixel concept
  23. typename PixelRef2, // models pixel concept
  24. typename PixelR> // models pixel value concept
  25. struct pixel_plus_t {
  26. PixelR operator() (const PixelRef1& p1,
  27. const PixelRef2& p2) const {
  28. PixelR result;
  29. static_transform(p1,p2,result,
  30. channel_plus_t<typename channel_type<PixelRef1>::type,
  31. typename channel_type<PixelRef2>::type,
  32. typename channel_type<PixelR>::type>());
  33. return result;
  34. }
  35. };
  36. /// \ingroup PixelNumericOperations
  37. /// \brief construct for subtracting two pixels
  38. template <typename PixelRef1, // models pixel concept
  39. typename PixelRef2, // models pixel concept
  40. typename PixelR> // models pixel value concept
  41. struct pixel_minus_t {
  42. PixelR operator() (const PixelRef1& p1,
  43. const PixelRef2& p2) const {
  44. PixelR result;
  45. static_transform(p1,p2,result,
  46. channel_minus_t<typename channel_type<PixelRef1>::type,
  47. typename channel_type<PixelRef2>::type,
  48. typename channel_type<PixelR>::type>());
  49. return result;
  50. }
  51. };
  52. /// \ingroup PixelNumericOperations
  53. /// \brief construct for multiplying scalar to a pixel
  54. template <typename PixelRef, // models pixel concept
  55. typename Scalar, // models a scalar type
  56. typename PixelR> // models pixel value concept
  57. struct pixel_multiplies_scalar_t {
  58. PixelR operator () (const PixelRef& p,
  59. const Scalar& s) const {
  60. PixelR result;
  61. static_transform(p,result,
  62. std::bind(channel_multiplies_scalar_t<typename channel_type<PixelRef>::type,
  63. Scalar,
  64. typename channel_type<PixelR>::type>(),
  65. std::placeholders::_1, s));
  66. return result;
  67. }
  68. };
  69. /// \ingroup PixelNumericOperations
  70. /// \brief construct for dividing two pixels
  71. template <typename PixelRef1, // models pixel concept
  72. typename PixelRef2, // models pixel concept
  73. typename PixelR> // models pixel value concept
  74. struct pixel_multiply_t {
  75. PixelR operator() (const PixelRef1& p1,
  76. const PixelRef2& p2) const {
  77. PixelR result;
  78. static_transform(p1,p2,result,
  79. channel_multiplies_t<typename channel_type<PixelRef1>::type,
  80. typename channel_type<PixelRef2>::type,
  81. typename channel_type<PixelR>::type>());
  82. return result;
  83. }
  84. };
  85. /// \ingroup PixelNumericOperations
  86. /// \brief construct for dividing a pixel by a scalar
  87. template <typename PixelRef, // models pixel concept
  88. typename Scalar, // models a scalar type
  89. typename PixelR> // models pixel value concept
  90. struct pixel_divides_scalar_t {
  91. PixelR operator () (const PixelRef& p,
  92. const Scalar& s) const {
  93. PixelR result;
  94. static_transform(p,result,
  95. std::bind(channel_divides_scalar_t<typename channel_type<PixelRef>::type,
  96. Scalar,
  97. typename channel_type<PixelR>::type>(),
  98. std::placeholders::_1, s));
  99. return result;
  100. }
  101. };
  102. /// \ingroup PixelNumericOperations
  103. /// \brief construct for dividing two pixels
  104. template <typename PixelRef1, // models pixel concept
  105. typename PixelRef2, // models pixel concept
  106. typename PixelR> // models pixel value concept
  107. struct pixel_divide_t {
  108. PixelR operator() (const PixelRef1& p1,
  109. const PixelRef2& p2) const {
  110. PixelR result;
  111. static_transform(p1,p2,result,
  112. channel_divides_t<typename channel_type<PixelRef1>::type,
  113. typename channel_type<PixelRef2>::type,
  114. typename channel_type<PixelR>::type>());
  115. return result;
  116. }
  117. };
  118. /// \ingroup PixelNumericOperations
  119. /// \brief construct for dividing a pixel by 2
  120. template <typename PixelRef> // models pixel concept
  121. struct pixel_halves_t {
  122. PixelRef& operator () (PixelRef& p) const {
  123. static_for_each(p,channel_halves_t<typename channel_type<PixelRef>::type>());
  124. return p;
  125. }
  126. };
  127. /// \ingroup PixelNumericOperations
  128. /// \brief construct for setting a pixel to zero (for whatever zero means)
  129. template <typename PixelRef> // models pixel concept
  130. struct pixel_zeros_t {
  131. PixelRef& operator () (PixelRef& p) const {
  132. static_for_each(p,channel_zeros_t<typename channel_type<PixelRef>::type>());
  133. return p;
  134. }
  135. };
  136. // Hailin: This is how you can do it:
  137. template <typename Pixel>
  138. void zero_channels(Pixel& p) {
  139. static_for_each(p,channel_zeros_t<typename channel_type<Pixel>::type>());
  140. }
  141. /// \ingroup PixelNumericOperations
  142. ///definition and a generic implementation for casting and assigning a pixel to another
  143. ///user should specialize it for better performance
  144. template <typename PixelRef, // models pixel concept
  145. typename PixelRefR> // models pixel concept
  146. struct pixel_assigns_t {
  147. PixelRefR operator () (const PixelRef& src,
  148. PixelRefR& dst) const {
  149. static_for_each(src,dst,channel_assigns_t<typename channel_type<PixelRef>::type,
  150. typename channel_type<PixelRefR>::type>());
  151. return dst;
  152. }
  153. };
  154. }} // namespace boost::gil
  155. #endif