channel.hpp 6.3 KB

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