planar_pixel_reference.hpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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_PLANAR_PIXEL_REFERENCE_HPP
  9. #define BOOST_GIL_PLANAR_PIXEL_REFERENCE_HPP
  10. #include <boost/gil/channel.hpp>
  11. #include <boost/gil/color_base.hpp>
  12. #include <boost/gil/concepts.hpp>
  13. #include <boost/gil/pixel.hpp>
  14. #include <boost/gil/planar_pixel_iterator.hpp>
  15. #include <boost/gil/detail/mp11.hpp>
  16. #include <type_traits>
  17. namespace boost { namespace gil {
  18. /// \defgroup ColorBaseModelPlanarRef planar_pixel_reference
  19. /// \ingroup ColorBaseModel
  20. /// \brief A homogeneous color base whose element is a channel reference. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept.
  21. /// This class is used as a reference proxy to a planar pixel.
  22. /// \defgroup PixelModelPlanarRef planar_pixel_reference
  23. /// \ingroup PixelModel
  24. /// \brief A reference proxy to a planar pixel. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept.
  25. /// \ingroup PixelModelPlanarRef ColorBaseModelPlanarRef PixelBasedModel
  26. /// \brief A reference proxy to a planar pixel.
  27. ///
  28. /// A reference to a planar pixel is a proxy class containing references to each of the corresponding channels.
  29. /// Models: HomogeneousColorBaseConcept, HomogeneousPixelConcept
  30. ///
  31. /// \tparam ChannelReference A channel reference, either const or mutable
  32. /// \tparam ColorSpace
  33. template <typename ChannelReference, typename ColorSpace>
  34. struct planar_pixel_reference : detail::homogeneous_color_base
  35. <
  36. ChannelReference,
  37. layout<ColorSpace>,
  38. mp11::mp_size<ColorSpace>::value
  39. >
  40. {
  41. using parent_t =detail::homogeneous_color_base
  42. <
  43. ChannelReference,
  44. layout<ColorSpace>,
  45. mp11::mp_size<ColorSpace>::value
  46. >;
  47. private:
  48. // These three are only defined for homogeneous pixels
  49. using channel_t = typename channel_traits<ChannelReference>::value_type;
  50. using channel_const_reference = typename channel_traits<ChannelReference>::const_reference;
  51. public:
  52. static constexpr bool is_mutable = channel_traits<ChannelReference>::is_mutable;
  53. using value_type = pixel<channel_t,layout<ColorSpace>>;
  54. using reference = planar_pixel_reference<ChannelReference, ColorSpace>;
  55. using const_reference = planar_pixel_reference<channel_const_reference,ColorSpace>;
  56. planar_pixel_reference(ChannelReference v0, ChannelReference v1)
  57. : parent_t(v0, v1)
  58. {}
  59. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2)
  60. : parent_t(v0, v1, v2)
  61. {}
  62. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3)
  63. : parent_t(v0, v1, v2, v3)
  64. {}
  65. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4)
  66. : parent_t(v0, v1, v2, v3, v4)
  67. {}
  68. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4, ChannelReference v5)
  69. : parent_t(v0, v1, v2, v3, v4, v5)
  70. {}
  71. planar_pixel_reference(planar_pixel_reference const& p) : parent_t(p) {}
  72. // TODO: What is the purpose of returning via const reference?
  73. auto operator=(planar_pixel_reference const& p) const -> planar_pixel_reference const&
  74. {
  75. static_copy(p, *this);
  76. return *this;
  77. }
  78. template <typename Pixel>
  79. planar_pixel_reference(Pixel const& p) : parent_t(p)
  80. {
  81. check_compatible<Pixel>();
  82. }
  83. // TODO: What is the purpose of returning via const reference?
  84. template <typename Pixel>
  85. auto operator=(Pixel const& p) const -> planar_pixel_reference const&
  86. {
  87. check_compatible<Pixel>();
  88. static_copy(p, *this);
  89. return *this;
  90. }
  91. // PERFORMANCE_CHECK: Is this constructor necessary?
  92. template <typename ChannelV, typename Mapping>
  93. planar_pixel_reference(pixel<ChannelV, layout<ColorSpace, Mapping>>& p)
  94. : parent_t(p)
  95. {
  96. check_compatible<pixel<ChannelV, layout<ColorSpace, Mapping>>>();
  97. }
  98. // Construct at offset from a given location
  99. template <typename ChannelPtr>
  100. planar_pixel_reference(planar_pixel_iterator<ChannelPtr, ColorSpace> const& p, std::ptrdiff_t diff)
  101. : parent_t(p, diff)
  102. {}
  103. // This overload is necessary for a compiler implementing Core Issue 574
  104. // to prevent generation of an implicit copy assignment operator (the reason
  105. // for generating implicit copy assignment operator is that according to
  106. // Core Issue 574, a cv-qualified assignment operator is not considered
  107. // "copy assignment operator").
  108. // EDG implemented Core Issue 574 starting with EDG Version 3.8. I'm not
  109. // sure why they did it for a template member function as well.
  110. #if BOOST_WORKAROUND(__HP_aCC, >= 61700) || BOOST_WORKAROUND(__INTEL_COMPILER, >= 1000)
  111. const planar_pixel_reference& operator=(const planar_pixel_reference& p) { static_copy(p,*this); return *this; }
  112. template <typename P> const planar_pixel_reference& operator=(const P& p) { check_compatible<P>(); static_copy(p,*this); return *this; }
  113. #endif
  114. template <typename Pixel>
  115. bool operator==(Pixel const& p) const
  116. {
  117. check_compatible<Pixel>();
  118. return static_equal(*this, p);
  119. }
  120. template <typename Pixel>
  121. bool operator!=(Pixel const &p) const { return !(*this == p); }
  122. auto operator[](std::size_t i) const -> ChannelReference { return this->at_c_dynamic(i); }
  123. auto operator->() const -> planar_pixel_reference const* { return this; }
  124. private:
  125. template <typename Pixel>
  126. static void check_compatible()
  127. {
  128. gil_function_requires<PixelsCompatibleConcept<Pixel, planar_pixel_reference>>();
  129. }
  130. };
  131. /////////////////////////////
  132. // ColorBasedConcept
  133. /////////////////////////////
  134. template <typename ChannelReference, typename ColorSpace, int K>
  135. struct kth_element_type<planar_pixel_reference<ChannelReference, ColorSpace>, K>
  136. {
  137. using type = ChannelReference;
  138. };
  139. template <typename ChannelReference, typename ColorSpace, int K>
  140. struct kth_element_reference_type
  141. <
  142. planar_pixel_reference<ChannelReference, ColorSpace>,
  143. K
  144. >
  145. {
  146. using type = ChannelReference;
  147. };
  148. template <typename ChannelReference, typename ColorSpace, int K>
  149. struct kth_element_const_reference_type
  150. <
  151. planar_pixel_reference<ChannelReference, ColorSpace>,
  152. K
  153. >
  154. : std::add_lvalue_reference<typename std::add_const<ChannelReference>::type>
  155. {
  156. // using type = typename channel_traits<ChannelReference>::const_reference;
  157. };
  158. /////////////////////////////
  159. // PixelConcept
  160. /////////////////////////////
  161. /// \brief Metafunction predicate that flags planar_pixel_reference as a model of PixelConcept. Required by PixelConcept
  162. /// \ingroup PixelModelPlanarRef
  163. template <typename ChannelReference, typename ColorSpace>
  164. struct is_pixel< planar_pixel_reference<ChannelReference, ColorSpace>>
  165. : std::true_type
  166. {};
  167. /////////////////////////////
  168. // HomogeneousPixelBasedConcept
  169. /////////////////////////////
  170. /// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
  171. /// \ingroup PixelModelPlanarRef
  172. template <typename ChannelReference, typename ColorSpace>
  173. struct color_space_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
  174. using type = ColorSpace;
  175. };
  176. /// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
  177. /// \ingroup PixelModelPlanarRef
  178. template <typename ChannelReference, typename ColorSpace>
  179. struct channel_mapping_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
  180. using type = typename layout<ColorSpace>::channel_mapping_t;
  181. };
  182. /// \brief Specifies that planar_pixel_reference represents a planar construct. Required by PixelBasedConcept
  183. /// \ingroup PixelModelPlanarRef
  184. template <typename ChannelReference, typename ColorSpace>
  185. struct is_planar<planar_pixel_reference<ChannelReference, ColorSpace>>
  186. : std::true_type
  187. {};
  188. /// \brief Specifies the color space type of a planar pixel reference. Required by HomogeneousPixelBasedConcept
  189. /// \ingroup PixelModelPlanarRef
  190. template <typename ChannelReference, typename ColorSpace>
  191. struct channel_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
  192. using type = typename channel_traits<ChannelReference>::value_type;
  193. };
  194. }} // namespace boost::gil
  195. namespace std {
  196. // We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
  197. // swap with 'left bias':
  198. // - swap between proxy and anything
  199. // - swap between value type and proxy
  200. // - swap between proxy and proxy
  201. // Having three overloads allows us to swap between different (but compatible) models of PixelConcept
  202. /// \brief swap for planar_pixel_reference
  203. /// \ingroup PixelModelPlanarRef
  204. template <typename CR, typename CS, typename R> inline
  205. void swap(const boost::gil::planar_pixel_reference<CR,CS> x, R& y) {
  206. boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
  207. }
  208. /// \brief swap for planar_pixel_reference
  209. /// \ingroup PixelModelPlanarRef
  210. template <typename CR, typename CS> inline
  211. void swap(typename boost::gil::planar_pixel_reference<CR,CS>::value_type& x, const boost::gil::planar_pixel_reference<CR,CS> y) {
  212. boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
  213. }
  214. /// \brief swap for planar_pixel_reference
  215. /// \ingroup PixelModelPlanarRef
  216. template <typename CR, typename CS> inline
  217. void swap(const boost::gil::planar_pixel_reference<CR,CS> x, const boost::gil::planar_pixel_reference<CR,CS> y) {
  218. boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
  219. }
  220. } // namespace std
  221. #endif