]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |