planar_pixel_reference.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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/mpl/range_c.hpp>
  16. namespace boost { namespace gil {
  17. /// \defgroup ColorBaseModelPlanarRef planar_pixel_reference
  18. /// \ingroup ColorBaseModel
  19. /// \brief A homogeneous color base whose element is a channel reference. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept.
  20. /// This class is used as a reference proxy to a planar pixel.
  21. /// \defgroup PixelModelPlanarRef planar_pixel_reference
  22. /// \ingroup PixelModel
  23. /// \brief A reference proxy to a planar pixel. Models HomogeneousColorBaseConcept, HomogeneousPixelConcept.
  24. /// \ingroup PixelModelPlanarRef ColorBaseModelPlanarRef PixelBasedModel
  25. /// \brief A reference proxy to a planar pixel. Models: HomogeneousColorBaseConcept, HomogeneousPixelConcept
  26. ///
  27. /// A reference to a planar pixel is a proxy class containing references to each of the corresponding channels.
  28. ///
  29. template <typename ChannelReference, typename ColorSpace> // ChannelReference is a channel reference (const or mutable)
  30. struct planar_pixel_reference
  31. : public detail::homogeneous_color_base<ChannelReference,layout<ColorSpace>,mpl::size<ColorSpace>::value>
  32. {
  33. using parent_t = detail::homogeneous_color_base<ChannelReference,layout<ColorSpace>,mpl::size<ColorSpace>::value>;
  34. private:
  35. // These three are only defined for homogeneous pixels
  36. using channel_t = typename channel_traits<ChannelReference>::value_type;
  37. using channel_const_reference = typename channel_traits<ChannelReference>::const_reference;
  38. public:
  39. static constexpr bool is_mutable = channel_traits<ChannelReference>::is_mutable;
  40. using value_type = pixel<channel_t,layout<ColorSpace>>;
  41. using reference = planar_pixel_reference<ChannelReference, ColorSpace>;
  42. using const_reference = planar_pixel_reference<channel_const_reference,ColorSpace>;
  43. planar_pixel_reference(ChannelReference v0, ChannelReference v1) : parent_t(v0,v1) {}
  44. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2) : parent_t(v0,v1,v2) {}
  45. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3) : parent_t(v0,v1,v2,v3) {}
  46. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4) : parent_t(v0,v1,v2,v3,v4) {}
  47. planar_pixel_reference(ChannelReference v0, ChannelReference v1, ChannelReference v2, ChannelReference v3, ChannelReference v4, ChannelReference v5) : parent_t(v0,v1,v2,v3,v4,v5) {}
  48. template <typename P> planar_pixel_reference(const P& p) : parent_t(p) { check_compatible<P>();}
  49. // PERFORMANCE_CHECK: Is this constructor necessary?
  50. template <typename ChannelV, typename Mapping>
  51. planar_pixel_reference(pixel<ChannelV,layout<ColorSpace,Mapping> >& p) : parent_t(p) { check_compatible<pixel<ChannelV,layout<ColorSpace,Mapping> > >();}
  52. // Construct at offset from a given location
  53. template <typename ChannelPtr> planar_pixel_reference(const planar_pixel_iterator<ChannelPtr,ColorSpace>& p, std::ptrdiff_t diff) : parent_t(p,diff) {}
  54. const planar_pixel_reference& operator=(const planar_pixel_reference& p) const { static_copy(p,*this); return *this; }
  55. template <typename P> const planar_pixel_reference& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }
  56. // This overload is necessary for a compiler implementing Core Issue 574
  57. // to prevent generation of an implicit copy assignment operator (the reason
  58. // for generating implicit copy assignment operator is that according to
  59. // Core Issue 574, a cv-qualified assignment operator is not considered
  60. // "copy assignment operator").
  61. // EDG implemented Core Issue 574 starting with EDG Version 3.8. I'm not
  62. // sure why they did it for a template member function as well.
  63. #if BOOST_WORKAROUND(__HP_aCC, >= 61700) || BOOST_WORKAROUND(__INTEL_COMPILER, >= 1000)
  64. const planar_pixel_reference& operator=(const planar_pixel_reference& p) { static_copy(p,*this); return *this; }
  65. template <typename P> const planar_pixel_reference& operator=(const P& p) { check_compatible<P>(); static_copy(p,*this); return *this; }
  66. #endif
  67. template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
  68. template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
  69. ChannelReference operator[](std::size_t i) const { return this->at_c_dynamic(i); }
  70. const planar_pixel_reference* operator->() const { return this; }
  71. private:
  72. template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,planar_pixel_reference> >(); }
  73. };
  74. /////////////////////////////
  75. // ColorBasedConcept
  76. /////////////////////////////
  77. template <typename ChannelReference, typename ColorSpace, int K>
  78. struct kth_element_type<planar_pixel_reference<ChannelReference,ColorSpace>, K> {
  79. using type = ChannelReference;
  80. };
  81. template <typename ChannelReference, typename ColorSpace, int K>
  82. struct kth_element_reference_type<planar_pixel_reference<ChannelReference,ColorSpace>, K> {
  83. using type = ChannelReference;
  84. };
  85. template <typename ChannelReference, typename ColorSpace, int K>
  86. struct kth_element_const_reference_type<planar_pixel_reference<ChannelReference,ColorSpace>, K>
  87. : public add_reference<typename add_const<ChannelReference>::type>
  88. {
  89. // using type = typename channel_traits<ChannelReference>::const_reference;
  90. };
  91. /////////////////////////////
  92. // PixelConcept
  93. /////////////////////////////
  94. /// \brief Metafunction predicate that flags planar_pixel_reference as a model of PixelConcept. Required by PixelConcept
  95. /// \ingroup PixelModelPlanarRef
  96. template <typename ChannelReference, typename ColorSpace>
  97. struct is_pixel< planar_pixel_reference<ChannelReference,ColorSpace> > : public mpl::true_{};
  98. /////////////////////////////
  99. // HomogeneousPixelBasedConcept
  100. /////////////////////////////
  101. /// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
  102. /// \ingroup PixelModelPlanarRef
  103. template <typename ChannelReference, typename ColorSpace>
  104. struct color_space_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
  105. using type = ColorSpace;
  106. };
  107. /// \brief Specifies the color space type of a planar pixel reference. Required by PixelBasedConcept
  108. /// \ingroup PixelModelPlanarRef
  109. template <typename ChannelReference, typename ColorSpace>
  110. struct channel_mapping_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
  111. using type = typename layout<ColorSpace>::channel_mapping_t;
  112. };
  113. /// \brief Specifies that planar_pixel_reference represents a planar construct. Required by PixelBasedConcept
  114. /// \ingroup PixelModelPlanarRef
  115. template <typename ChannelReference, typename ColorSpace>
  116. struct is_planar<planar_pixel_reference<ChannelReference,ColorSpace> > : mpl::true_ {};
  117. /// \brief Specifies the color space type of a planar pixel reference. Required by HomogeneousPixelBasedConcept
  118. /// \ingroup PixelModelPlanarRef
  119. template <typename ChannelReference, typename ColorSpace>
  120. struct channel_type<planar_pixel_reference<ChannelReference,ColorSpace> > {
  121. using type = typename channel_traits<ChannelReference>::value_type;
  122. };
  123. }} // namespace boost::gil
  124. namespace std {
  125. // We are forced to define swap inside std namespace because on some platforms (Visual Studio 8) STL calls swap qualified.
  126. // swap with 'left bias':
  127. // - swap between proxy and anything
  128. // - swap between value type and proxy
  129. // - swap between proxy and proxy
  130. // Having three overloads allows us to swap between different (but compatible) models of PixelConcept
  131. /// \brief swap for planar_pixel_reference
  132. /// \ingroup PixelModelPlanarRef
  133. template <typename CR, typename CS, typename R> inline
  134. void swap(const boost::gil::planar_pixel_reference<CR,CS> x, R& y) {
  135. boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
  136. }
  137. /// \brief swap for planar_pixel_reference
  138. /// \ingroup PixelModelPlanarRef
  139. template <typename CR, typename CS> inline
  140. void swap(typename boost::gil::planar_pixel_reference<CR,CS>::value_type& x, const boost::gil::planar_pixel_reference<CR,CS> y) {
  141. boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
  142. }
  143. /// \brief swap for planar_pixel_reference
  144. /// \ingroup PixelModelPlanarRef
  145. template <typename CR, typename CS> inline
  146. void swap(const boost::gil::planar_pixel_reference<CR,CS> x, const boost::gil::planar_pixel_reference<CR,CS> y) {
  147. boost::gil::swap_proxy<typename boost::gil::planar_pixel_reference<CR,CS>::value_type>(x,y);
  148. }
  149. } // namespace std
  150. #endif