channel.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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_CONCEPTS_CHANNEL_HPP
  9. #define BOOST_GIL_CONCEPTS_CHANNEL_HPP
  10. #include <boost/gil/concepts/basic.hpp>
  11. #include <boost/gil/concepts/concept_check.hpp>
  12. #include <boost/gil/concepts/fwd.hpp>
  13. #include <boost/concept_check.hpp>
  14. #include <utility> // std::swap
  15. #if defined(BOOST_CLANG)
  16. #pragma clang diagnostic push
  17. #pragma clang diagnostic ignored "-Wunused-local-typedefs"
  18. #endif
  19. #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
  20. #pragma GCC diagnostic push
  21. #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
  22. #endif
  23. namespace boost { namespace gil {
  24. // Forward declarations
  25. template <typename T>
  26. struct channel_traits;
  27. template <typename DstT, typename SrcT>
  28. auto channel_convert(SrcT const& val)
  29. -> typename channel_traits<DstT>::value_type;
  30. /// \ingroup ChannelConcept
  31. /// \brief A channel is the building block of a color.
  32. /// Color is defined as a mixture of primary colors and a channel defines
  33. /// the degree to which each primary color is used in the mixture.
  34. ///
  35. /// For example, in the RGB color space, using 8-bit unsigned channels,
  36. /// the color red is defined as [255 0 0], which means maximum of Red,
  37. /// and no Green and Blue.
  38. ///
  39. /// Built-in scalar types, such as \p int and \p float, are valid GIL channels.
  40. /// In more complex scenarios, channels may be represented as bit ranges or
  41. /// even individual bits.
  42. /// In such cases special classes are needed to represent the value and
  43. /// reference to a channel.
  44. ///
  45. /// Channels have a traits class, \p channel_traits, which defines their
  46. /// associated types as well as their operating ranges.
  47. ///
  48. /// \code
  49. /// concept ChannelConcept<typename T> : EqualityComparable<T>
  50. /// {
  51. /// typename value_type = T; // use channel_traits<T>::value_type to access it
  52. /// typename reference = T&; // use channel_traits<T>::reference to access it
  53. /// typename pointer = T*; // use channel_traits<T>::pointer to access it
  54. /// typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
  55. /// typename const_pointer = const T*; // use channel_traits<T>::const_pointer to access it
  56. /// static const bool is_mutable; // use channel_traits<T>::is_mutable to access it
  57. ///
  58. /// static T min_value(); // use channel_traits<T>::min_value to access it
  59. /// static T max_value(); // use channel_traits<T>::min_value to access it
  60. /// };
  61. /// \endcode
  62. template <typename T>
  63. struct ChannelConcept
  64. {
  65. void constraints()
  66. {
  67. gil_function_requires<boost::EqualityComparableConcept<T>>();
  68. using v = typename channel_traits<T>::value_type;
  69. using r = typename channel_traits<T>::reference;
  70. using p = typename channel_traits<T>::pointer;
  71. using cr = typename channel_traits<T>::const_reference;
  72. using cp = typename channel_traits<T>::const_pointer;
  73. channel_traits<T>::min_value();
  74. channel_traits<T>::max_value();
  75. }
  76. T c;
  77. };
  78. namespace detail
  79. {
  80. /// \tparam T models ChannelConcept
  81. template <typename T>
  82. struct ChannelIsMutableConcept
  83. {
  84. void constraints()
  85. {
  86. c1 = c2;
  87. using std::swap;
  88. swap(c1, c2);
  89. }
  90. T c1;
  91. T c2;
  92. };
  93. } // namespace detail
  94. /// \brief A channel that allows for modifying its value
  95. /// \code
  96. /// concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
  97. /// \endcode
  98. /// \ingroup ChannelConcept
  99. template <typename T>
  100. struct MutableChannelConcept
  101. {
  102. void constraints()
  103. {
  104. gil_function_requires<ChannelConcept<T>>();
  105. gil_function_requires<detail::ChannelIsMutableConcept<T>>();
  106. }
  107. };
  108. /// \brief A channel that supports default construction.
  109. /// \code
  110. /// concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
  111. /// \endcode
  112. /// \ingroup ChannelConcept
  113. template <typename T>
  114. struct ChannelValueConcept
  115. {
  116. void constraints()
  117. {
  118. gil_function_requires<ChannelConcept<T>>();
  119. gil_function_requires<Regular<T>>();
  120. }
  121. };
  122. /// \brief Predicate metafunction returning whether two channels are compatible
  123. ///
  124. /// Channels are considered compatible if their value types
  125. /// (ignoring constness and references) are the same.
  126. ///
  127. /// Example:
  128. ///
  129. /// \code
  130. /// static_assert(channels_are_compatible<uint8_t, const uint8_t&>::value, "");
  131. /// \endcode
  132. /// \ingroup ChannelAlgorithm
  133. template <typename T1, typename T2> // Models GIL Pixel
  134. struct channels_are_compatible
  135. : is_same
  136. <
  137. typename channel_traits<T1>::value_type,
  138. typename channel_traits<T2>::value_type
  139. >
  140. {
  141. };
  142. /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
  143. ///
  144. /// \code
  145. /// concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2>
  146. /// {
  147. /// where SameType<T1::value_type, T2::value_type>;
  148. /// };
  149. /// \endcode
  150. /// \ingroup ChannelConcept
  151. template <typename Channel1, typename Channel2>
  152. struct ChannelsCompatibleConcept
  153. {
  154. void constraints()
  155. {
  156. static_assert(channels_are_compatible<Channel1, Channel2>::value, "");
  157. }
  158. };
  159. /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels.
  160. ///
  161. /// Convertibility is non-symmetric and implies that one channel can be
  162. /// converted to another. Conversion is explicit and often lossy operation.
  163. ///
  164. /// concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel>
  165. /// {
  166. /// DstChannel channel_convert(const SrcChannel&);
  167. /// };
  168. /// \endcode
  169. /// \ingroup ChannelConcept
  170. template <typename SrcChannel, typename DstChannel>
  171. struct ChannelConvertibleConcept
  172. {
  173. void constraints()
  174. {
  175. gil_function_requires<ChannelConcept<SrcChannel>>();
  176. gil_function_requires<MutableChannelConcept<DstChannel>>();
  177. dst = channel_convert<DstChannel, SrcChannel>(src);
  178. ignore_unused_variable_warning(dst);
  179. }
  180. SrcChannel src;
  181. DstChannel dst;
  182. };
  183. }} // namespace boost::gil
  184. #if defined(BOOST_CLANG)
  185. #pragma clang diagnostic pop
  186. #endif
  187. #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
  188. #pragma GCC diagnostic pop
  189. #endif
  190. #endif