packed_pixel.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. //
  2. // Copyright 2019 Mateusz Loskot <mateusz at loskot dot net>
  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. #include <boost/gil/channel.hpp>
  9. #include <boost/gil/packed_pixel.hpp>
  10. #include <boost/gil/gray.hpp>
  11. #include <boost/gil/rgb.hpp>
  12. #include <boost/core/typeinfo.hpp>
  13. #include <boost/mp11.hpp>
  14. #define BOOST_TEST_MODULE test_channel_traits
  15. #include "unit_test.hpp"
  16. namespace gil = boost::gil;
  17. namespace mp11 = boost::mp11;
  18. namespace boost { namespace gil {
  19. template <typename BitField, typename ChannelRefs, typename Layout>
  20. std::ostream& operator<<(std::ostream& os, gil::packed_pixel<BitField, ChannelRefs, Layout> const& p)
  21. {
  22. os << "packed_pixel<"
  23. << "BitField=" << boost::core::demangled_name(typeid(BitField))
  24. << ", ChannelRefs=" << boost::core::demangled_name(typeid(ChannelRefs))
  25. << ", Layout=" << boost::core::demangled_name(typeid(Layout))
  26. << ">(" << (std::uint64_t)p._bitfield << ")";
  27. return os;
  28. }
  29. }} // namespace boost::gil
  30. using packed_channel_references_3 = typename gil::detail::packed_channel_references_vector_type
  31. <
  32. std::uint8_t,
  33. mp11::mp_list_c<int, 3>
  34. >::type;
  35. using packed_pixel_gray3 = gil::packed_pixel
  36. <
  37. std::uint8_t,
  38. packed_channel_references_3,
  39. gil::gray_layout_t
  40. >;
  41. BOOST_AUTO_TEST_CASE(packed_pixel_gray3_definition)
  42. {
  43. // Verify packed_pixel members
  44. static_assert(std::is_same<packed_pixel_gray3::layout_t, gil::gray_layout_t>::value,
  45. "layout should be bgr");
  46. static_assert(std::is_same<packed_pixel_gray3::value_type, packed_pixel_gray3>::value,
  47. "value_type member should be of the same type as the packed_pixel specialization");
  48. static_assert(std::is_reference<packed_pixel_gray3::reference>::value,
  49. "reference member should be a reference");
  50. static_assert(std::is_reference<packed_pixel_gray3::const_reference>::value,
  51. "const_reference member should be a reference");
  52. static_assert(std::is_same<decltype(packed_pixel_gray3::is_mutable), bool const>::value &&
  53. packed_pixel_gray3::is_mutable,
  54. "is_mutable should be boolean");
  55. // Verify metafunctions
  56. static_assert(mp11::mp_size<packed_channel_references_3>::value == 1,
  57. "packed_channel_references_vector_type should define one reference to channel start bits");
  58. using channel1_ref_t = mp11::mp_at_c<packed_channel_references_3, 0>;
  59. static_assert(channel1_ref_t::num_bits == 3,
  60. "1st channel of gray3 pixel should be of 3-bit size");
  61. static_assert(std::is_same
  62. <
  63. channel1_ref_t,
  64. gil::packed_channel_reference<std::uint8_t, 0, 3, true> const
  65. >::value,
  66. "1st element of packed_channel_references_vector should be packed_channel_reference of 1st channel");
  67. // double check intermediate metafunction packed_channel_reference_type
  68. static_assert(std::is_same
  69. <
  70. gil::detail::packed_channel_reference_type
  71. <
  72. std::uint8_t,
  73. std::integral_constant<int, 0>,
  74. std::integral_constant<int, 3>
  75. >::type,
  76. channel1_ref_t
  77. >::value,
  78. "packed_channel_reference_type should return packed_channel_reference");
  79. static_assert(std::is_same
  80. <
  81. gil::detail::packed_channel_reference_type
  82. <
  83. std::uint8_t,
  84. std::integral_constant<int, 0>,
  85. std::integral_constant<int, 3>
  86. >::type,
  87. gil::packed_channel_reference<std::uint8_t, 0, 3, true> const
  88. >::value,
  89. "packed_channel_reference_type should return packed_channel_reference");
  90. }
  91. BOOST_AUTO_TEST_CASE(packed_pixel_gray3_assignment)
  92. {
  93. packed_pixel_gray3 p1{int{5}};
  94. packed_pixel_gray3 p2;
  95. p2 = p1;
  96. BOOST_TEST(p1._bitfield == p2._bitfield);
  97. }
  98. BOOST_AUTO_TEST_CASE(packed_pixel_gray_equality)
  99. {
  100. packed_pixel_gray3 p1{int{5}};
  101. packed_pixel_gray3 p2{int{5}};
  102. BOOST_TEST(p1 == p2);
  103. packed_pixel_gray3 p3{int{3}};
  104. BOOST_TEST(p2 != p3);
  105. }
  106. BOOST_AUTO_TEST_CASE(packed_pixel_gray3_assignment_gray_channel)
  107. {
  108. {
  109. packed_pixel_gray3 p1; // default-initialized
  110. p1 = int{5};
  111. BOOST_TEST(p1._bitfield == int{5});
  112. }
  113. {
  114. packed_pixel_gray3 p1{0}; // value-initialized
  115. p1 = int{5};
  116. BOOST_TEST(p1._bitfield == int{5});
  117. }
  118. }
  119. BOOST_AUTO_TEST_CASE(packed_pixel_gray_equality_gray_channel)
  120. {
  121. packed_pixel_gray3 p1{int{3}};
  122. BOOST_TEST(p1 == int{3});
  123. }
  124. using packed_channel_references_121 = typename gil::detail::packed_channel_references_vector_type
  125. <
  126. std::uint8_t,
  127. mp11::mp_list_c<int, 1, 2, 1>
  128. >::type;
  129. using packed_pixel_bgr121 = gil::packed_pixel
  130. <
  131. std::uint8_t,
  132. packed_channel_references_121,
  133. gil::bgr_layout_t
  134. >;
  135. BOOST_AUTO_TEST_CASE(packed_pixel_bgr121_definition)
  136. {
  137. // Verify packed_pixel members
  138. static_assert(std::is_same<packed_pixel_bgr121::layout_t, gil::bgr_layout_t>::value,
  139. "layout should be bgr");
  140. static_assert(std::is_same<packed_pixel_bgr121::value_type, packed_pixel_bgr121>::value,
  141. "value_type member should be of the same type as the packed_pixel specialization");
  142. static_assert(std::is_reference<packed_pixel_bgr121::reference>::value,
  143. "reference member should be a reference");
  144. static_assert(std::is_reference<packed_pixel_bgr121::const_reference>::value,
  145. "const_reference member should be a reference");
  146. static_assert(std::is_same<decltype(packed_pixel_bgr121::is_mutable), bool const>::value &&
  147. packed_pixel_bgr121::is_mutable,
  148. "is_mutable should be boolean");
  149. // Verify metafunctions
  150. static_assert(mp11::mp_size<packed_channel_references_121>::value == 3,
  151. "packed_channel_references_vector_type should define three references to channel start bits");
  152. using channel1_ref_t = mp11::mp_at_c<packed_channel_references_121, 0>;
  153. static_assert(channel1_ref_t::num_bits == 1,
  154. "1st channel of bgr121 pixel should be of 1-bit size");
  155. using channel2_ref_t = mp11::mp_at_c<packed_channel_references_121, 1>;
  156. static_assert(channel2_ref_t::num_bits == 2,
  157. "2nd channel of bgr121 pixel should be of 2-bit size");
  158. using channel3_ref_t = mp11::mp_at_c<packed_channel_references_121, 2>;
  159. static_assert(channel3_ref_t::num_bits == 1,
  160. "3rd channel of bgr121 pixel should be of 1-bit size");
  161. static_assert(std::is_same
  162. <
  163. channel1_ref_t,
  164. gil::packed_channel_reference<std::uint8_t, 0, 1, true> const
  165. >::value,
  166. "1st element of packed_channel_references_vector should be packed_channel_reference of 1st channel");
  167. static_assert(std::is_same
  168. <
  169. channel2_ref_t,
  170. gil::packed_channel_reference<std::uint8_t, 1, 2, true> const
  171. >::value,
  172. "2nd element of packed_channel_references_vector should be packed_channel_reference of 2nd channel");
  173. static_assert(std::is_same
  174. <
  175. channel3_ref_t,
  176. gil::packed_channel_reference<std::uint8_t, 3, 1, true> const
  177. >::value,
  178. "3rd element of packed_channel_references_vector should be packed_channel_reference of 3rd channel");
  179. // double check intermediate metafunction packed_channel_reference_type
  180. static_assert(std::is_same
  181. <
  182. gil::detail::packed_channel_reference_type
  183. <
  184. std::uint8_t, mp11::mp_int<0>, mp11::mp_int<1>
  185. >::type,
  186. channel1_ref_t
  187. >::value,
  188. "packed_channel_reference_type should return packed_channel_reference");
  189. static_assert(std::is_same
  190. <
  191. gil::detail::packed_channel_reference_type
  192. <
  193. std::uint8_t, mp11::mp_int<0>, mp11::mp_int<1>
  194. >::type,
  195. gil::packed_channel_reference<std::uint8_t, 0, 1, true> const
  196. >::value,
  197. "packed_channel_reference_type should return packed_channel_reference");
  198. }
  199. BOOST_AUTO_TEST_CASE(packed_pixel_bgr121_assignment)
  200. {
  201. packed_pixel_bgr121 p1{0, 3, 1};
  202. packed_pixel_bgr121 p2;
  203. p2 = p1;
  204. BOOST_TEST(p1._bitfield == p2._bitfield);
  205. }
  206. BOOST_AUTO_TEST_CASE(packed_pixel_bgr121_equality)
  207. {
  208. packed_pixel_bgr121 p1{1, 3, 0};
  209. packed_pixel_bgr121 p2{1, 3, 0};
  210. BOOST_TEST(p1 == p2);
  211. packed_pixel_bgr121 p3{0, 3, 1};
  212. BOOST_TEST(p2 != p3);
  213. }
  214. using packed_channel_references_535 = typename gil::detail::packed_channel_references_vector_type
  215. <
  216. std::uint16_t,
  217. mp11::mp_list_c<int, 5, 3, 5>
  218. >::type;
  219. using packed_pixel_rgb535 = gil::packed_pixel
  220. <
  221. std::uint16_t,
  222. packed_channel_references_535,
  223. gil::rgb_layout_t
  224. >;
  225. BOOST_AUTO_TEST_CASE(packed_pixel_rgb535_definition)
  226. {
  227. // Verify packed_pixel members
  228. static_assert(std::is_same<packed_pixel_rgb535::layout_t, gil::rgb_layout_t>::value,
  229. "layout should be bgr");
  230. static_assert(std::is_same<packed_pixel_rgb535::value_type, packed_pixel_rgb535>::value,
  231. "value_type member should be of the same type as the packed_pixel specialization");
  232. static_assert(std::is_reference<packed_pixel_rgb535::reference>::value,
  233. "reference member should be a reference");
  234. static_assert(std::is_reference<packed_pixel_rgb535::const_reference>::value,
  235. "const_reference member should be a reference");
  236. static_assert(std::is_same<decltype(packed_pixel_rgb535::is_mutable), bool const>::value &&
  237. packed_pixel_rgb535::is_mutable,
  238. "is_mutable should be boolean");
  239. // Verify metafunctions
  240. static_assert(mp11::mp_size<packed_channel_references_535>::value == 3,
  241. "packed_channel_references_vector_type should define three references to channel start bits");
  242. using channel1_ref_t = mp11::mp_at_c<packed_channel_references_535, 0>;
  243. static_assert(channel1_ref_t::num_bits == 5,
  244. "1st channel of rgb535 pixel should be of 5-bit size");
  245. using channel2_ref_t = mp11::mp_at_c<packed_channel_references_535, 1>;
  246. static_assert(channel2_ref_t::num_bits == 3,
  247. "2nd channel of rgb535 pixel should be of 3-bit size");
  248. using channel3_ref_t = mp11::mp_at_c<packed_channel_references_535, 2>;
  249. static_assert(channel3_ref_t::num_bits == 5,
  250. "3rd channel of rgb535 pixel should be of 5-bit size");
  251. static_assert(std::is_same
  252. <
  253. channel1_ref_t,
  254. gil::packed_channel_reference<std::uint16_t, 0, 5, true> const
  255. >::value,
  256. "1st element of packed_channel_references_vector should be packed_channel_reference of 1st channel");
  257. static_assert(std::is_same
  258. <
  259. channel2_ref_t,
  260. gil::packed_channel_reference<std::uint16_t, 5, 3, true> const
  261. >::value,
  262. "2nd element of packed_channel_references_vector should be packed_channel_reference of 2nd channel");
  263. static_assert(std::is_same
  264. <
  265. channel3_ref_t,
  266. gil::packed_channel_reference<std::uint16_t, 8, 5, true> const
  267. >::value,
  268. "3rd element of packed_channel_references_vector should be packed_channel_reference of 3rd channel");
  269. // double check intermediate metafunction packed_channel_reference_type
  270. static_assert(std::is_same
  271. <
  272. gil::detail::packed_channel_reference_type
  273. <
  274. std::uint16_t,
  275. std::integral_constant<int, 0>,
  276. std::integral_constant<int, 5>
  277. >::type,
  278. channel1_ref_t
  279. >::value,
  280. "packed_channel_reference_type should return packed_channel_reference");
  281. static_assert(std::is_same
  282. <
  283. gil::detail::packed_channel_reference_type
  284. <
  285. std::uint16_t,
  286. std::integral_constant<int, 0>,
  287. std::integral_constant<int, 5>
  288. >::type,
  289. gil::packed_channel_reference<std::uint16_t, 0, 5, true> const
  290. >::value,
  291. "packed_channel_reference_type should return packed_channel_reference");
  292. }
  293. BOOST_AUTO_TEST_CASE(packed_pixel_rgb535_assignment)
  294. {
  295. packed_pixel_rgb535 p1{31, 7, 31};
  296. packed_pixel_rgb535 p2;
  297. p2 = p1;
  298. BOOST_TEST(p1._bitfield == p2._bitfield);
  299. }
  300. BOOST_AUTO_TEST_CASE(packed_pixel_rgb535_equality)
  301. {
  302. packed_pixel_rgb535 p1{7, 3, 7};
  303. packed_pixel_rgb535 p2{7, 3, 7};
  304. BOOST_TEST(p1 == p2);
  305. packed_pixel_rgb535 p3{7, 7, 7};
  306. BOOST_TEST(p2 != p3);
  307. }