e4a232a1dfe8f76bf05cd1f285dedf2babcd7211
[profile/ivi/opencv.git] / modules / core / include / opencv2 / core / private.hpp
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 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16 // Third party copyrights are property of their respective owners.
17 //
18 // Redistribution and use in source and binary forms, with or without modification,
19 // are permitted provided that the following conditions are met:
20 //
21 //   * Redistribution's of source code must retain the above copyright notice,
22 //     this list of conditions and the following disclaimer.
23 //
24 //   * Redistribution's in binary form must reproduce the above copyright notice,
25 //     this list of conditions and the following disclaimer in the documentation
26 //     and/or other materials provided with the distribution.
27 //
28 //   * The name of the copyright holders may not be used to endorse or promote products
29 //     derived from this software without specific prior written permission.
30 //
31 // This software is provided by the copyright holders and contributors "as is" and
32 // any express or implied warranties, including, but not limited to, the implied
33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
34 // In no event shall the Intel Corporation or contributors be liable for any direct,
35 // indirect, incidental, special, exemplary, or consequential damages
36 // (including, but not limited to, procurement of substitute goods or services;
37 // loss of use, data, or profits; or business interruption) however caused
38 // and on any theory of liability, whether in contract, strict liability,
39 // or tort (including negligence or otherwise) arising in any way out of
40 // the use of this software, even if advised of the possibility of such damage.
41 //
42 //M*/
43
44 #ifndef __OPENCV_CORE_PRIVATE_HPP__
45 #define __OPENCV_CORE_PRIVATE_HPP__
46
47 #ifndef __OPENCV_BUILD
48 #  error this is a private header which should not be used from outside of the OpenCV library
49 #endif
50
51 #include "opencv2/core.hpp"
52 #include "cvconfig.h"
53
54 #ifdef HAVE_EIGEN
55 #  if defined __GNUC__ && defined __APPLE__
56 #    pragma GCC diagnostic ignored "-Wshadow"
57 #  endif
58 #  include <Eigen/Core>
59 #  include "opencv2/core/eigen.hpp"
60 #endif
61
62 #ifdef HAVE_TBB
63 #  include "tbb/tbb_stddef.h"
64 #  if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202
65 #    include "tbb/tbb.h"
66 #    include "tbb/task.h"
67 #    undef min
68 #    undef max
69 #  else
70 #    undef HAVE_TBB
71 #  endif
72 #endif
73
74 namespace cv
75 {
76 #ifdef HAVE_TBB
77
78     typedef tbb::blocked_range<int> BlockedRange;
79
80     template<typename Body> static inline
81     void parallel_for( const BlockedRange& range, const Body& body )
82     {
83         tbb::parallel_for(range, body);
84     }
85
86     typedef tbb::split Split;
87
88     template<typename Body> static inline
89     void parallel_reduce( const BlockedRange& range, Body& body )
90     {
91         tbb::parallel_reduce(range, body);
92     }
93
94     typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
95 #else
96     class BlockedRange
97     {
98     public:
99         BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
100         BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
101         int begin() const { return _begin; }
102         int end() const { return _end; }
103         int grainsize() const { return _grainsize; }
104
105     protected:
106         int _begin, _end, _grainsize;
107     };
108
109     template<typename Body> static inline
110     void parallel_for( const BlockedRange& range, const Body& body )
111     {
112         body(range);
113     }
114     typedef std::vector<Rect> ConcurrentRectVector;
115
116     class Split {};
117
118     template<typename Body> static inline
119     void parallel_reduce( const BlockedRange& range, Body& body )
120     {
121         body(range);
122     }
123 #endif
124
125     // Returns a static string if there is a parallel framework,
126     // NULL otherwise.
127     CV_EXPORTS const char* currentParallelFramework();
128 } //namespace cv
129
130 #define CV_INIT_ALGORITHM(classname, algname, memberinit) \
131     static inline ::cv::Algorithm* create##classname##_hidden() \
132     { \
133         return new classname; \
134     } \
135     \
136     static inline ::cv::Ptr< ::cv::Algorithm> create##classname##_ptr_hidden() \
137     { \
138         return ::cv::makePtr<classname>(); \
139     } \
140     \
141     static inline ::cv::AlgorithmInfo& classname##_info() \
142     { \
143         static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname##_hidden); \
144         return classname##_info_var; \
145     } \
146     \
147     static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \
148     \
149     ::cv::AlgorithmInfo* classname::info() const \
150     { \
151         static volatile bool initialized = false; \
152         \
153         if( !initialized ) \
154         { \
155             initialized = true; \
156             classname obj; \
157             memberinit; \
158         } \
159         return &classname##_info(); \
160     }
161
162
163
164 /****************************************************************************************\
165 *                                  Common declarations                                   *
166 \****************************************************************************************/
167
168 /* the alignment of all the allocated buffers */
169 #define  CV_MALLOC_ALIGN    16
170
171 #ifdef __GNUC__
172 #  define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
173 #elif defined _MSC_VER
174 #  define CV_DECL_ALIGNED(x) __declspec(align(x))
175 #else
176 #  define CV_DECL_ALIGNED(x)
177 #endif
178
179 /* IEEE754 constants and macros */
180 #define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
181 #define  CV_TOGGLE_DBL(x) ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))
182
183 static inline void* cvAlignPtr( const void* ptr, int align = 32 )
184 {
185     CV_DbgAssert ( (align & (align-1)) == 0 );
186     return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
187 }
188
189 static inline int cvAlign( int size, int align )
190 {
191     CV_DbgAssert( (align & (align-1)) == 0 && size < INT_MAX );
192     return (size + align - 1) & -align;
193 }
194
195 #ifdef IPL_DEPTH_8U
196 static inline cv::Size cvGetMatSize( const CvMat* mat )
197 {
198     return cv::Size(mat->cols, mat->rows);
199 }
200 #endif
201
202 namespace cv
203 {
204 CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
205 }
206
207
208 /****************************************************************************************\
209 *                     Structures and macros for integration with IPP                     *
210 \****************************************************************************************/
211
212 #ifdef HAVE_IPP
213 #  include "ipp.h"
214
215 #  define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR)
216
217 #define IPP_ALIGN 32 // required for AVX optimization
218
219 #define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
220
221 static inline IppiSize ippiSize(int width, int height)
222 {
223     IppiSize size = { width, height };
224     return size;
225 }
226
227 static inline IppiSize ippiSize(const cv::Size & _size)
228 {
229     IppiSize size = { _size.width, _size.height };
230     return size;
231 }
232
233 static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
234 {
235     return borderTypeNI == cv::BORDER_CONSTANT ? ippBorderConst :
236         borderTypeNI == cv::BORDER_WRAP ? ippBorderWrap :
237         borderTypeNI == cv::BORDER_REPLICATE ? ippBorderRepl :
238         borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror :
239         borderTypeNI == cv::BORDER_REFLECT ? ippBorderMirrorR : (IppiBorderType)-1;
240 }
241
242 static inline IppDataType ippiGetDataType(int depth)
243 {
244     return depth == CV_8U ? ipp8u :
245         depth == CV_8S ? ipp8s :
246         depth == CV_16U ? ipp16u :
247         depth == CV_16S ? ipp16s :
248         depth == CV_32S ? ipp32s :
249         depth == CV_32F ? ipp32f :
250         depth == CV_64F ? ipp64f : (IppDataType)-1;
251 }
252
253 #else
254 #  define IPP_VERSION_X100 0
255 #endif
256
257 #define CV_IPP_CHECK_COND (cv::ipp::useIPP())
258 #define CV_IPP_CHECK() if(CV_IPP_CHECK_COND)
259
260 #ifndef IPPI_CALL
261 #  define IPPI_CALL(func) CV_Assert((func) >= 0)
262 #endif
263
264 /* IPP-compatible return codes */
265 typedef enum CvStatus
266 {
267     CV_BADMEMBLOCK_ERR          = -113,
268     CV_INPLACE_NOT_SUPPORTED_ERR= -112,
269     CV_UNMATCHED_ROI_ERR        = -111,
270     CV_NOTFOUND_ERR             = -110,
271     CV_BADCONVERGENCE_ERR       = -109,
272
273     CV_BADDEPTH_ERR             = -107,
274     CV_BADROI_ERR               = -106,
275     CV_BADHEADER_ERR            = -105,
276     CV_UNMATCHED_FORMATS_ERR    = -104,
277     CV_UNSUPPORTED_COI_ERR      = -103,
278     CV_UNSUPPORTED_CHANNELS_ERR = -102,
279     CV_UNSUPPORTED_DEPTH_ERR    = -101,
280     CV_UNSUPPORTED_FORMAT_ERR   = -100,
281
282     CV_BADARG_ERR               = -49,  //ipp comp
283     CV_NOTDEFINED_ERR           = -48,  //ipp comp
284
285     CV_BADCHANNELS_ERR          = -47,  //ipp comp
286     CV_BADRANGE_ERR             = -44,  //ipp comp
287     CV_BADSTEP_ERR              = -29,  //ipp comp
288
289     CV_BADFLAG_ERR              =  -12,
290     CV_DIV_BY_ZERO_ERR          =  -11, //ipp comp
291     CV_BADCOEF_ERR              =  -10,
292
293     CV_BADFACTOR_ERR            =  -7,
294     CV_BADPOINT_ERR             =  -6,
295     CV_BADSCALE_ERR             =  -4,
296     CV_OUTOFMEM_ERR             =  -3,
297     CV_NULLPTR_ERR              =  -2,
298     CV_BADSIZE_ERR              =  -1,
299     CV_NO_ERR                   =   0,
300     CV_OK                       =   CV_NO_ERR
301 }
302 CvStatus;
303
304
305
306 /****************************************************************************************\
307 *                                  Auxiliary algorithms                                  *
308 \****************************************************************************************/
309
310 namespace cv
311 {
312
313 // This function splits the input sequence or set into one or more equivalence classes and
314 // returns the vector of labels - 0-based class indexes for each element.
315 // predicate(a,b) returns true if the two sequence elements certainly belong to the same class.
316 //
317 // The algorithm is described in "Introduction to Algorithms"
318 // by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets"
319 template<typename _Tp, class _EqPredicate> int
320 partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
321            _EqPredicate predicate=_EqPredicate())
322 {
323     int i, j, N = (int)_vec.size();
324     const _Tp* vec = &_vec[0];
325
326     const int PARENT=0;
327     const int RANK=1;
328
329     std::vector<int> _nodes(N*2);
330     int (*nodes)[2] = (int(*)[2])&_nodes[0];
331
332     // The first O(N) pass: create N single-vertex trees
333     for(i = 0; i < N; i++)
334     {
335         nodes[i][PARENT]=-1;
336         nodes[i][RANK] = 0;
337     }
338
339     // The main O(N^2) pass: merge connected components
340     for( i = 0; i < N; i++ )
341     {
342         int root = i;
343
344         // find root
345         while( nodes[root][PARENT] >= 0 )
346             root = nodes[root][PARENT];
347
348         for( j = 0; j < N; j++ )
349         {
350             if( i == j || !predicate(vec[i], vec[j]))
351                 continue;
352             int root2 = j;
353
354             while( nodes[root2][PARENT] >= 0 )
355                 root2 = nodes[root2][PARENT];
356
357             if( root2 != root )
358             {
359                 // unite both trees
360                 int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
361                 if( rank > rank2 )
362                     nodes[root2][PARENT] = root;
363                 else
364                 {
365                     nodes[root][PARENT] = root2;
366                     nodes[root2][RANK] += rank == rank2;
367                     root = root2;
368                 }
369                 CV_Assert( nodes[root][PARENT] < 0 );
370
371                 int k = j, parent;
372
373                 // compress the path from node2 to root
374                 while( (parent = nodes[k][PARENT]) >= 0 )
375                 {
376                     nodes[k][PARENT] = root;
377                     k = parent;
378                 }
379
380                 // compress the path from node to root
381                 k = i;
382                 while( (parent = nodes[k][PARENT]) >= 0 )
383                 {
384                     nodes[k][PARENT] = root;
385                     k = parent;
386                 }
387             }
388         }
389     }
390
391     // Final O(N) pass: enumerate classes
392     labels.resize(N);
393     int nclasses = 0;
394
395     for( i = 0; i < N; i++ )
396     {
397         int root = i;
398         while( nodes[root][PARENT] >= 0 )
399             root = nodes[root][PARENT];
400         // re-use the rank as the class label
401         if( nodes[root][RANK] >= 0 )
402             nodes[root][RANK] = ~nclasses++;
403         labels[i] = ~nodes[root][RANK];
404     }
405
406     return nclasses;
407 }
408
409 } // namespace cv
410
411 #endif // __OPENCV_CORE_PRIVATE_HPP__