pixel_numeric_operations.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. Copyright 2005-2007 Adobe Systems Incorporated
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. /*************************************************************************************************/
  8. #ifndef BOOST_GIL_EXTENSION_NUMERIC_PIXEL_NUMERIC_OPERATIONS_HPP
  9. #define BOOST_GIL_EXTENSION_NUMERIC_PIXEL_NUMERIC_OPERATIONS_HPP
  10. /*!
  11. /// \file
  12. /// \brief Structures for pixel-wise numeric operations
  13. /// \author Lubomir Bourdev and Hailin Jin \n
  14. /// Adobe Systems Incorporated
  15. /// \date 2005-2007 \n
  16. /// Currently defined structures:
  17. /// pixel_plus_t (+), pixel_minus_t (-)
  18. /// pixel_multiplies_scalar_t (*), pixel_divides_scalar_t (/)
  19. /// pixel_halves_t (/=2), pixel_zeros_t (=0)
  20. /// pixel_assigns_t (=)
  21. */
  22. #include <functional>
  23. #include <boost/gil/gil_config.hpp>
  24. #include <boost/gil/pixel.hpp>
  25. #include <boost/gil/color_base_algorithm.hpp>
  26. #include <boost/gil/extension/numeric/channel_numeric_operations.hpp>
  27. namespace boost { namespace gil {
  28. /// \ingroup PixelNumericOperations
  29. /// \brief construct for adding two pixels
  30. template <typename PixelRef1, // models pixel concept
  31. typename PixelRef2, // models pixel concept
  32. typename PixelR> // models pixel value concept
  33. struct pixel_plus_t {
  34. PixelR operator() (const PixelRef1& p1,
  35. const PixelRef2& p2) const {
  36. PixelR result;
  37. static_transform(p1,p2,result,
  38. channel_plus_t<typename channel_type<PixelRef1>::type,
  39. typename channel_type<PixelRef2>::type,
  40. typename channel_type<PixelR>::type>());
  41. return result;
  42. }
  43. };
  44. /// \ingroup PixelNumericOperations
  45. /// \brief construct for subtracting two pixels
  46. template <typename PixelRef1, // models pixel concept
  47. typename PixelRef2, // models pixel concept
  48. typename PixelR> // models pixel value concept
  49. struct pixel_minus_t {
  50. PixelR operator() (const PixelRef1& p1,
  51. const PixelRef2& p2) const {
  52. PixelR result;
  53. static_transform(p1,p2,result,
  54. channel_minus_t<typename channel_type<PixelRef1>::type,
  55. typename channel_type<PixelRef2>::type,
  56. typename channel_type<PixelR>::type>());
  57. return result;
  58. }
  59. };
  60. /// \ingroup PixelNumericOperations
  61. /// \brief construct for multiplying scalar to a pixel
  62. template <typename PixelRef, // models pixel concept
  63. typename Scalar, // models a scalar type
  64. typename PixelR> // models pixel value concept
  65. struct pixel_multiplies_scalar_t {
  66. PixelR operator () (const PixelRef& p,
  67. const Scalar& s) const {
  68. PixelR result;
  69. static_transform(p,result,
  70. std::bind2nd(channel_multiplies_scalar_t<typename channel_type<PixelRef>::type,
  71. Scalar,
  72. typename channel_type<PixelR>::type>(),s));
  73. return result;
  74. }
  75. };
  76. /// \ingroup PixelNumericOperations
  77. /// \brief construct for dividing two pixels
  78. template <typename PixelRef1, // models pixel concept
  79. typename PixelRef2, // models pixel concept
  80. typename PixelR> // models pixel value concept
  81. struct pixel_multiply_t {
  82. PixelR operator() (const PixelRef1& p1,
  83. const PixelRef2& p2) const {
  84. PixelR result;
  85. static_transform(p1,p2,result,
  86. channel_multiplies_t<typename channel_type<PixelRef1>::type,
  87. typename channel_type<PixelRef2>::type,
  88. typename channel_type<PixelR>::type>());
  89. return result;
  90. }
  91. };
  92. /// \ingroup PixelNumericOperations
  93. /// \brief construct for dividing a pixel by a scalar
  94. template <typename PixelRef, // models pixel concept
  95. typename Scalar, // models a scalar type
  96. typename PixelR> // models pixel value concept
  97. struct pixel_divides_scalar_t {
  98. PixelR operator () (const PixelRef& p,
  99. const Scalar& s) const {
  100. PixelR result;
  101. static_transform(p,result,
  102. std::bind2nd(channel_divides_scalar_t<typename channel_type<PixelRef>::type,
  103. Scalar,
  104. typename channel_type<PixelR>::type>(),s));
  105. return result;
  106. }
  107. };
  108. /// \ingroup PixelNumericOperations
  109. /// \brief construct for dividing two pixels
  110. template <typename PixelRef1, // models pixel concept
  111. typename PixelRef2, // models pixel concept
  112. typename PixelR> // models pixel value concept
  113. struct pixel_divide_t {
  114. PixelR operator() (const PixelRef1& p1,
  115. const PixelRef2& p2) const {
  116. PixelR result;
  117. static_transform(p1,p2,result,
  118. channel_divides_t<typename channel_type<PixelRef1>::type,
  119. typename channel_type<PixelRef2>::type,
  120. typename channel_type<PixelR>::type>());
  121. return result;
  122. }
  123. };
  124. /// \ingroup PixelNumericOperations
  125. /// \brief construct for dividing a pixel by 2
  126. template <typename PixelRef> // models pixel concept
  127. struct pixel_halves_t {
  128. PixelRef& operator () (PixelRef& p) const {
  129. static_for_each(p,channel_halves_t<typename channel_type<PixelRef>::type>());
  130. return p;
  131. }
  132. };
  133. /// \ingroup PixelNumericOperations
  134. /// \brief construct for setting a pixel to zero (for whatever zero means)
  135. template <typename PixelRef> // models pixel concept
  136. struct pixel_zeros_t {
  137. PixelRef& operator () (PixelRef& p) const {
  138. static_for_each(p,channel_zeros_t<typename channel_type<PixelRef>::type>());
  139. return p;
  140. }
  141. };
  142. // Hailin: This is how you can do it:
  143. template <typename Pixel>
  144. void zero_channels(Pixel& p) {
  145. static_for_each(p,channel_zeros_t<typename channel_type<Pixel>::type>());
  146. }
  147. /// \ingroup PixelNumericOperations
  148. ///definition and a generic implementation for casting and assigning a pixel to another
  149. ///user should specialize it for better performance
  150. template <typename PixelRef, // models pixel concept
  151. typename PixelRefR> // models pixel concept
  152. struct pixel_assigns_t {
  153. PixelRefR operator () (const PixelRef& src,
  154. PixelRefR& dst) const {
  155. static_for_each(src,dst,channel_assigns_t<typename channel_type<PixelRef>::type,
  156. typename channel_type<PixelRefR>::type>());
  157. return dst;
  158. }
  159. };
  160. } } // namespace boost::gil
  161. #endif // BOOST_GIL_EXTENSION_NUMERIC_PIXEL_NUMERIC_OPERATIONS_HPP