CVD 0.8
cvd/utility.h
00001 #ifndef CVD_UTILITY_H
00002 #define CVD_UTILITY_H
00003 
00004 #ifndef _WIN32
00005 #include <stdint.h>
00006 #endif
00007 
00008 #include <cvd/image.h>
00009 #include <cvd/internal/is_pod.h>
00010 #include <cvd/internal/pixel_traits.h>
00011 #include <cvd/internal/convert_pixel_types.h>
00012 
00013 namespace CVD { //begin namespace
00014 
00030   template<class S, class T> void copy(const BasicImage<S>& in, BasicImage<T>& out, ImageRef size=ImageRef(-1,-1), ImageRef begin = ImageRef(), ImageRef dst = ImageRef())
00031   {
00032     if (size.x == -1 && size.y == -1)
00033       size = in.size();
00034     // FIXME: This should be an exception, but which one do I use? 
00035     // I refuse to define another "ImageRefNotInImage" in this namespace.
00036     if (!(in.in_image(begin) && out.in_image(dst) && in.in_image(begin+size - ImageRef(1,1)) && out.in_image(dst+size - ImageRef(1,1)))){   
00037     std::cerr << "bad copy: " << in.size() << " " << out.size() << " " << size << " " << begin << " " << dst << std::endl;
00038     int *p = 0;
00039     *p = 1;
00040     }
00041     if (in.size() == out.size() && size == in.size() && begin == ImageRef() && dst == ImageRef()) {
00042       Pixel::ConvertPixels<S,T>::convert(in.data(), out.data(), in.totalsize());
00043       return;
00044     }
00045     
00046     const S* from = &in[begin];
00047     T* to = &out[dst];
00048     int i = 0;
00049     while (i++<size.y) {
00050       Pixel::ConvertPixels<S,T>::convert(from, to, size.x);
00051       from += in.size().x;
00052       to += out.size().x;
00053     }
00054   }
00055   
00056   template <class T, bool pod = Internal::is_POD<T>::is_pod> struct ZeroPixel {
00057       static void zero(T& t) { 
00058       for (unsigned int c=0; c<Pixel::Component<T>::count; c++)
00059           Pixel::Component<T>::get(t,c) = 0;
00060       }
00061   };
00062   
00063   template <class T> struct ZeroPixel<T,true> {
00064       static void zero(T& t) { memset(&t,0,sizeof(T)); }
00065   };
00066   
00067   template <class T, bool pod = Internal::is_POD<T>::is_pod> struct ZeroPixels {
00068       static void zero(T* pixels, int count) {
00069       if (count) {
00070           ZeroPixel<T>::zero(*pixels);
00071           std::fill(pixels+1, pixels+count, *pixels);
00072       }
00073       }
00074   };
00075 
00076   template <class T> struct ZeroPixels<T,true> {
00077       static void zero(T* pixels, int count) {
00078       memset(pixels, 0, sizeof(T)*count);
00079       }
00080   };
00081   
00082 
00085   template <class T> inline void zeroPixel(T& pixel) { ZeroPixel<T>::zero(pixel); }
00086 
00089   template <class T> inline void zeroPixels(T* pixels, int count) {  ZeroPixels<T>::zero(pixels, count);  }
00090   
00092   template <class T> void zeroBorders(BasicImage<T>& I)
00093   {
00094     if (I.size().y == 0)
00095       return;
00096     zeroPixels(I[0], I.size().x);
00097     for (int r=0;r<I.size().y-1; r++)
00098     zeroPixels(I[r]+I.size().x-1,2);
00099     zeroPixels(I[I.size().y-1], I.size().x);
00100   }
00101 
00107   template<class T> void fillBorders(SubImage<T>& im, const T pix, int w=1)
00108   {
00109       //Fill the top and bottom
00110       for(int n=0; n < w; n++)
00111           for(int x=0;  x < im.size().x; x++)
00112           {
00113                 im[n][x] = pix;
00114                 im[im.size().y-1-n][x] = pix;
00115           }
00116     
00117       for(int y=w; y < im.size().y - w; y++)
00118           for(int n=0; n < w; n++)
00119           {
00120               im[y][n] = pix;
00121               im[y][im.size().x - 1 - n] = pix;
00122           } 
00123 
00124   }
00125 
00126 
00127 
00128 
00132   template <class A, class B> inline void differences(const A* a, const A* b, B* diff, size_t count)
00133   {
00134       while (count--)
00135       *(diff++) = (B)*(a++) - (B)*(b++);
00136   }
00137 
00141   template <class A, class B, class C> inline void add_multiple_of_sum(const A* a, const A* b, const C& c,  B* out, size_t count)
00142   {
00143       while (count--)
00144       *(out++) += (*(a++) + *(b++)) * c;
00145   }
00146 
00150       template <class A, class B, class C> inline void assign_multiple(const A* a, const B& c,  C* out, size_t count)
00151   {
00152       while (count--)
00153       *(out++) = static_cast<C>(*(a++) * c);
00154   }
00155 
00159   template <class T> double inner_product(const T* a, const T* b, size_t count) {
00160       double dot = 0;
00161       while (count--)
00162       dot += *(a++) * *(b++);
00163       return dot;
00164   }
00165 
00166   template <class R, class D, class T> struct SumSquaredDifferences {
00167       static inline R sum_squared_differences(const T* a, const T* b, size_t count) {
00168       R ssd = 0;
00169       while (count--) {
00170           D d = *a++ - *b++;
00171           ssd += d*d;
00172       }
00173       return ssd;
00174       }
00175   };
00176 
00177   template <class T1, class T2> inline void square(const T1* in, T2* out, size_t count) 
00178   {
00179       while (count--) {
00180       *(out++) = static_cast<T2>(*in * *in);
00181       ++in;
00182       }
00183   }
00184 
00185   template <class T1, class T2> inline void subtract_square(const T1* in, T2* out, size_t count) 
00186   {
00187       while (count--) {
00188       *(out++) -= static_cast<T2>(*in * *in);
00189       ++in;
00190       }
00191   }
00192 
00196   template <class T> inline double sum_squared_differences(const T* a, const T* b, size_t count) {
00197       return SumSquaredDifferences<double,double,T>::sum_squared_differences(a,b,count);
00198   }
00199   
00201   template<int bytes> bool is_aligned(const void* ptr);
00202   template<> inline bool is_aligned<8>(const void* ptr) {   return ((reinterpret_cast<size_t>(ptr)) & 0x7) == 0;   }
00203   template<> inline bool is_aligned<16>(const void* ptr) {  return ((reinterpret_cast<size_t>(ptr)) & 0xF) == 0;   }
00204 
00206   template<int A, class T> inline size_t steps_to_align(const T* ptr) 
00207   {
00208       return is_aligned<A>(ptr) ? 0 : (A-((reinterpret_cast<size_t>(ptr)) & (A-1)))/sizeof(T); 
00209   }
00210 
00211   void differences(const byte* a, const byte* b, short* diff, unsigned int size);
00212   void differences(const short* a, const short* b, short* diff, unsigned int size);
00213 
00214 
00215   void differences(const float* a, const float* b, float* diff, size_t size);
00216   void add_multiple_of_sum(const float* a, const float* b, const float& c,  float* out, size_t count);
00217   void assign_multiple(const float* a, const float& c,  float* out, size_t count);
00218   double inner_product(const float* a, const float* b, size_t count);
00219   double sum_squared_differences(const float* a, const float* b, size_t count);
00220   void square(const float* in, float* out, size_t count);
00221   void subtract_square(const float* in, float* out, size_t count);
00222 
00223   void differences(const int32_t* a, const int32_t* b, int32_t* diff, size_t size);
00224   void differences(const double* a, const double* b, double* diff, size_t size);
00225   void add_multiple_of_sum(const double* a, const double* b, const double& c,  double* out, size_t count);
00226   void assign_multiple(const double* a, const double& c,  double* out, size_t count);
00227   double inner_product(const double* a, const double* b, size_t count);
00228   double sum_squared_differences(const double* a, const double* b, size_t count);
00229   long long sum_squared_differences(const byte* a, const byte* b, size_t count);
00230 
00231 
00232 }
00233 
00234 #endif