00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CVD_RGB_TRAITS_H
00022 #define CVD_RGB_TRAITS_H
00023
00024 #include <cvd/rgb.h>
00025 #include <cvd/rgba.h>
00026 #include <cvd/rgb8.h>
00027 #include <cvd/argb.h>
00028 #include <cvd/bgrx.h>
00029 #include <cvd/la.h>
00030 #include <cvd/internal/builtin_components.h>
00031 #include <cvd/internal/pixel_traits.h>
00032
00033 namespace CVD
00034 {
00035 namespace Pixel
00036 {
00037
00038 template<class P> struct Component<Rgb<P> >
00039 {
00040 typedef P type;
00041 static const size_t count = 3;
00042
00043
00044
00045 static const P& get(const Rgb<P>& pixel, size_t i)
00046 {
00047 return *(reinterpret_cast<const P*>(&pixel)+i);
00048
00049 }
00050
00051 static P& get(Rgb<P>& pixel, size_t i)
00052 {
00053 return *(reinterpret_cast<P*>(&pixel)+i);
00054
00055 }
00056 };
00057
00058 template<class P> struct Component<Bgrx<P> >
00059 {
00060 typedef P type;
00061 static const size_t count = 3;
00062
00063
00064
00065 static const P& get(const Bgrx<P>& pixel, size_t i)
00066 {
00067 return *(reinterpret_cast<const P*>(&pixel)+i);
00068
00069 }
00070
00071 static P& get(Bgrx<P>& pixel, size_t i)
00072 {
00073 return *(reinterpret_cast<P*>(&pixel)+i);
00074
00075 }
00076 };
00077
00078
00079 template<> struct Component<Rgb8>
00080 {
00081 typedef unsigned char type;
00082 static const size_t count = 3;
00083
00084 static const type& get(const Rgb8& pixel, size_t i)
00085 {
00086 return *(reinterpret_cast<const unsigned char*>(&pixel)+i);
00087
00088 }
00089
00090 static type& get(Rgb8& pixel, size_t i)
00091 {
00092 return *(reinterpret_cast<unsigned char*>(&pixel)+i);
00093
00094 }
00095 };
00096
00097 template<class P> struct Component<Rgba<P> >
00098 {
00099 typedef P type;
00100 static const size_t count = 4;
00101
00102 static const P& get(const Rgba<P>& pixel, size_t i)
00103 {
00104 return *(reinterpret_cast<const P*>(&pixel)+i);
00105
00106 }
00107
00108 static P& get(Rgba<P>& pixel, size_t i)
00109 {
00110 return *(reinterpret_cast<P*>(&pixel)+i);
00111
00112 }
00113 };
00114
00115 template<class P> struct Component<La<P> >
00116 {
00117 typedef P type;
00118 static const size_t count = 2;
00119
00120 static const P& get(const La<P>& pixel, size_t i)
00121 {
00122 return *(reinterpret_cast<const P*>(&pixel)+i);
00123 }
00124
00125 static P& get(La<P>& pixel, size_t i)
00126 {
00127 return *(reinterpret_cast<P*>(&pixel)+i);
00128 }
00129 };
00130
00131 template<class P> struct Component<Argb<P> >
00132 {
00133 typedef P type;
00134 static const size_t count = 4;
00135
00136 static const P& get(const Argb<P>& pixel, size_t i)
00137 {
00138
00139 return i == 0 ? pixel.red : (i==1 ? pixel.green : (i==2 ?pixel.blue: pixel.alpha));
00140 }
00141
00142 static P& get(Argb<P>& pixel, size_t i)
00143 {
00144
00145 return i == 0 ? pixel.red : (i==1 ? pixel.green : (i==2 ?pixel.blue: pixel.alpha));
00146 }
00147 };
00148
00149 template <class T> struct is_Rgb { enum { value = 0 }; };
00150 template <class T> struct is_Rgb<Rgb<T> > { enum { value = 1 }; };
00151 template <> struct is_Rgb<Rgb8> { enum { value = 1 }; };
00152 template <class T> struct is_Rgb<Rgba<T> > { enum { value = 1 }; };
00153 template <class T> struct is_Rgb<Argb<T> > { enum { value = 1 }; };
00154
00155 template<class T, int LIFT> struct traits<Rgb<T>, LIFT>
00156 {
00157 typedef Rgb<typename Pixel::traits<T>::wider_type> wider_type;
00158 typedef Rgb<typename Pixel::traits<T>::float_type> float_type;
00159 };
00160
00161 template<class T, int LIFT> struct traits<Rgba<T>, LIFT>
00162 {
00163 typedef Rgba<typename Pixel::traits<T>::wider_type> wider_type;
00164 typedef Rgba<typename Pixel::traits<T>::float_type> float_type;
00165 };
00166
00167 template<class T, int LIFT> struct traits<La<T>, LIFT>
00168 {
00169 typedef La<typename Pixel::traits<T>::wider_type> wider_type;
00170 typedef La<typename Pixel::traits<T>::float_type> float_type;
00171 };
00172
00173 template<int LIFT> struct traits<Rgb8, LIFT>
00174 {
00175 typedef Rgb<int> wider_type;
00176 typedef Rgb<float> float_type;
00177 };
00178
00179 }
00180 template <class T> struct Rgb_ops {
00181 template <class S> static inline T sum(const T& a, const S& b) { return T(a.red+b.red, a.green+b.green, a.blue+b.blue); }
00182 template <class S> static inline void add(T& a, const S& b) { a.red+=b.red; a.green+=b.green; a.blue+=b.blue; }
00183 template <class S> static inline T diff(const T& a, const S& b) { return T(a.red-b.red, a.green-b.green, a.blue-b.blue); }
00184 template <class S> static inline void sub(T& a, const S& b) { a.red-=b.red; a.green-=b.green; a.blue-=b.blue; }
00185 template <class S> static inline T prod(const T& a, const S& b) { return T(a.red*b, a.green*b, a.blue*b); }
00186 template <class S> static inline void mul(T& a, const S& b) { a.red*=b; a.green*=b; a.blue*=b; }
00187 template <class S> static inline T quot(const T& a, const S& b) { return T(a.red/b, a.green/b, a.blue/b); }
00188 template <class S> static inline void div(T& a, const S& b) { a.red/=b; a.green/=b; a.blue/=b; }
00189 template <class S> static inline void assign(T& a, const S& b) { a.red=b.red; a.green=b.green; a.blue=b.blue; }
00190 };
00191
00192 template <class T, class S> inline Rgb<T> operator+(const Rgb<T>& a, const Rgb<S>& b) { return Rgb_ops<Rgb<T> >::sum(a,b); }
00193 template <class T, class S> inline Rgb<T>& operator+=(Rgb<T>& a, const Rgb<S>& b) { Rgb_ops<Rgb<T> >::add(a,b); return a; }
00194 template <class T, class S> inline Rgb<T> operator-(const Rgb<T>& a, const Rgb<S>& b) { return Rgb_ops<Rgb<T> >::diff(a,b); }
00195 template <class T, class S> inline Rgb<T>& operator-=(Rgb<T>& a, const Rgb<S>& b) { Rgb_ops<Rgb<T> >::sub(a,b); return a; }
00196 template <class T, class S> inline Rgb<T> operator*(const Rgb<T>& a, const S& b) { return Rgb_ops<Rgb<T> >::prod(a,b); }
00197 template <class T, class S> inline Rgb<T> operator*(const S& b, const Rgb<T>& a) { return Rgb_ops<Rgb<T> >::prod(a,b); }
00198 template <class T, class S> inline Rgb<T>& operator*=(Rgb<T>& a, const S& b) { Rgb_ops<Rgb<T> >::mul(a,b); return a; }
00199 template <class T, class S> inline Rgb<T> operator/(const Rgb<T>& a, const S& b) { return Rgb_ops<Rgb<T> >::quot(a,b); }
00200 template <class T, class S> inline Rgb<T> operator/(const S& b, const Rgb<T>& a) { return Rgb_ops<Rgb<T> >::quot(a,b); }
00201 template <class T, class S> inline Rgb<T>& operator/=(Rgb<T>& a, const S& b) { Rgb_ops<Rgb<T> >::div(a,b); return a; }
00202
00203
00204 template <class T> struct Rgba_ops {
00205 template <class S> static inline T sum(const T& a, const S& b) { return T(a.red+b.red, a.green+b.green, a.blue+b.blue, a.alpha+b.alpha); }
00206 template <class S> static inline void add(T& a, const S& b) { a.red+=b.red; a.green+=b.green; a.blue+=b.blue; a.alpha+=b.alpha;}
00207 template <class S> static inline T diff(const T& a, const S& b) { return T(a.red-b.red, a.green-b.green, a.blue-b.blue, a.alpha-b.alpha); }
00208 template <class S> static inline void sub(T& a, const S& b) { a.red-=b.red; a.green-=b.green; a.blue-=b.blue; a.alpha-=b.alpha; }
00209 template <class S> static inline T prod(const T& a, const S& b) { return T(a.red*b, a.green*b, a.blue*b, a.alpha*b); }
00210 template <class S> static inline void mul(T& a, const S& b) { a.red*=b; a.green*=b; a.blue*=b; a.alpha*=b; }
00211 template <class S> static inline T quot(const T& a, const S& b) { return T(a.red/b, a.green/b, a.blue/b, a.alpha/b); }
00212 template <class S> static inline void div(T& a, const S& b) { a.red/=b; a.green/=b; a.blue/=b; a.alpha/=b;}
00213 template <class S> static inline void assign(T& a, const S& b) { a.red=b.red; a.green=b.green; a.blue=b.blue; a.alpha=b.alpha; }
00214 };
00215
00216 template <class T, class S> inline Rgba<T> operator+(const Rgba<T>& a, const Rgba<S>& b) { return Rgba_ops<Rgba<T> >::sum(a,b); }
00217 template <class T, class S> inline Rgba<T>& operator+=(Rgba<T>& a, const Rgba<S>& b) { Rgba_ops<Rgba<T> >::add(a,b); return a; }
00218 template <class T, class S> inline Rgba<T> operator-(const Rgba<T>& a, const Rgba<S>& b) { return Rgba_ops<Rgba<T> >::diff(a,b); }
00219 template <class T, class S> inline Rgba<T>& operator-=(Rgba<T>& a, const Rgba<S>& b) { Rgba_ops<Rgba<T> >::sub(a,b); return a; }
00220 template <class T, class S> inline Rgba<T> operator*(const Rgba<T>& a, const S& b) { return Rgba_ops<Rgba<T> >::prod(a,b); }
00221 template <class T, class S> inline Rgba<T> operator*(const S& b, const Rgba<T>& a) { return Rgba_ops<Rgba<T> >::prod(a,b); }
00222 template <class T, class S> inline Rgba<T>& operator*=(Rgba<T>& a, const S& b) { Rgba_ops<Rgba<T> >::mul(a,b); return a; }
00223 template <class T, class S> inline Rgba<T> operator/(const Rgba<T>& a, const S& b) { return Rgba_ops<Rgba<T> >::quot(a,b); }
00224 template <class T, class S> inline Rgba<T> operator/(const S& b, const Rgba<T>& a) { return Rgba_ops<Rgba<T> >::quot(a,b); }
00225 template <class T, class S> inline Rgba<T>& operator/=(Rgba<T>& a, const S& b) { Rgba_ops<Rgba<T> >::div(a,b); return a; }
00226
00227 template <class T> struct La_ops {
00228 template <class S> static inline T sum(const T& a, const S& b) { return T(a.luminance+b.luminance, a.alpha+b.alpha); }
00229 template <class S> static inline void add(T& a, const S& b) { a.luminance+=b.luminance; a.alpha+=b.alpha;}
00230 template <class S> static inline T diff(const T& a, const S& b) { return T(a.luminance-b.luminance, a.alpha-b.alpha); }
00231 template <class S> static inline void sub(T& a, const S& b) { a.luminance-=b.luminance; a.alpha-=b.alpha; }
00232 template <class S> static inline T prod(const T& a, const S& b) { return T(a.luminance*b, a.alpha*b); }
00233 template <class S> static inline void mul(T& a, const S& b) { a.luminance*=b; a.alpha*=b; }
00234 template <class S> static inline T quot(const T& a, const S& b) { return T(a.luminance/b, a.alpha/b); }
00235 template <class S> static inline void div(T& a, const S& b) { a.luminance/=b; a.alpha/=b;}
00236 template <class S> static inline void assign(T& a, const S& b) { a.luminance=b.luminance; a.alpha=b.alpha; }
00237 };
00238
00239 template <class T, class S> inline La<T> operator+(const La<T>& a, const La<S>& b) { return La_ops<La<T> >::sum(a,b); }
00240 template <class T, class S> inline La<T>& operator+=(La<T>& a, const La<S>& b) { La_ops<La<T> >::add(a,b); return a; }
00241 template <class T, class S> inline La<T> operator-(const La<T>& a, const La<S>& b) { return La_ops<La<T> >::diff(a,b); }
00242 template <class T, class S> inline La<T>& operator-=(La<T>& a, const La<S>& b) { La_ops<La<T> >::sub(a,b); return a; }
00243 template <class T, class S> inline La<T> operator*(const La<T>& a, const S& b) { return La_ops<La<T> >::prod(a,b); }
00244 template <class T, class S> inline La<T> operator*(const S& b, const La<T>& a) { return La_ops<La<T> >::prod(a,b); }
00245 template <class T, class S> inline La<T>& operator*=(La<T>& a, const S& b) { La_ops<La<T> >::mul(a,b); return a; }
00246 template <class T, class S> inline La<T> operator/(const La<T>& a, const S& b) { return La_ops<La<T> >::quot(a,b); }
00247 template <class T, class S> inline La<T> operator/(const S& b, const La<T>& a) { return La_ops<La<T> >::quot(a,b); }
00248 template <class T, class S> inline La<T>& operator/=(La<T>& a, const S& b) { La_ops<La<T> >::div(a,b); return a; }
00249
00250
00251
00252 }
00253 #endif