00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CVD_CONVERT_PIXEL_TYPES_H
00022 #define CVD_CONVERT_PIXEL_TYPES_H
00023
00024 #include <math.h>
00025
00026 #include <cvd/abs.h>
00027 #include <cvd/internal/scalar_convert.h>
00028 #include <cvd/internal/builtin_components.h>
00029 #include <cvd/internal/rgb_components.h>
00030 #include <cvd/internal/is_pod.h>
00031 #include <limits>
00032
00033 namespace CVD{namespace Pixel
00034 {
00035
00036
00037
00038
00039
00040 template <class From, class To, int CF=Pixel::Component<From>::count, int CT=Pixel::Component<To>::count> struct GenericConversion;
00041
00042 template <class From, class To> struct GenericConversion<From,To,1,1> {
00043 static inline void convert(const From& from, To& to) {
00044 to = scalar_convert<To,From>(from);
00045 }
00046 };
00047
00048 template <class From, class To, int N> struct GenericConversion<From,To,N,N> {
00049 typedef typename Pixel::Component<From>::type FromS;
00050 typedef typename Pixel::Component<To>::type ToS;
00051 static inline void convert(const From& from, To& to) {
00052 for (int i=0; i<N; i++)
00053 Pixel::Component<To>::get(to,i) = scalar_convert<ToS,FromS>(Pixel::Component<From>::get(from,i));
00054 }
00055 };
00056
00057 template <class T, int N> struct GenericConversion<T,T,N,N> {
00058 static inline void convert(const T& from, T& to) {
00059 to = from;
00060 }
00061 };
00062
00063 template <class T, int N> struct GenericConversion<T[N],T[N], N, N> {
00064 typedef T array[N];
00065 static inline void convert(const array& from, array& to) {
00066 for (int i=0; i<N; i++)
00067 to[i] = from[i];
00068 }
00069 };
00070
00071 template <class Rgbish, class Scalar> struct CIE {
00072 static inline void convert(const Rgbish& from, Scalar& to) {
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 const double wr=0.2989959716796875, wg=0.587005615234375, wb=0.1139984130859375;
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 to = scalar_convert<Scalar,typename Pixel::Component<Rgbish>::type,double>(wr*from.red + wg*from.green + wb*from.blue);
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 }
00111 };
00112
00113 template <class P, class Scalar> struct Uniform {
00114 static inline void convert(const P& from, Scalar& to) {
00115 typedef typename Pixel::Component<P>::type T;
00116 typename traits<T>::wider_type sum = Pixel::Component<P>::get(from,0);
00117 for (unsigned int i=1; i<Pixel::Component<P>::count; i++)
00118 sum += Pixel::Component<P>::get(from,i);
00119 to = scalar_convert<Scalar,T>(sum/Pixel::Component<P>::count);
00120 }
00121 };
00122
00123 template <class P, class Scalar> struct RMS {
00124 static inline void convert(const P& from, Scalar& to) {
00125 typedef typename Pixel::Component<P>::type T;
00126 double sum = Pixel::Component<P>::get(from,0);
00127 sum *= sum;
00128 for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
00129 double w = Pixel::Component<P>::get(from,i);
00130 sum += w*w;
00131 }
00132 to = scalar_convert<Scalar,T,double>(sqrt(sum/(Pixel::Component<P>::count)));
00133 }
00134 };
00135
00136 template <class P, class Scalar> struct AverageAbs {
00137 static inline void convert(const P& from, Scalar& to) {
00138 typedef typename Pixel::Component<P>::type T;
00139 typedef typename Pixel::traits<T>::wider_type sum_type;
00140 sum_type sum = CVD::abs(Pixel::Component<P>::get(from,0));
00141 for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
00142 sum += CVD::abs(Pixel::Component<P>::get(from,i));
00143 }
00144 to = scalar_convert<Scalar,T,sum_type>(sum/Pixel::Component<P>::count);
00145 }
00146 };
00147
00148 template <class P, class Scalar> struct L2Norm {
00149 static inline void convert(const P& from, Scalar& to) {
00150 typedef typename Pixel::Component<P>::type T;
00151 double sum = Pixel::Component<P>::get(from,0);
00152 sum *= sum;
00153 for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
00154 double w = Pixel::Component<P>::get(from,i);
00155 sum += w*w;
00156 }
00157 to = scalar_convert<Scalar,T,double>(sqrt(sum));
00158 }
00159 };
00160
00161 template <class P, class Scalar> struct SumOfSquares {
00162 static inline void convert(const P& from, Scalar& to) {
00163 typedef typename Pixel::Component<P>::type T;
00164 double sum = Pixel::Component<P>::get(from,0);
00165 sum *= sum;
00166 for (unsigned int i=1; i<Pixel::Component<P>::count; i++) {
00167 double w = Pixel::Component<P>::get(from,i);
00168 sum += w*w;
00169 }
00170 to = scalar_convert<Scalar,T,double>(sum);
00171 }
00172 };
00173
00174 template <class Scalar, class Vec> struct Replicate {
00175 static inline void convert(const Scalar& from, Vec& to) {
00176 typedef typename Pixel::Component<Vec>::type T;
00177 Pixel::Component<Vec>::get(to,0) = scalar_convert<T, Scalar>(from);
00178 for (size_t i=1; i<Pixel::Component<Vec>::count; i++)
00179 Pixel::Component<Vec>::get(to,i) = Pixel::Component<Vec>::get(to,0);
00180 }
00181 };
00182
00183 template <class Scalar, class T> struct GreyToRgba {
00184 static inline void convert(const Scalar& from, Rgba<T>& to) {
00185 to.red = to.green = to.blue = scalar_convert<T, Scalar>(from);
00186 to.alpha = traits<T>::max_intensity;
00187 }
00188 };
00189
00190 template <class A, class B> inline void RgbToRgb(const A& from, B& to) {
00191 typedef typename Pixel::Component<A>::type T;
00192 typedef typename Pixel::Component<B>::type S;
00193 to.red = scalar_convert<S,T>(from.red);
00194 to.green = scalar_convert<S,T>(from.green);
00195 to.blue = scalar_convert<S,T>(from.blue);
00196 }
00197
00198 template <class A, class B> struct RgbishToRgbish {
00199 static inline void convert(const A& from, B& to) {
00200 RgbToRgb(from,to);
00201 }
00202 };
00203
00204 template <class A,class T> struct RgbishToRgbish<A,Rgba<T> > {
00205 static inline void convert(const A& from, Rgba<T>& to) {
00206 RgbToRgb(from,to);
00207 to.alpha = traits<T>::max_intensity;
00208 }
00209 };
00210
00211 template <class A,class T> struct RgbishToRgbish<A,Argb<T> > {
00212 static inline void convert(const A& from, Argb<T>& to) {
00213 RgbToRgb(from,to);
00214 to.alpha = traits<T>::max_intensity;
00215 }
00216 };
00217
00218 template <class S,class T> struct RgbishToRgbish<Rgba<S>,Rgba<T> > {
00219 static inline void convert(const Rgba<S>& from, Rgba<T>& to) {
00220 RgbToRgb(from,to);
00221 to.alpha = scalar_convert<T,S>(from.alpha);
00222 }
00223 };
00224
00225 template <class S,class T> struct RgbishToRgbish<Argb<S>,Argb<T> > {
00226 static inline void convert(const Argb<S>& from, Argb<T>& to) {
00227 RgbToRgb(from,to);
00228 to.alpha = scalar_convert<T,S>(from.alpha);
00229 }
00230 };
00231
00232
00233
00234
00235
00236 template <class From, class To, int FN=Pixel::Component<From>::count, int TN=Pixel::Component<To>::count> struct DefaultConversion {
00237 typedef GenericConversion<From,To> type;
00238 };
00239
00240
00241 template <class S, class T> struct DefaultConversion<S,Rgb<T>,1,3> { typedef Replicate<S,Rgb<T> > type; };
00242 template <class S> struct DefaultConversion<S,Rgb8,1,3> { typedef Replicate<S,Rgb8> type; };
00243 template <class S, class T> struct DefaultConversion<S,Bgrx<T>,1,3> { typedef Replicate<S,Bgrx<T> > type; };
00244 template <class S, class T> struct DefaultConversion<S,Rgba<T>,1,4> { typedef GreyToRgba<S,T> type; };
00245
00246
00247 template <class T, class S> struct DefaultConversion<Rgb<T>,S,3,1> { typedef CIE<Rgb<T>,S> type; };
00248 template <class T> struct DefaultConversion<Rgb<T>,Rgb8, 3,3> { typedef RgbishToRgbish<Rgb<T>, Rgb8> type; };
00249 template <class T, class S> struct DefaultConversion<Rgb<T>,Rgba<S>,3,4> { typedef RgbishToRgbish<Rgb<T>, Rgba<S> > type; };
00250 template <class T, class S> struct DefaultConversion<Rgb<T>,Rgb<S>,3,3> { typedef RgbishToRgbish<Rgb<T>, Rgb<S> > type; };
00251 template <class T> struct DefaultConversion<Rgb<T>,Rgb<T>,3,3> { typedef GenericConversion<Rgb<T>, Rgb<T> > type; };
00252 template <class T> struct DefaultConversion<Rgb<T>,Bgrx<T>,3,3> { typedef RgbishToRgbish<Rgb<T>, Bgrx<T> > type; };
00253
00254
00255 template <class T, class S> struct DefaultConversion<Bgrx<T>,S,3,1> { typedef CIE<Bgrx<T>,S> type; };
00256 template <class T> struct DefaultConversion<Bgrx<T>,Rgb8, 3,3> { typedef RgbishToRgbish<Bgrx<T>, Rgb8> type; };
00257 template <class T, class S> struct DefaultConversion<Bgrx<T>,Rgba<S>,3,4> { typedef RgbishToRgbish<Bgrx<T>, Rgba<S> > type; };
00258 template <class T, class S> struct DefaultConversion<Bgrx<T>,Rgb<S>,3,3> { typedef RgbishToRgbish<Bgrx<T>, Rgb<S> > type; };
00259 template <class T> struct DefaultConversion<Bgrx<T>,Rgb<T>,3,3> { typedef GenericConversion<Bgrx<T>, Rgb<T> > type; };
00260 template <class T> struct DefaultConversion<Bgrx<T>,Bgrx<T>,3,3> { typedef RgbishToRgbish<Bgrx<T>, Bgrx<T> > type; };
00261
00262
00263 template <class S> struct DefaultConversion<Rgb8,S,3,1> { typedef CIE<Rgb8,S> type; };
00264 template <class S> struct DefaultConversion<Rgb8,Rgb<S>,3,3> { typedef RgbishToRgbish<Rgb8, Rgb<S> > type; };
00265 template <class S> struct DefaultConversion<Rgb8,Rgba<S>,3,4> { typedef RgbishToRgbish<Rgb8, Rgba<S> > type; };
00266 template <class S> struct DefaultConversion<Rgb8,Bgrx<S>,3,4> { typedef RgbishToRgbish<Rgb8, Bgrx<S> > type; };
00267 template <> struct DefaultConversion<Rgb8,Rgb8,3,3> { typedef GenericConversion<Rgb8, Rgb8> type; };
00268
00269
00270 template <class T, class S> struct DefaultConversion<Rgba<T>,S,4,1> { typedef CIE<Rgba<T>,S> type; };
00271 template <class T, class S> struct DefaultConversion<Rgba<T>,Rgb<S>,4,3> { typedef RgbishToRgbish<Rgba<T>, Rgb<S> > type; };
00272 template <class T, class S> struct DefaultConversion<Rgba<T>,Bgrx<S>,4,3> { typedef RgbishToRgbish<Rgba<T>, Bgrx<S> > type; };
00273 template <class T> struct DefaultConversion<Rgba<T>,Rgb8,4,3> { typedef RgbishToRgbish<Rgba<T>, Rgb8> type; };
00274 template <class T, class S> struct DefaultConversion<Rgba<T>,Rgba<S>,4,4> { typedef RgbishToRgbish<Rgba<T>, Rgba<S> > type; };
00275 template <class T, class S> struct DefaultConversion<Rgba<T>,Argb<S>,4,4> { typedef RgbishToRgbish<Rgba<T>, Argb<S> > type; };
00276 template <class T> struct DefaultConversion<Rgba<T>,Rgba<T>,4,4> { typedef GenericConversion<Rgba<T>, Rgba<T> > type; };
00277
00278
00279
00280 template <class T, class S> struct DefaultConversion<Argb<T>,S,4,1> { typedef CIE<Argb<T>,S> type; };
00281 template <class T, class S> struct DefaultConversion<Argb<T>,Rgb<S>,4,3> { typedef RgbishToRgbish<Argb<T>, Rgb<S> > type; };
00282 template <class T> struct DefaultConversion<Argb<T>,Rgb8,4,3> { typedef RgbishToRgbish<Argb<T>, Rgb8> type; };
00283 template <class T, class S> struct DefaultConversion<Argb<T>,Rgba<S>,4,4> { typedef RgbishToRgbish<Argb<T>, Rgba<S> > type; };
00284 template <class T> struct DefaultConversion<Argb<T>,Argb<T>,4,4> { typedef GenericConversion<Argb<T>, Argb<T> > type; };
00285
00286
00287 template <class From, class To, class Conv=typename DefaultConversion<From,To>::type,
00288 bool both_pod=CVD::Internal::is_POD<From>::is_pod && CVD::Internal::is_POD<To>::is_pod> struct ConvertPixels {
00289 static inline void convert(const From* from, To* to, size_t count) {
00290 for (size_t i=0; i<count; i++)
00291 Conv::convert(from[i], to[i]);
00292 }
00293 };
00294
00295 template <class T> struct ConvertPixels<T,T,GenericConversion<T,T>,true> {
00296 static inline void convert(const T* from, T* to, size_t count) {
00297 memcpy(to, from, count*sizeof(T));
00298 }
00299 };
00300
00305 template<class C> struct DefaultConvertible
00306 {
00307 static const int is = std::numeric_limits<C>::is_specialized;
00308 };
00309
00310 template<class C> struct DefaultConvertible<Rgb<C> >
00311 {
00312 static const int is = std::numeric_limits<C>::is_specialized;
00313 };
00314
00315 template<class C> struct DefaultConvertible<Argb<C> >
00316 {
00317 static const int is = std::numeric_limits<C>::is_specialized;
00318 };
00319
00320 template<class C> struct DefaultConvertible<Rgba<C> >
00321 {
00322 static const int is = std::numeric_limits<C>::is_specialized;
00323 };
00324
00325 template<class C> struct DefaultConvertible<Bgrx<C> >
00326 {
00327 static const int is = std::numeric_limits<C>::is_specialized;
00328 };
00329
00330 template<> struct DefaultConvertible<Rgb8>
00331 {
00332 static const int is = 1;
00333 };
00334
00335 }}
00336 #endif