cvd/utility.h

00001 #ifndef CVD_UTILITY_H
00002 #define CVD_UTILITY_H
00003 
00004 #include <cvd/image.h>
00005 #include <cvd/internal/is_pod.h>
00006 #include <cvd/internal/pixel_traits.h>
00007 #include <cvd/internal/convert_pixel_types.h>
00008 
00009 namespace CVD { //begin namespace
00010 
00026   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())
00027   {
00028     if (size.x == -1 && size.y == -1)
00029       size = in.size();
00030     // FIXME: This should be an exception, but which one do I use? 
00031     // I refuse to define another "ImageRefNotInImage" in this namespace.
00032     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)))){   
00033     std::cerr << "bad copy: " << in.size() << " " << out.size() << " " << size << " " << begin << " " << dst << std::endl;
00034     int *p = 0;
00035     *p = 1;
00036     }
00037     if (in.size() == out.size() && size == in.size() && begin == ImageRef() && dst == ImageRef()) {
00038       Pixel::ConvertPixels<S,T>::convert(in.data(), out.data(), in.totalsize());
00039       return;
00040     }
00041     
00042     const S* from = &in[begin];
00043     T* to = &out[dst];
00044     int i = 0;
00045     while (i++<size.y) {
00046       Pixel::ConvertPixels<S,T>::convert(from, to, size.x);
00047       from += in.size().x;
00048       to += out.size().x;
00049     }
00050   }
00051   
00052   template <class T, bool pod = Internal::is_POD<T>::is_pod> struct ZeroPixel {
00053       static void zero(T& t) { 
00054       for (unsigned int c=0; c<Pixel::Component<T>::count; c++)
00055           Pixel::Component<T>::get(t,c) = 0;
00056       }
00057   };
00058   
00059   template <class T> struct ZeroPixel<T,true> {
00060       static void zero(T& t) { memset(&t,0,sizeof(T)); }
00061   };
00062   
00063   template <class T, bool pod = Internal::is_POD<T>::is_pod> struct ZeroPixels {
00064       static void zero(T* pixels, int count) {
00065       if (count) {
00066           ZeroPixel<T>::zero(*pixels);
00067           std::fill(pixels+1, pixels+count, *pixels);
00068       }
00069       }
00070   };
00071 
00072   template <class T> struct ZeroPixels<T,true> {
00073       static void zero(T* pixels, int count) {
00074       memset(pixels, 0, sizeof(T)*count);
00075       }
00076   };
00077   
00078 
00081   template <class T> inline void zeroPixel(T& pixel) { ZeroPixel<T>::zero(pixel); }
00082 
00085   template <class T> inline void zeroPixels(T* pixels, int count) {  ZeroPixels<T>::zero(pixels, count);  }
00086   
00088   template <class T> void zeroBorders(BasicImage<T>& I)
00089   {
00090     if (I.size().y == 0)
00091       return;
00092     zeroPixels(I[0], I.size().x);
00093     for (int r=0;r<I.size().y-1; r++)
00094     zeroPixels(I[r]+I.size().x-1,2);
00095     zeroPixels(I[I.size().y-1], I.size().x);
00096   }
00097 
00101   template <class A, class B> inline void differences(const A* a, const A* b, B* diff, size_t count)
00102   {
00103       while (count--)
00104       *(diff++) = (B)*(a++) - (B)*(b++);
00105   }
00106 
00110   template <class A, class B> inline void add_multiple_of_sum(const A* a, const A* b, const float& c,  B* out, size_t count)
00111   {
00112       while (count--)
00113       *(out++) += (*(a++) + *(b++)) * c;
00114   }
00115   
00119       template <class A, class B, class C> inline void assign_multiple(const A* a, const B& c,  C* out, size_t count)
00120   {
00121       while (count--)
00122       *(out++) = static_cast<C>(*(a++) * c);
00123   }
00124 
00128   template <class T> double inner_product(const T* a, const T* b, size_t count) {
00129       double dot = 0;
00130       while (count--)
00131       dot += *(a++) * *(b++);
00132       return dot;
00133   }
00134 
00135   template <class R, class D, class T> struct SumSquaredDifferences {
00136       static inline R sum_squared_differences(const T* a, const T* b, size_t count) {
00137       R ssd = 0;
00138       while (count--) {
00139           D d = *a++ - *b++;
00140           ssd += d*d;
00141       }
00142       return ssd;
00143       }
00144   };
00145 
00146   template <class T1, class T2> inline void square(const T1* in, T2* out, size_t count) 
00147   {
00148       while (count--) {
00149       *(out++) = static_cast<T2>(*in * *in);
00150       ++in;
00151       }
00152   }
00153 
00154   template <class T1, class T2> inline void subtract_square(const T1* in, T2* out, size_t count) 
00155   {
00156       while (count--) {
00157       *(out++) -= static_cast<T2>(*in * *in);
00158       ++in;
00159       }
00160   }
00161 
00165   template <class T> inline double sum_squared_differences(const T* a, const T* b, size_t count) {
00166       return SumSquaredDifferences<double,double,T>::sum_squared_differences(a,b,count);
00167   }
00168   
00170   template<int bytes> bool is_aligned(const void* ptr);
00171   template<> inline bool is_aligned<8>(const void* ptr) {   return ((reinterpret_cast<size_t>(ptr)) & 0x7) == 0;   }
00172   template<> inline bool is_aligned<16>(const void* ptr) {  return ((reinterpret_cast<size_t>(ptr)) & 0xF) == 0;   }
00173 
00175   template<int A, class T> inline size_t steps_to_align(const T* ptr) 
00176   {
00177       return is_aligned<A>(ptr) ? 0 : (A-((reinterpret_cast<size_t>(ptr)) & (A-1)))/sizeof(T); 
00178   }
00179 
00180   void differences(const byte* a, const byte* b, short* diff, unsigned int size);
00181   void differences(const short* a, const short* b, short* diff, unsigned int size);
00182 
00183 
00184   void differences(const float* a, const float* b, float* diff, size_t size);
00185   void add_multiple_of_sum(const float* a, const float* b, const float& c,  float* out, size_t count);
00186   void assign_multiple(const float* a, const float& c,  float* out, size_t count);
00187   double inner_product(const float* a, const float* b, size_t count);
00188   double sum_squared_differences(const float* a, const float* b, size_t count);
00189   void square(const float* in, float* out, size_t count);
00190   void subtract_square(const float* in, float* out, size_t count);
00191 
00192   void differences(const int32_t* a, const int32_t* b, int32_t* diff, size_t size);
00193   void differences(const double* a, const double* b, double* diff, size_t size);
00194   void add_multiple_of_sum(const double* a, const double* b, const float& c,  double* out, size_t count);
00195   void assign_multiple(const double* a, const double& c,  double* out, size_t count);
00196   double inner_product(const double* a, const double* b, size_t count);
00197   double sum_squared_differences(const double* a, const double* b, size_t count);
00198   long long sum_squared_differences(const byte* a, const byte* b, size_t count);
00199 
00200 
00201 }
00202 
00203 #endif

Generated on Wed Feb 18 10:23:02 2009 for CVD by  doxygen 1.5.3