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