color_base.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003    
00004     Use, modification and distribution are subject to the Boost Software License,
00005     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00006     http://www.boost.org/LICENSE_1_0.txt).
00007 
00008     See http://opensource.adobe.com/gil for most recent version including documentation.
00009 */
00010 
00011 /*************************************************************************************************/
00012 
00013 #ifndef GIL_COLOR_BASE_HPP
00014 #define GIL_COLOR_BASE_HPP
00015 
00024 
00025 #include <cassert>
00026 #include <boost/mpl/range_c.hpp>
00027 #include <boost/mpl/size.hpp>
00028 #include <boost/mpl/vector_c.hpp>
00029 #include <boost/type_traits.hpp>
00030 #include <boost/utility/enable_if.hpp>
00031 
00032 #include "gil_config.hpp"
00033 #include "utilities.hpp"
00034 #include "gil_concept.hpp"
00035 
00036 namespace boost { namespace gil {
00037 
00038 // Forward-declare semantic_at_c
00039 template <int K, typename ColorBase>
00040 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
00041 template <int K, typename ColorBase>
00042 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
00043 
00044 // Forward declare element_reference_type
00045 template <typename ColorBase> struct element_reference_type;
00046 template <typename ColorBase> struct element_const_reference_type;
00047 template <typename ColorBase, int K> struct kth_element_type;
00048 template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
00049 template <typename ColorBase, int K> struct kth_element_reference_type;
00050 template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
00051 template <typename ColorBase, int K> struct kth_element_const_reference_type;
00052 template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
00053 
00054 namespace detail {
00055 
00056 template <typename DstLayout, typename SrcLayout, int K>
00057 struct mapping_transform 
00058     : public mpl::at<typename SrcLayout::channel_mapping_t, 
00059                      typename detail::type_to_index<typename DstLayout::channel_mapping_t,mpl::integral_c<int,K> >::type
00060                            >::type {};
00061 
00066 
00067 
00070 template <typename Element, typename Layout>
00071 struct homogeneous_color_base<Element,Layout,1> {
00072 private:
00073     Element _v0;
00074 public:
00075     typedef Layout layout_t;
00076     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
00077     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00078 
00079     homogeneous_color_base() {}
00080     homogeneous_color_base(Element v) : _v0(v) {}
00081  
00082     // grayscale pixel values are convertible to channel type
00083     operator Element () const { return _v0; }
00084 
00085     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,1>& c) : _v0(at_c<0>(c)) {}
00086 };
00087 
00088 
00091 template <typename Element, typename Layout>
00092 struct homogeneous_color_base<Element,Layout,2> {
00093 private:
00094     Element _v0, _v1;
00095 public:
00096     typedef Layout layout_t;
00097     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
00098     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00099     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
00100     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00101 
00102     homogeneous_color_base() {}
00103     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {}
00104     homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {}
00105 
00106     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,2>& c) : 
00107         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00108         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
00109 
00110     // Support for l-value reference proxy copy construction
00111     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,2>& c) : 
00112         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00113         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
00114 
00115     // Support for planar_pixel_iterator construction and dereferencing
00116     template <typename P> homogeneous_color_base(P* p,bool) : 
00117         _v0(&semantic_at_c<0>(*p)), 
00118         _v1(&semantic_at_c<1>(*p)) {}
00119     template <typename Ref> Ref deref() const { 
00120         return Ref(*semantic_at_c<0>(*this), 
00121                    *semantic_at_c<1>(*this)); }
00122 
00123     // Support for planar_pixel_reference offset constructor
00124     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) 
00125         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00126           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {}
00127 
00128     // Support for planar_pixel_reference operator[]
00129     Element at_c_dynamic(size_t i) const {
00130         if (i==0) return _v0;
00131         return _v1;
00132     }
00133 };
00134 
00137 template <typename Element, typename Layout>
00138 struct homogeneous_color_base<Element,Layout,3> {
00139 private:
00140     Element _v0, _v1, _v2;
00141 public:
00142     typedef Layout layout_t;
00143     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
00144     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00145     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
00146     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00147     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<2>)       { return _v2; }
00148     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00149 
00150     homogeneous_color_base() {}
00151     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {}
00152     homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {}
00153 
00154     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,3>& c) : 
00155         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00156         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)), 
00157         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
00158 
00159     // Support for l-value reference proxy copy construction
00160     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,3>& c) : 
00161         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00162         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)), 
00163         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
00164 
00165     // Support for planar_pixel_iterator construction and dereferencing
00166     template <typename P> homogeneous_color_base(P* p,bool) : 
00167         _v0(&semantic_at_c<0>(*p)), 
00168         _v1(&semantic_at_c<1>(*p)), 
00169         _v2(&semantic_at_c<2>(*p)) {}
00170     template <typename Ref> Ref deref() const { 
00171         return Ref(*semantic_at_c<0>(*this), 
00172                    *semantic_at_c<1>(*this), 
00173                    *semantic_at_c<2>(*this)); }
00174 
00175     // Support for planar_pixel_reference offset constructor
00176     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) 
00177         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00178           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
00179           _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {}
00180 
00181     // Support for planar_pixel_reference operator[]
00182     Element at_c_dynamic(size_t i) const {
00183         switch (i) {
00184             case 0: return _v0;
00185             case 1: return _v1;
00186         }
00187         return _v2;
00188     }
00189 };
00190 
00193 template <typename Element, typename Layout>
00194 struct homogeneous_color_base<Element,Layout,4> {
00195 private:
00196     Element _v0, _v1, _v2, _v3;
00197 public:
00198     typedef Layout layout_t;
00199     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
00200     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00201     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
00202     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00203     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<2>)       { return _v2; }
00204     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00205     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<3>)       { return _v3; }
00206     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
00207     homogeneous_color_base() {}
00208     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {}
00209     homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {}
00210 
00211     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,4>& c) :
00212         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00213         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)), 
00214         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00215         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
00216 
00217     // Support for l-value reference proxy copy construction
00218     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,4>& c) : 
00219         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00220         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)), 
00221         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00222         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
00223 
00224     // Support for planar_pixel_iterator construction and dereferencing
00225     template <typename P> homogeneous_color_base(P* p,bool) : 
00226         _v0(&semantic_at_c<0>(*p)), 
00227         _v1(&semantic_at_c<1>(*p)), 
00228         _v2(&semantic_at_c<2>(*p)), 
00229         _v3(&semantic_at_c<3>(*p)) {}
00230 
00231     template <typename Ref> Ref deref() const { 
00232         return Ref(*semantic_at_c<0>(*this), 
00233                    *semantic_at_c<1>(*this), 
00234                    *semantic_at_c<2>(*this), 
00235                    *semantic_at_c<3>(*this)); }
00236 
00237     // Support for planar_pixel_reference offset constructor
00238     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) 
00239         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00240           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
00241           _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
00242           _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {}
00243 
00244     // Support for planar_pixel_reference operator[]
00245     Element at_c_dynamic(size_t i) const {
00246         switch (i) {
00247             case 0: return _v0;
00248             case 1: return _v1;
00249             case 2: return _v2;
00250         }
00251         return _v3;
00252     }
00253 };
00254 
00257 template <typename Element, typename Layout>
00258 struct homogeneous_color_base<Element,Layout,5> {
00259 private:
00260     Element _v0, _v1, _v2, _v3, _v4;
00261 public:
00262     typedef Layout layout_t;
00263     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
00264     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00265     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
00266     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00267     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<2>)       { return _v2; }
00268     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00269     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<3>)       { return _v3; }
00270     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
00271     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<4>)       { return _v4; }
00272     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) const { return _v4; }
00273     homogeneous_color_base() {}
00274     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {}
00275     homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {}
00276 
00277     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,5>& c) :
00278         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00279         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)), 
00280         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00281         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
00282         _v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
00283 
00284     // Support for l-value reference proxy copy construction
00285     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,5>& c) : 
00286         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)), 
00287         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)), 
00288         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00289         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
00290         _v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
00291 
00292     // Support for planar_pixel_iterator construction and dereferencing
00293     template <typename P> homogeneous_color_base(P* p,bool) : 
00294         _v0(&semantic_at_c<0>(*p)), 
00295         _v1(&semantic_at_c<1>(*p)), 
00296         _v2(&semantic_at_c<2>(*p)), 
00297         _v3(&semantic_at_c<3>(*p)),
00298         _v4(&semantic_at_c<4>(*p)) {}
00299 
00300     template <typename Ref> Ref deref() const { 
00301         return Ref(*semantic_at_c<0>(*this), 
00302                    *semantic_at_c<1>(*this), 
00303                    *semantic_at_c<2>(*this), 
00304                    *semantic_at_c<3>(*this),
00305                    *semantic_at_c<4>(*this)); }
00306 
00307     // Support for planar_pixel_reference offset constructor
00308     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff) 
00309         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00310           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
00311           _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
00312           _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)),
00313           _v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {}
00314 
00315     // Support for planar_pixel_reference operator[]
00316     Element at_c_dynamic(size_t i) const {
00317         switch (i) {
00318             case 0: return _v0;
00319             case 1: return _v1;
00320             case 2: return _v2;
00321             case 3: return _v3;
00322         }
00323         return _v4;
00324     }
00325 };
00326 
00327 // The following way of casting adjacent channels (the contents of color_base) into an array appears to be unsafe
00328 // -- there is no guarantee that the compiler won't add any padding between adjacent channels.
00329 // Note, however, that GIL _must_ be compiled with compiler settings ensuring there is no padding in the color base structs.
00330 // This is because the color base structs must model the interleaved organization in memory. In other words, the client may
00331 // 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)
00332 // with no padding. We have tested with char/int/float/double channels on gcc and VC and have so far discovered no problem.
00333 // We have even tried using strange channels consisting of short + char (3 bytes). With the default 4-byte alignment on VC, the size
00334 // 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.
00335 // However, the client must nevertheless ensure that proper compiler settings are used for their compiler and their channel types.
00336 
00337 template <typename Element, typename Layout, int K>
00338 typename element_reference_type<homogeneous_color_base<Element,Layout,K> >::type       
00339 dynamic_at_c(homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
00340     assert(i<K);
00341     return (gil_reinterpret_cast<Element*>(&cb))[i];
00342 }
00343 
00344 template <typename Element, typename Layout, int K>
00345 typename element_const_reference_type<homogeneous_color_base<Element,Layout,K> >::type 
00346 dynamic_at_c(const homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
00347     assert(i<K);
00348     return (gil_reinterpret_cast_c<const Element*>(&cb))[i];
00349 }
00350 
00351 template <typename Element, typename Layout, int K>
00352 typename element_reference_type<homogeneous_color_base<Element&,Layout,K> >::type       
00353 dynamic_at_c(const homogeneous_color_base<Element&,Layout,K>& cb, std::size_t i) {
00354     assert(i<K);
00355     return cb.at_c_dynamic(i);
00356 }
00357 
00358 template <typename Element, typename Layout, int K>
00359 typename element_const_reference_type<homogeneous_color_base<const Element&,Layout,K> >::type 
00360 dynamic_at_c(const homogeneous_color_base<const Element&,Layout,K>& cb, std::size_t i) {
00361     assert(i<K);
00362     return cb.at_c_dynamic(i);
00363 }
00364 
00365 
00366 } // namespace detail
00367 
00368 template <typename Element, typename Layout, int K1, int K>  
00369 struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
00370     typedef Element type;
00371 };
00372 
00373 template <typename Element, typename Layout, int K1, int K> 
00374 struct kth_element_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<Element> {};
00375 
00376 template <typename Element, typename Layout, int K1, int K> 
00377 struct kth_element_const_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<typename add_const<Element>::type> {};
00378 
00381 template <int K, typename E, typename L, int N> inline
00382 typename add_reference<E>::type
00383 at_c(      detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
00384 
00387 template <int K, typename E, typename L, int N> inline
00388 typename add_reference<typename add_const<E>::type>::type
00389 at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
00390 
00391 namespace detail {
00392     struct swap_fn {
00393         template <typename T> void operator()(T& x, T& y) const {
00394             using std::swap;
00395             swap(x,y);
00396         }
00397     };
00398 }
00399 template <typename E, typename L, int N> inline
00400 void swap(detail::homogeneous_color_base<E,L,N>& x, detail::homogeneous_color_base<E,L,N>& y) { 
00401     static_for_each(x,y,detail::swap_fn());
00402 }
00403 
00404 
00405 } }  // namespace boost::gil
00406 
00407 #endif

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google