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