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://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 1.5.6 |