planar_pixel_reference.hpp 9.7 KB

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