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

Generated on Sat May 2 13:50:13 2009 for Generic Image Library by  doxygen 1.5.6