Update to 2.0.0 tree from current Fremantle build
[opencv] / src / cxcore / _cxcore.h
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #ifndef _CXCORE_INTERNAL_H_
44 #define _CXCORE_INTERNAL_H_
45
46 #if defined _MSC_VER && _MSC_VER >= 1200
47     /* disable warnings related to inline functions */
48     #pragma warning( disable: 4251 4711 4710 4514 )
49 #endif
50
51 typedef unsigned long ulong;
52
53 #ifdef __BORLANDC__
54 #ifndef WIN32
55     #define     WIN32
56 #endif
57     #define     CV_DLL
58 #endif
59
60 #include "cxcore.h"
61 #include "cxmisc.h"
62
63 #include <assert.h>
64 #include <ctype.h>
65 #include <float.h>
66 #include <limits.h>
67 #include <math.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71
72 #if defined WIN32 || defined _WIN32
73 #  ifndef WIN32
74 #    define WIN32
75 #  endif
76 #  ifndef _WIN32
77 #    define _WIN32
78 #  endif
79 #endif
80
81 #if defined WIN32 || defined WINCE
82 #ifndef _WIN32_WINNT         // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
83 #define _WIN32_WINNT 0x0400  // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
84 #endif
85 #include <windows.h>
86 #undef small
87 #undef min
88 #undef max
89 #else
90 #include <pthread.h>
91 #include <sys/mman.h>
92 #endif
93
94 #ifdef HAVE_CONFIG_H
95 #include <cvconfig.h>
96 #endif
97
98 #ifdef HAVE_IPP
99 #include "ipp.h"
100 #endif
101
102
103 #define CV_MEMCPY_CHAR( dst, src, len )                 \
104 {                                                       \
105     size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);    \
106     char* _icv_memcpy_dst_ = (char*)(dst);              \
107     const char* _icv_memcpy_src_ = (const char*)(src);  \
108                                                         \
109     for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \
110         _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];        \
111 }
112
113
114 #define CV_MEMCPY_INT( dst, src, len )                  \
115 {                                                       \
116     size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);    \
117     int* _icv_memcpy_dst_ = (int*)(dst);                \
118     const int* _icv_memcpy_src_ = (const int*)(src);    \
119     assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 && \
120     ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );  \
121                                                         \
122     for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)  \
123         _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];\
124 }
125
126
127 #define CV_MEMCPY_AUTO( dst, src, len )                                             \
128 {                                                                                   \
129     size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
130     char* _icv_memcpy_dst_ = (char*)(dst);                                          \
131     const char* _icv_memcpy_src_ = (const char*)(src);                              \
132     if( (_icv_memcpy_len_ & (sizeof(int)-1)) == 0 )                                 \
133     {                                                                               \
134         assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 &&                  \
135                 ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                  \
136         for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_;                 \
137             _icv_memcpy_i_+=sizeof(int) )                                           \
138         {                                                                           \
139             *(int*)(_icv_memcpy_dst_+_icv_memcpy_i_) =                              \
140             *(const int*)(_icv_memcpy_src_+_icv_memcpy_i_);                         \
141         }                                                                           \
142     }                                                                               \
143     else                                                                            \
144     {                                                                               \
145         for(_icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++)\
146             _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];    \
147     }                                                                               \
148 }
149
150
151 #define CV_ZERO_CHAR( dst, len )                        \
152 {                                                       \
153     size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);    \
154     char* _icv_memcpy_dst_ = (char*)(dst);              \
155                                                         \
156     for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \
157         _icv_memcpy_dst_[_icv_memcpy_i_] = '\0';        \
158 }
159
160
161 #define CV_ZERO_INT( dst, len )                                                     \
162 {                                                                                   \
163     size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
164     int* _icv_memcpy_dst_ = (int*)(dst);                                            \
165     assert( ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                      \
166                                                                                     \
167     for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)          \
168         _icv_memcpy_dst_[_icv_memcpy_i_] = 0;                                       \
169 }
170
171 namespace cv
172 {
173     
174 // -128.f ... 255.f
175 extern const float g_8x32fTab[];
176 #define CV_8TO32F(x)  cv::g_8x32fTab[(x)+128]
177
178 extern const ushort g_8x16uSqrTab[];
179 #define CV_SQR_8U(x)  cv::g_8x16uSqrTab[(x)+255]
180
181 extern const char* g_HersheyGlyphs[];
182
183 extern const signed char g_DepthToType[];
184 #define IplToCvDepth( depth ) \
185     cv::g_DepthToType[(((depth) & 255) >> 2) + ((depth) < 0)]
186
187 extern const uchar g_Saturate8u[];
188 #define CV_FAST_CAST_8U(t)   (assert(-256 <= (t) && (t) <= 512), cv::g_Saturate8u[(t)+256])
189 #define CV_MIN_8U(a,b)       ((a) - CV_FAST_CAST_8U((a) - (b)))
190 #define CV_MAX_8U(a,b)       ((a) + CV_FAST_CAST_8U((b) - (a)))
191
192 typedef void (*CopyMaskFunc)(const Mat& src, Mat& dst, const Mat& mask);
193
194 extern CopyMaskFunc g_copyMaskFuncTab[];
195
196 static inline CopyMaskFunc getCopyMaskFunc(int esz)
197 {
198     CV_Assert( (unsigned)esz <= 32U );
199     CopyMaskFunc func = g_copyMaskFuncTab[esz];
200     CV_Assert( func != 0 );
201     return func;
202 }
203
204 #if defined WIN32 || defined _WIN32
205 void deleteThreadAllocData();
206 void deleteThreadRNGData();
207 #endif
208
209 template<typename T1, typename T2=T1, typename T3=T1> struct OpAdd
210 {
211     typedef T1 type1;
212     typedef T2 type2;
213     typedef T3 rtype;
214     T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a + b); }
215 };
216
217 template<typename T1, typename T2=T1, typename T3=T1> struct OpSub
218 {
219     typedef T1 type1;
220     typedef T2 type2;
221     typedef T3 rtype;
222     T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a - b); }
223 };
224
225 template<typename T1, typename T2=T1, typename T3=T1> struct OpRSub
226 {
227     typedef T1 type1;
228     typedef T2 type2;
229     typedef T3 rtype;
230     T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(b - a); }
231 };
232
233 template<typename T1, typename T2=T1, typename T3=T1> struct OpMul
234 {
235     typedef T1 type1;
236     typedef T2 type2;
237     typedef T3 rtype;
238     T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a * b); }
239 };
240
241 template<typename T1, typename T2=T1, typename T3=T1> struct OpDiv
242 {
243     typedef T1 type1;
244     typedef T2 type2;
245     typedef T3 rtype;
246     T3 operator ()(T1 a, T2 b) const { return saturate_cast<T3>(a / b); }
247 };
248
249 template<typename T> struct OpMin
250 {
251     typedef T type1;
252     typedef T type2;
253     typedef T rtype;
254     T operator ()(T a, T b) const { return std::min(a, b); }
255 };
256
257 template<typename T> struct OpMax
258 {
259     typedef T type1;
260     typedef T type2;
261     typedef T rtype;
262     T operator ()(T a, T b) const { return std::max(a, b); }
263 };
264
265 static inline Size getContinuousSize( const Mat& m1, int widthScale=1 )
266 {
267     return m1.isContinuous() ? Size(m1.cols*m1.rows*widthScale, 1) :
268         Size(m1.cols*widthScale, m1.rows);
269 }
270
271 static inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 )
272 {
273     return (m1.flags & m2.flags & Mat::CONTINUOUS_FLAG) != 0 ?
274         Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows);
275 }
276
277 static inline Size getContinuousSize( const Mat& m1, const Mat& m2,
278                                       const Mat& m3, int widthScale=1 )
279 {
280     return (m1.flags & m2.flags & m3.flags & Mat::CONTINUOUS_FLAG) != 0 ?
281         Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows);
282 }
283
284 static inline Size getContinuousSize( const Mat& m1, const Mat& m2,
285                                       const Mat& m3, const Mat& m4,
286                                       int widthScale=1 )
287 {
288     return (m1.flags & m2.flags & m3.flags & m4.flags & Mat::CONTINUOUS_FLAG) != 0 ?
289         Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows);
290 }
291
292 static inline Size getContinuousSize( const Mat& m1, const Mat& m2,
293                                       const Mat& m3, const Mat& m4,
294                                       const Mat& m5, int widthScale=1 )
295 {
296     return (m1.flags & m2.flags & m3.flags & m4.flags & m5.flags & Mat::CONTINUOUS_FLAG) != 0 ?
297         Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows);
298 }
299
300 struct NoVec
301 {
302     int operator()(const void*, const void*, void*, int) const { return 0; }
303 };
304
305 template<class Op, class VecOp> static void
306 binaryOpC1_( const Mat& srcmat1, const Mat& srcmat2, Mat& dstmat )
307 {
308     Op op; VecOp vecOp;
309     typedef typename Op::type1 T1;
310     typedef typename Op::type2 T2;
311     typedef typename Op::rtype DT;
312
313     const T1* src1 = (const T1*)srcmat1.data;
314     const T2* src2 = (const T2*)srcmat2.data;
315     DT* dst = (DT*)dstmat.data;
316     size_t step1 = srcmat1.step/sizeof(src1[0]);
317     size_t step2 = srcmat2.step/sizeof(src2[0]);
318     size_t step = dstmat.step/sizeof(dst[0]);
319     Size size = getContinuousSize( srcmat1, srcmat2, dstmat, dstmat.channels() );
320
321     if( size.width == 1 )
322     {
323         for( ; size.height--; src1 += step1, src2 += step2, dst += step )
324             dst[0] = op( src1[0], src2[0] );
325         return;
326     }
327
328     for( ; size.height--; src1 += step1, src2 += step2, dst += step )
329     {
330         int x = vecOp(src1, src2, dst, size.width);
331         for( ; x <= size.width - 4; x += 4 )
332         {
333             DT f0, f1;
334             f0 = op( src1[x], src2[x] );
335             f1 = op( src1[x+1], src2[x+1] );
336             dst[x] = f0;
337             dst[x+1] = f1;
338             f0 = op(src1[x+2], src2[x+2]);
339             f1 = op(src1[x+3], src2[x+3]);
340             dst[x+2] = f0;
341             dst[x+3] = f1;
342         }
343
344         for( ; x < size.width; x++ )
345             dst[x] = op( src1[x], src2[x] );
346     }
347 }
348
349 typedef void (*BinaryFunc)(const Mat& src1, const Mat& src2, Mat& dst);
350
351 template<class Op> static void
352 binarySOpCn_( const Mat& srcmat, Mat& dstmat, const Scalar& _scalar )
353 {
354     Op op;
355     typedef typename Op::type1 T;
356     typedef typename Op::type2 WT;
357     typedef typename Op::rtype DT;
358     const T* src0 = (const T*)srcmat.data;
359     DT* dst0 = (DT*)dstmat.data;
360     size_t step1 = srcmat.step/sizeof(src0[0]);
361     size_t step = dstmat.step/sizeof(dst0[0]);
362     int cn = dstmat.channels();
363     Size size = getContinuousSize( srcmat, dstmat, cn );
364     WT scalar[12];
365     _scalar.convertTo(scalar, cn, 12);
366
367     for( ; size.height--; src0 += step1, dst0 += step )
368     {
369         int i, len = size.width;
370         const T* src = src0;
371         T* dst = dst0;
372
373         for( ; (len -= 12) >= 0; dst += 12, src += 12 )
374         {
375             DT t0 = op(src[0], scalar[0]);
376             DT t1 = op(src[1], scalar[1]);
377             dst[0] = t0; dst[1] = t1;
378
379             t0 = op(src[2], scalar[2]);
380             t1 = op(src[3], scalar[3]);
381             dst[2] = t0; dst[3] = t1;
382
383             t0 = op(src[4], scalar[4]);
384             t1 = op(src[5], scalar[5]);
385             dst[4] = t0; dst[5] = t1;
386
387             t0 = op(src[6], scalar[6]);
388             t1 = op(src[7], scalar[7]);
389             dst[6] = t0; dst[7] = t1;
390
391             t0 = op(src[8], scalar[8]);
392             t1 = op(src[9], scalar[9]);
393             dst[8] = t0; dst[9] = t1;
394
395             t0 = op(src[10], scalar[10]);
396             t1 = op(src[11], scalar[11]);
397             dst[10] = t0; dst[11] = t1;
398         }
399
400         for( (len) += 12, i = 0; i < (len); i++ )
401             dst[i] = op((WT)src[i], scalar[i]);
402     }
403 }
404
405 template<class Op> static void
406 binarySOpC1_( const Mat& srcmat, Mat& dstmat, double _scalar )
407 {
408     Op op;
409     typedef typename Op::type1 T;
410     typedef typename Op::type2 WT;
411     typedef typename Op::rtype DT;
412     WT scalar = saturate_cast<WT>(_scalar);
413     const T* src = (const T*)srcmat.data;
414     DT* dst = (DT*)dstmat.data;
415     size_t step1 = srcmat.step/sizeof(src[0]);
416     size_t step = dstmat.step/sizeof(dst[0]);
417     Size size = srcmat.size();
418     
419     size.width *= srcmat.channels();
420     if( srcmat.isContinuous() && dstmat.isContinuous() )
421     {
422         size.width *= size.height;
423         size.height = 1;
424     }
425
426     for( ; size.height--; src += step1, dst += step )
427     {
428         int x;
429         for( x = 0; x <= size.width - 4; x += 4 )
430         {
431             DT f0 = op( src[x], scalar );
432             DT f1 = op( src[x+1], scalar );
433             dst[x] = f0;
434             dst[x+1] = f1;
435             f0 = op( src[x+2], scalar );
436             f1 = op( src[x+3], scalar );
437             dst[x+2] = f0;
438             dst[x+3] = f1;
439         }
440
441         for( ; x < size.width; x++ )
442             dst[x] = op( src[x], scalar );
443     }
444 }
445
446 typedef void (*BinarySFuncCn)(const Mat& src1, Mat& dst, const Scalar& scalar);
447 typedef void (*BinarySFuncC1)(const Mat& src1, Mat& dst, double scalar);
448
449 }
450
451 #endif /*_CXCORE_INTERNAL_H_*/