color_base.hppGo 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 Generated on Thu Nov 8 21:53:16 2007 for Generic Image Library by 1.4.4 |