test_fixture.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //
  2. // Copyright 2005-2007 Adobe Systems Incorporated
  3. // Copyright 2018 Mateusz Loskot <mateusz at loskot dot net>
  4. //
  5. // Distributed under the Boost Software License, Version 1.0
  6. // See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt
  8. //
  9. #ifndef BOOST_GIL_TEST_TEST_FIXTURE_HPP
  10. #define BOOST_GIL_TEST_TEST_FIXTURE_HPP
  11. #include <boost/gil/channel.hpp>
  12. #include <boost/gil/concepts.hpp>
  13. #include <boost/gil/typedefs.hpp>
  14. #include <cstdint>
  15. #include <tuple>
  16. #include <type_traits>
  17. namespace boost { namespace gil { namespace test { namespace fixture {
  18. using channel_byte_types = std::tuple
  19. <
  20. std::uint8_t,
  21. std::int8_t,
  22. std::uint16_t,
  23. std::int16_t,
  24. std::uint32_t,
  25. std::int32_t,
  26. gil::float32_t,
  27. gil::float64_t
  28. >;
  29. using channel_integer_types = std::tuple
  30. <
  31. std::uint8_t,
  32. std::int8_t,
  33. std::uint16_t,
  34. std::int16_t,
  35. std::uint32_t,
  36. std::int32_t
  37. >;
  38. using channel_integer_signed_types = std::tuple
  39. <
  40. std::int8_t,
  41. std::int16_t,
  42. std::int32_t
  43. >;
  44. using channel_integer_unsigned_types = std::tuple
  45. <
  46. std::uint8_t,
  47. std::uint16_t,
  48. std::uint32_t
  49. >;
  50. // FIXME: If float types are convertible between each other,
  51. // currently they are not, then move to channel_byte_types and
  52. // remove channel_integer_types as redundant.
  53. using channel_float_types = std::tuple
  54. <
  55. gil::float32_t,
  56. gil::float64_t
  57. >;
  58. using channel_bitfield_types = std::tuple
  59. <
  60. std::uint16_t,
  61. std::uint32_t,
  62. std::uint64_t
  63. // TODO: Shall we test signed types for unexpected conversions, etc.?
  64. >;
  65. template <typename ChannelValue>
  66. struct channel_minmax_value
  67. {
  68. //static_assert(std::)
  69. ChannelValue min_v_;
  70. ChannelValue max_v_;
  71. channel_minmax_value()
  72. : min_v_(gil::channel_traits<ChannelValue>::min_value())
  73. , max_v_(gil::channel_traits<ChannelValue>::max_value())
  74. {}
  75. };
  76. template <typename ChannelFixtureBase>
  77. struct channel : public ChannelFixtureBase
  78. {
  79. using channel_t = typename ChannelFixtureBase::channel_t;
  80. using channel_value_t = typename gil::channel_traits<channel_t>::value_type;
  81. channel()
  82. {
  83. BOOST_TEST(this->min_v_ == gil::channel_traits<channel_t>::min_value());
  84. BOOST_TEST(this->max_v_ == gil::channel_traits<channel_t>::max_value());
  85. }
  86. };
  87. // The channel fixtures are defined for different types of channels
  88. // (ie. channel values, references and subbyte references)
  89. // ensure there are two members, min_v_ and max_v_ initialized
  90. // with the minimum and maximum channel value.
  91. // The different channel types have different ways to initialize them,
  92. // thus require different fixtures provided.
  93. // For basic channel types values can be initialized directly.
  94. template <typename ChannelValue>
  95. struct channel_value
  96. {
  97. using channel_t = ChannelValue;
  98. channel_t min_v_;
  99. channel_t max_v_;
  100. channel_value()
  101. : min_v_(gil::channel_traits<ChannelValue>::min_value())
  102. , max_v_(gil::channel_traits<ChannelValue>::max_value())
  103. {
  104. boost::function_requires<gil::ChannelValueConcept<ChannelValue>>();
  105. }
  106. };
  107. // For channel references we need to have separate channel values.
  108. template <typename ChannelRef>
  109. struct channel_reference
  110. : public channel_value<typename gil::channel_traits<ChannelRef>::value_type>
  111. {
  112. using parent_t = channel_value<typename gil::channel_traits<ChannelRef>::value_type>;
  113. using channel_t = ChannelRef;
  114. channel_t min_v_;
  115. channel_t max_v_;
  116. channel_reference()
  117. : parent_t()
  118. , min_v_(parent_t::min_v_)
  119. , max_v_(parent_t::max_v_)
  120. {
  121. boost::function_requires<ChannelConcept<ChannelRef>>();
  122. }
  123. };
  124. // For sub-byte channel references we need to store the bit buffers somewhere
  125. template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
  126. struct packed_channel_reference
  127. {
  128. using channel_t = ChannelSubbyteRef;
  129. using integer_t = typename channel_t::integer_t;
  130. channel_t min_v_;
  131. channel_t max_v_;
  132. integer_t min_bitbuf_;
  133. integer_t max_bitbuf_;
  134. packed_channel_reference() : min_v_(&min_bitbuf_), max_v_(&max_bitbuf_)
  135. {
  136. boost::function_requires<ChannelConcept<ChannelSubbyteRef>>();
  137. ChannelMutableRef b1(&min_bitbuf_);
  138. b1 = gil::channel_traits<channel_t>::min_value();
  139. ChannelMutableRef b2(&max_bitbuf_);
  140. b2 = gil::channel_traits<channel_t>::max_value();
  141. }
  142. };
  143. // For sub-byte channel references we need to store the bit buffers somewhere
  144. template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
  145. struct packed_dynamic_channel_reference
  146. {
  147. using channel_t = ChannelSubbyteRef;
  148. using integer_t = typename channel_t::integer_t;
  149. channel_t min_v_;
  150. channel_t max_v_;
  151. integer_t min_bitbuf_;
  152. integer_t max_bitbuf_;
  153. packed_dynamic_channel_reference(int first_bit1 = 1, int first_bit2 = 2)
  154. : min_v_(&min_bitbuf_, first_bit1)
  155. , max_v_(&max_bitbuf_, first_bit2)
  156. {
  157. boost::function_requires<ChannelConcept<ChannelSubbyteRef>>();
  158. ChannelMutableRef b1(&min_bitbuf_, 1);
  159. b1 = gil::channel_traits<channel_t>::min_value();
  160. ChannelMutableRef b2(&max_bitbuf_, 2);
  161. b2 = gil::channel_traits<channel_t>::max_value();
  162. }
  163. };
  164. // Concrete fixture for 16-bit pack of 5,6,5-bit channels
  165. template <typename BitField>
  166. struct packed_channels565
  167. {
  168. static_assert(sizeof(BitField) >= sizeof(std::uint16_t), "16-bit or more required");
  169. using channel_0_5_t = gil::packed_channel_reference<BitField, 0, 5,true>;
  170. using channel_5_6_t = gil::packed_channel_reference<BitField, 5, 6,true>;
  171. using channel_11_5_t = gil::packed_channel_reference<BitField, 11, 5,true>;
  172. using fixture_0_5_t = fixture::packed_channel_reference<channel_0_5_t>;
  173. using fixture_5_6_t = fixture::packed_channel_reference<channel_5_6_t>;
  174. using fixture_11_5_t = fixture::packed_channel_reference<channel_11_5_t>;
  175. std::uint16_t data_ = 0;
  176. channel_0_5_t channel1_;
  177. channel_5_6_t channel2_;
  178. channel_11_5_t channel3_;
  179. packed_channels565() : channel1_(&data_), channel2_(&data_), channel3_(&data_)
  180. {
  181. channel1_ = gil::channel_traits<channel_0_5_t>::max_value();
  182. channel2_ = gil::channel_traits<channel_5_6_t>::max_value();
  183. channel3_ = gil::channel_traits<channel_11_5_t>::max_value();
  184. BOOST_TEST(data_ == 65535);
  185. }
  186. };
  187. // Concrete fixture for dynamically-referenced 16-bit pack of 5,6,5-bit channels
  188. template <typename BitField>
  189. struct packed_dynamic_channels565
  190. {
  191. static_assert(sizeof(BitField) >= sizeof(std::uint16_t), "16-bit or more required");
  192. using channel_5_t = gil::packed_dynamic_channel_reference<BitField,5,true>;
  193. using channel_6_t = gil::packed_dynamic_channel_reference<BitField,6,true>;
  194. using fixture_5_t = fixture::packed_dynamic_channel_reference<channel_5_t>;
  195. using fixture_6_t = fixture::packed_dynamic_channel_reference<channel_6_t>;
  196. std::uint16_t data_ = 0;
  197. channel_5_t channel1_;
  198. channel_6_t channel2_;
  199. channel_5_t channel3_;
  200. packed_dynamic_channels565()
  201. : channel1_(&data_, 0)
  202. , channel2_(&data_, 5)
  203. , channel3_(&data_, 11)
  204. {
  205. channel1_ = gil::channel_traits<channel_5_t>::max_value();
  206. channel2_ = gil::channel_traits<channel_6_t>::max_value();
  207. channel3_ = gil::channel_traits<channel_5_t>::max_value();
  208. BOOST_TEST(data_ == 65535);
  209. }
  210. };
  211. }}}} // namespace boost::gil::test::fixture
  212. #endif