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 #include <sys/types.h>
00009
00010 namespace CVD {
00011
00027 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())
00028 {
00029 if (size.x == -1 && size.y == -1)
00030 size = in.size();
00031
00032
00033 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)))){
00034 std::cerr << "bad copy: " << in.size() << " " << out.size() << " " << size << " " << begin << " " << dst << std::endl;
00035 int *p = 0;
00036 *p = 1;
00037 }
00038 if (in.size() == out.size() && size == in.size() && begin == ImageRef() && dst == ImageRef()) {
00039 Pixel::ConvertPixels<S,T>::convert(in.data(), out.data(), in.totalsize());
00040 return;
00041 }
00042
00043 const S* from = &in[begin];
00044 T* to = &out[dst];
00045 int i = 0;
00046 while (i++<size.y) {
00047 Pixel::ConvertPixels<S,T>::convert(from, to, size.x);
00048 from += in.size().x;
00049 to += out.size().x;
00050 }
00051 }
00052
00053 template <class T, bool pod = Internal::is_POD<T>::is_pod> struct ZeroPixel {
00054 static void zero(T& t) {
00055 for (unsigned int c=0; c<Pixel::Component<T>::count; c++)
00056 Pixel::Component<T>::get(t,c) = 0;
00057 }
00058 };
00059
00060 template <class T> struct ZeroPixel<T,true> {
00061 static void zero(T& t) { memset(&t,0,sizeof(T)); }
00062 };
00063
00064 template <class T, bool pod = Internal::is_POD<T>::is_pod> struct ZeroPixels {
00065 static void zero(T* pixels, int count) {
00066 if (count) {
00067 ZeroPixel<T>::zero(*pixels);
00068 std::fill(pixels+1, pixels+count, *pixels);
00069 }
00070 }
00071 };
00072
00073 template <class T> struct ZeroPixels<T,true> {
00074 static void zero(T* pixels, int count) {
00075 memset(pixels, 0, sizeof(T)*count);
00076 }
00077 };
00078
00079
00082 template <class T> inline void zeroPixel(T& pixel) { ZeroPixel<T>::zero(pixel); }
00083
00086 template <class T> inline void zeroPixels(T* pixels, int count) { ZeroPixels<T>::zero(pixels, count); }
00087
00089 template <class T> void zeroBorders(BasicImage<T>& I)
00090 {
00091 if (I.size().y == 0)
00092 return;
00093 zeroPixels(I[0], I.size().x);
00094 for (int r=0;r<I.size().y-1; r++)
00095 zeroPixels(I[r]+I.size().x-1,2);
00096 zeroPixels(I[I.size().y-1], I.size().x);
00097 }
00098
00104 template<class T> void fillBorders(SubImage<T>& im, const T pix, int w=1)
00105 {
00106
00107 for(int n=0; n < w; n++)
00108 for(int x=0; x < im.size().x; x++)
00109 {
00110 im[n][x] = pix;
00111 im[im.size().y-1-n][x] = pix;
00112 }
00113
00114 for(int y=w; y < im.size().y - w; y++)
00115 for(int n=0; n < w; n++)
00116 {
00117 im[y][n] = pix;
00118 im[y][im.size().x - 1 - n] = pix;
00119 }
00120
00121 }
00122
00123
00124
00125
00129 template <class A, class B> inline void differences(const A* a, const A* b, B* diff, size_t count)
00130 {
00131 while (count--)
00132 *(diff++) = (B)*(a++) - (B)*(b++);
00133 }
00134
00138 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)
00139 {
00140 while (count--)
00141 *(out++) += (*(a++) + *(b++)) * c;
00142 }
00143
00147 template <class A, class B, class C> inline void assign_multiple(const A* a, const B& c, C* out, size_t count)
00148 {
00149 while (count--)
00150 *(out++) = static_cast<C>(*(a++) * c);
00151 }
00152
00156 template <class T> double inner_product(const T* a, const T* b, size_t count) {
00157 double dot = 0;
00158 while (count--)
00159 dot += *(a++) * *(b++);
00160 return dot;
00161 }
00162
00163 template <class R, class D, class T> struct SumSquaredDifferences {
00164 static inline R sum_squared_differences(const T* a, const T* b, size_t count) {
00165 R ssd = 0;
00166 while (count--) {
00167 D d = *a++ - *b++;
00168 ssd += d*d;
00169 }
00170 return ssd;
00171 }
00172 };
00173
00174 template <class T1, class T2> inline void square(const T1* in, T2* out, size_t count)
00175 {
00176 while (count--) {
00177 *(out++) = static_cast<T2>(*in * *in);
00178 ++in;
00179 }
00180 }
00181
00182 template <class T1, class T2> inline void subtract_square(const T1* in, T2* out, size_t count)
00183 {
00184 while (count--) {
00185 *(out++) -= static_cast<T2>(*in * *in);
00186 ++in;
00187 }
00188 }
00189
00193 template <class T> inline double sum_squared_differences(const T* a, const T* b, size_t count) {
00194 return SumSquaredDifferences<double,double,T>::sum_squared_differences(a,b,count);
00195 }
00196
00198 template<int bytes> bool is_aligned(const void* ptr);
00199 template<> inline bool is_aligned<8>(const void* ptr) { return ((reinterpret_cast<size_t>(ptr)) & 0x7) == 0; }
00200 template<> inline bool is_aligned<16>(const void* ptr) { return ((reinterpret_cast<size_t>(ptr)) & 0xF) == 0; }
00201
00203 template<int A, class T> inline size_t steps_to_align(const T* ptr)
00204 {
00205 return is_aligned<A>(ptr) ? 0 : (A-((reinterpret_cast<size_t>(ptr)) & (A-1)))/sizeof(T);
00206 }
00207
00208 void differences(const byte* a, const byte* b, short* diff, unsigned int size);
00209 void differences(const short* a, const short* b, short* diff, unsigned int size);
00210
00211
00212 void differences(const float* a, const float* b, float* diff, size_t size);
00213 void add_multiple_of_sum(const float* a, const float* b, const float& c, float* out, size_t count);
00214 void assign_multiple(const float* a, const float& c, float* out, size_t count);
00215 double inner_product(const float* a, const float* b, size_t count);
00216 double sum_squared_differences(const float* a, const float* b, size_t count);
00217 void square(const float* in, float* out, size_t count);
00218 void subtract_square(const float* in, float* out, size_t count);
00219
00220 void differences(const int32_t* a, const int32_t* b, int32_t* diff, size_t size);
00221 void differences(const double* a, const double* b, double* diff, size_t size);
00222 void add_multiple_of_sum(const double* a, const double* b, const double& c, double* out, size_t count);
00223 void assign_multiple(const double* a, const double& c, double* out, size_t count);
00224 double inner_product(const double* a, const double* b, size_t count);
00225 double sum_squared_differences(const double* a, const double* b, size_t count);
00226 long long sum_squared_differences(const byte* a, const byte* b, size_t count);
00227
00228
00229 }
00230
00231 #endif