CVD 0.8
|
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