00001 /*00002 Copyright 2005-2007 Adobe Systems Incorporated00003 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 at00006 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_HPP00014 #define GIL_COLOR_BASE_HPP00015
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-declare00039 template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
00040
00041 // Forward-declare semantic_at_c00042 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_type00048 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>
00074struct homogeneous_color_base<Element,Layout,1> {
00075 private:
00076 Element _v0;
00077 public:
00078 typedef Layout layout_t;
00079 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00080 typenameelement_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 type00086 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>
00095struct homogeneous_color_base<Element,Layout,2> {
00096 private:
00097 Element _v0, _v1;
00098 public:
00099 typedef Layout layout_t;
00100 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00101 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00102 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00103 typenameelement_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 construction00114 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 dereferencing00119 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 constructor00127 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>
00141struct homogeneous_color_base<Element,Layout,3> {
00142 private:
00143 Element _v0, _v1, _v2;
00144 public:
00145 typedef Layout layout_t;
00146 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00147 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00148 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00149 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00150 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
00151 typenameelement_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 construction00163 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 dereferencing00169 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 constructor00179 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>
00197struct homogeneous_color_base<Element,Layout,4> {
00198 private:
00199 Element _v0, _v1, _v2, _v3;
00200 public:
00201 typedef Layout layout_t;
00202 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00203 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00204 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00205 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00206 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
00207 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00208 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
00209 typenameelement_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 construction00221 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 dereferencing00228 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 constructor00241 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>
00261struct homogeneous_color_base<Element,Layout,5> {
00262 private:
00263 Element _v0, _v1, _v2, _v3, _v4;
00264 public:
00265 typedef Layout layout_t;
00266 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00267 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00268 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00269 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00270 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
00271 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00272 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
00273 typenameelement_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
00274 typenameelement_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) { return _v4; }
00275 typenameelement_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 construction00288 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 dereferencing00296 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 constructor00311 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 unsafe00331 // -- 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 may00334 // 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 size00337 // 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 typenameelement_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 typenameelement_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 detail00370
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> inline00385 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> inline00391 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> inline00403 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::gil00409
00410 #endif
Generated on Sat May 2 13:50:13 2009 for Generic Image Library by
1.5.6
Статья Generic Image Library: color_base.hpp Source File раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.