00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_PIXEL_H
00010 #define GIL_PIXEL_H
00011
00020
00021 #include <functional>
00022 #include "gil_config.hpp"
00023 #include "gil_concept.hpp"
00024 #include "channel.hpp"
00025 #include "metafunctions.hpp"
00026 #include "utilities.hpp"
00027 #include "pixel_algorithm.hpp"
00028
00029 ADOBE_GIL_NAMESPACE_BEGIN
00030
00031 struct gray_t;
00032
00033 namespace detail {
00046 template <typename T, typename C> struct color_base {};
00047
00050 template <typename T1, typename C1, typename T2, typename C2>
00051 struct _color_converter {
00052 template <typename P1, typename P2> void operator()(const P1& src, P2& dst);
00053 };
00054
00057 template <typename CS,int N> struct channel_accessor {};
00058
00059 template <typename CS>
00060 struct nth_channel_accessor {
00061
00062 template <typename T>
00063 T& operator()( color_base<T,CS>& p,std::size_t i) const {return (( T*)(&p))[i]; }
00064 template <typename T>
00065 const T& operator()(const color_base<T,CS>& p,std::size_t i) const {return ((const T*)(&p))[i]; }
00066
00067
00068 template <typename T>
00069 T& operator()(const color_base< T&,CS>& p,std::size_t i) const { return *((( T**)(( T*)&p))[i]); }
00070 template <typename T>
00071 const T& operator()(const color_base<const T&,CS>& p,std::size_t i) const { return *(((const T**)((const T*)&p))[i]); }
00072 };
00073 }
00074
00103
00104 template <typename TR, typename C> struct planar_ref;
00105
00106 template <typename T, typename C>
00107 struct pixel : public detail::color_base<T,C> {
00108 private:
00109 typedef detail::color_base<T,C> parent_t;
00110 public:
00111 typedef C color_space_t;
00112 typedef typename channel_traits<T>::value_type channel_t;
00113 typedef typename channel_traits<T>::reference channel_reference;
00114 typedef typename channel_traits<T>::const_reference channel_const_reference;
00115 typedef pixel<channel_t,color_space_t> pixel_value_type;
00116 template <int N> struct kth_channel_t { typedef channel_t type; };
00117
00118 static const int num_channels=color_space_t::num_channels;
00119
00120 pixel(){}
00121 explicit pixel(T v) { fill_channels(*this,v); }
00122 pixel(T v0, T v1) : parent_t(v0,v1) {}
00123 pixel(T v0, T v1, T v2) : parent_t(v0,v1,v2) {}
00124 pixel(T v0, T v1, T v2, T v3) : parent_t(v0,v1,v2,v3) {}
00125 pixel(T v0, T v1, T v2, T v3, T v4) : parent_t(v0,v1,v2,v3,v4) {}
00126
00127 pixel(const pixel& p) : parent_t(p) {}
00128 template <typename T1, typename C1> pixel(const pixel<T1,C1>& p) : parent_t(p) { boost::function_requires<PixelsCompatibleConcept<pixel<T1,C1>,pixel_value_type> >();}
00129 template <typename TR1, typename C1> pixel(const planar_ref<TR1,C1>& p) : parent_t(p) { boost::function_requires<PixelsCompatibleConcept<pixel<TR1,C1>,pixel_value_type> >();}
00130
00131 pixel& operator=(const pixel& p) { detail::channel_recursion<num_channels>::copy_channels(*this,p); return *this; }
00132 template <typename TR1, typename C1> pixel& operator=(const planar_ref<TR1,C1>& p) { boost::function_requires<PixelsCompatibleConcept<pixel<TR1,C1>,pixel_value_type> >(); detail::channel_recursion<num_channels>::copy_channels(*this,p); return *this; }
00133 pixel& operator=(T chan) { BOOST_STATIC_ASSERT((boost::is_same<C, gray_t>::value)); channel<0>()=chan; return *this; }
00134
00135 template <typename P> bool operator==(const P& p) const { boost::function_requires<PixelsCompatibleConcept<P,pixel_value_type> >(); return detail::channel_recursion<num_channels>::equal_to(*this,p); }
00136 template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
00137
00138 channel_reference operator[](std::size_t i) { return detail::nth_channel_accessor<color_space_t>()(*this,i); }
00139 channel_const_reference operator[](std::size_t i) const { return detail::nth_channel_accessor<color_space_t>()(*this,i); }
00140
00141 template <int N> channel_reference channel() { return detail::channel_accessor<C,N>()(*this); }
00142 template <int N> channel_const_reference channel() const { return detail::channel_accessor<C,N>()(*this); }
00143 template <int N> channel_reference semantic_channel() { return detail::channel_accessor<typename C::base,N>()(*this); }
00144 template <int N> channel_const_reference semantic_channel() const { return detail::channel_accessor<typename C::base,N>()(*this); }
00145 };
00146
00147
00148
00149 ADOBE_GIL_NAMESPACE_END
00150
00151 #endif