Boost GIL


color_base.hpp
Go to the documentation of this file.
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_COLOR_BASE_HPP
14 #define GIL_COLOR_BASE_HPP
15 
24 
25 #include <cassert>
26 
27 #include <boost/config.hpp>
28 #include <boost/mpl/range_c.hpp>
29 #include <boost/mpl/size.hpp>
30 #include <boost/mpl/vector_c.hpp>
31 #include <boost/type_traits.hpp>
32 #include <boost/utility/enable_if.hpp>
33 
34 #include "gil_config.hpp"
35 #include "utilities.hpp"
36 #include "gil_concept.hpp"
37 
38 namespace boost { namespace gil {
39 
40 // Forward-declare
41 template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
42 
43 // Forward-declare semantic_at_c
44 template <int K, typename ColorBase>
45 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
46 template <int K, typename ColorBase>
47 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
48 
49 // Forward declare element_reference_type
50 template <typename ColorBase> struct element_reference_type;
51 template <typename ColorBase> struct element_const_reference_type;
52 template <typename ColorBase, int K> struct kth_element_type;
53 template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
54 template <typename ColorBase, int K> struct kth_element_reference_type;
55 template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
56 template <typename ColorBase, int K> struct kth_element_const_reference_type;
57 template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
58 
59 namespace detail {
60 
61 template <typename DstLayout, typename SrcLayout, int K>
62 struct mapping_transform
63  : public mpl::at<typename SrcLayout::channel_mapping_t,
64  typename detail::type_to_index<typename DstLayout::channel_mapping_t,mpl::integral_c<int,K> >::type
65  >::type {};
66 
71 
72 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
73 #pragma warning(push)
74 #pragma warning(disable:4512) //assignment operator could not be generated
75 #endif
76 
79 template <typename Element, typename Layout>
80 struct homogeneous_color_base<Element,Layout,1> {
81 private:
82  Element _v0;
83 public:
84  typedef Layout layout_t;
85  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
86  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
87 
88  homogeneous_color_base() {}
89  homogeneous_color_base(Element v) : _v0(v) {}
90 
91  // grayscale pixel values are convertible to channel type
92  operator Element () const { return _v0; }
93 
94  template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,1>& c) : _v0(gil::at_c<0>(c)) {}
95 };
96 
97 
100 template <typename Element, typename Layout>
101 struct homogeneous_color_base<Element,Layout,2> {
102 private:
103  Element _v0, _v1;
104 public:
105  typedef Layout layout_t;
106  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
107  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
108  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
109  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
110 
111  homogeneous_color_base() {}
112  explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {}
113  homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {}
114 
115  template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,2>& c) :
116  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
117  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
118 
119  // Support for l-value reference proxy copy construction
120  template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,2>& c) :
121  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
122  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
123 
124  // Support for planar_pixel_iterator construction and dereferencing
125  template <typename P> homogeneous_color_base(P* p,bool) :
126  _v0(&semantic_at_c<0>(*p)),
127  _v1(&semantic_at_c<1>(*p)) {}
128  template <typename Ref> Ref deref() const {
129  return Ref(*semantic_at_c<0>(*this),
130  *semantic_at_c<1>(*this)); }
131 
132  // Support for planar_pixel_reference offset constructor
133  template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
134  : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
135  _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {}
136 
137  // Support for planar_pixel_reference operator[]
138  Element at_c_dynamic(std::size_t i) const {
139  if (i==0) return _v0;
140  return _v1;
141  }
142 };
143 
146 template <typename Element, typename Layout>
147 struct homogeneous_color_base<Element,Layout,3> {
148 private:
149  Element _v0, _v1, _v2;
150 public:
151  typedef Layout layout_t;
152  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
153  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
154  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
155  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
156  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
157  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
158 
159  homogeneous_color_base() {}
160  explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {}
161  homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {}
162 
163  template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,3>& c) :
164  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
165  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
166  _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
167 
168  // Support for l-value reference proxy copy construction
169  template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,3>& c) :
170  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
171  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
172  _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
173 
174  // Support for planar_pixel_iterator construction and dereferencing
175  template <typename P> homogeneous_color_base(P* p,bool) :
176  _v0(&semantic_at_c<0>(*p)),
177  _v1(&semantic_at_c<1>(*p)),
178  _v2(&semantic_at_c<2>(*p)) {}
179  template <typename Ref> Ref deref() const {
180  return Ref(*semantic_at_c<0>(*this),
181  *semantic_at_c<1>(*this),
182  *semantic_at_c<2>(*this)); }
183 
184  // Support for planar_pixel_reference offset constructor
185  template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
186  : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
187  _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
188  _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {}
189 
190  // Support for planar_pixel_reference operator[]
191  Element at_c_dynamic(std::size_t i) const {
192  switch (i) {
193  case 0: return _v0;
194  case 1: return _v1;
195  }
196  return _v2;
197  }
198 };
199 
202 template <typename Element, typename Layout>
203 struct homogeneous_color_base<Element,Layout,4> {
204 private:
205  Element _v0, _v1, _v2, _v3;
206 public:
207  typedef Layout layout_t;
208  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
209  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
210  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
211  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
212  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
213  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
214  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
215  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
216  homogeneous_color_base() {}
217  explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {}
218  homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {}
219 
220  template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,4>& c) :
221  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
222  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
223  _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
224  _v3(gil::at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
225 
226  // Support for l-value reference proxy copy construction
227  template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,4>& c) :
228  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
229  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
230  _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
231  _v3(gil::at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
232 
233  // Support for planar_pixel_iterator construction and dereferencing
234  template <typename P> homogeneous_color_base(P* p,bool) :
235  _v0(&semantic_at_c<0>(*p)),
236  _v1(&semantic_at_c<1>(*p)),
237  _v2(&semantic_at_c<2>(*p)),
238  _v3(&semantic_at_c<3>(*p)) {}
239 
240  template <typename Ref> Ref deref() const {
241  return Ref(*semantic_at_c<0>(*this),
242  *semantic_at_c<1>(*this),
243  *semantic_at_c<2>(*this),
244  *semantic_at_c<3>(*this)); }
245 
246  // Support for planar_pixel_reference offset constructor
247  template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
248  : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
249  _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
250  _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
251  _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {}
252 
253  // Support for planar_pixel_reference operator[]
254  Element at_c_dynamic(std::size_t i) const {
255  switch (i) {
256  case 0: return _v0;
257  case 1: return _v1;
258  case 2: return _v2;
259  }
260  return _v3;
261  }
262 };
263 
266 template <typename Element, typename Layout>
267 struct homogeneous_color_base<Element,Layout,5> {
268 private:
269  Element _v0, _v1, _v2, _v3, _v4;
270 public:
271  typedef Layout layout_t;
272  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
273  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
274  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
275  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
276  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
277  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
278  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
279  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
280  typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) { return _v4; }
281  typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) const { return _v4; }
282  homogeneous_color_base() {}
283  explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {}
284  homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {}
285 
286  template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,5>& c) :
287  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
288  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
289  _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
290  _v3(gil::at_c<mapping_transform<Layout,L2,3>::value>(c)),
291  _v4(gil::at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
292 
293  // Support for l-value reference proxy copy construction
294  template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,5>& c) :
295  _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
296  _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
297  _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)),
298  _v3(gil::at_c<mapping_transform<Layout,L2,3>::value>(c)),
299  _v4(gil::at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
300 
301  // Support for planar_pixel_iterator construction and dereferencing
302  template <typename P> homogeneous_color_base(P* p,bool) :
303  _v0(&semantic_at_c<0>(*p)),
304  _v1(&semantic_at_c<1>(*p)),
305  _v2(&semantic_at_c<2>(*p)),
306  _v3(&semantic_at_c<3>(*p)),
307  _v4(&semantic_at_c<4>(*p)) {}
308 
309  template <typename Ref> Ref deref() const {
310  return Ref(*semantic_at_c<0>(*this),
311  *semantic_at_c<1>(*this),
312  *semantic_at_c<2>(*this),
313  *semantic_at_c<3>(*this),
314  *semantic_at_c<4>(*this)); }
315 
316  // Support for planar_pixel_reference offset constructor
317  template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
318  : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
319  _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
320  _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
321  _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)),
322  _v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {}
323 
324  // Support for planar_pixel_reference operator[]
325  Element at_c_dynamic(std::size_t i) const {
326  switch (i) {
327  case 0: return _v0;
328  case 1: return _v1;
329  case 2: return _v2;
330  case 3: return _v3;
331  }
332  return _v4;
333  }
334 };
335 
336 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
337 #pragma warning(pop)
338 #endif
339 
340 // The following way of casting adjacent channels (the contents of color_base) into an array appears to be unsafe
341 // -- there is no guarantee that the compiler won't add any padding between adjacent channels.
342 // Note, however, that GIL _must_ be compiled with compiler settings ensuring there is no padding in the color base structs.
343 // This is because the color base structs must model the interleaved organization in memory. In other words, the client may
344 // have existing RGB image in the form "RGBRGBRGB..." and we must be able to represent it with an array of RGB color bases (i.e. RGB pixels)
345 // with no padding. We have tested with char/int/float/double channels on gcc and VC and have so far discovered no problem.
346 // We have even tried using strange channels consisting of short + char (3 bytes). With the default 4-byte alignment on VC, the size
347 // of this channel is padded to 4 bytes, so an RGB pixel of it will be 4x3=12 bytes. The code below will still work properly.
348 // However, the client must nevertheless ensure that proper compiler settings are used for their compiler and their channel types.
349 
350 template <typename Element, typename Layout, int K>
352 dynamic_at_c(homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
353  assert(i<K);
354  return (gil_reinterpret_cast<Element*>(&cb))[i];
355 }
356 
357 template <typename Element, typename Layout, int K>
359 dynamic_at_c(const homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
360  assert(i<K);
361  return (gil_reinterpret_cast_c<const Element*>(&cb))[i];
362 }
363 
364 template <typename Element, typename Layout, int K>
365 typename element_reference_type<homogeneous_color_base<Element&,Layout,K> >::type
366 dynamic_at_c(const homogeneous_color_base<Element&,Layout,K>& cb, std::size_t i) {
367  assert(i<K);
368  return cb.at_c_dynamic(i);
369 }
370 
371 template <typename Element, typename Layout, int K>
372 typename element_const_reference_type<homogeneous_color_base<const Element&,Layout,K> >::type
373 dynamic_at_c(const homogeneous_color_base<const Element&,Layout,K>& cb, std::size_t i) {
374  assert(i<K);
375  return cb.at_c_dynamic(i);
376 }
377 
378 
379 } // namespace detail
380 
381 template <typename Element, typename Layout, int K1, int K>
382 struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
383  typedef Element type;
384 };
385 
386 template <typename Element, typename Layout, int K1, int K>
387 struct kth_element_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<Element> {};
388 
389 template <typename Element, typename Layout, int K1, int K>
390 struct kth_element_const_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<typename add_const<Element>::type> {};
391 
394 template <int K, typename E, typename L, int N> inline
395 typename add_reference<E>::type
396 at_c( detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
397 
400 template <int K, typename E, typename L, int N> inline
401 typename add_reference<typename add_const<E>::type>::type
402 at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
403 
404 namespace detail {
405  struct swap_fn {
406  template <typename T> void operator()(T& x, T& y) const {
407  using std::swap;
408  swap(x,y);
409  }
410  };
411 }
412 template <typename E, typename L, int N> inline
413 void swap(detail::homogeneous_color_base<E,L,N>& x, detail::homogeneous_color_base<E,L,N>& y) {
414  static_for_each(x,y,detail::swap_fn());
415 }
416 
417 
418 } } // namespace boost::gil
419 
420 #endif
kth_semantic_element_const_reference_type< ColorBase, K >::type semantic_at_c(const ColorBase &p)
A constant accessor to the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:130
Concept check classes for GIL concepts.
Specifies the return type of the constant element accessor at_c of a homogeneous color base...
Definition: color_base.hpp:51
add_reference< typename add_const< E >::type >::type at_c(const detail::homogeneous_color_base< E, L, N > &p)
Provides constant access to the K-th element, in physical order.
Definition: color_base.hpp:402
Specifies the return type of the mutable element accessor at_c of a homogeneous color base...
Definition: color_base.hpp:50
GIL configuration file.
Various utilities not specific to the image library. Some are non-standard STL extensions or generic ...