include/opencv2/core/internal.hpp
Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 /* The header is for internal use and it is likely to change.
00044    It contains some macro definitions that are used in cxcore, cv, cvaux
00045    and, probably, other libraries. If you need some of this functionality,
00046    the safe way is to copy it into your code and rename the macros.
00047 */
00048 #ifndef __OPENCV_CORE_INTERNAL_HPP__
00049 #define __OPENCV_CORE_INTERNAL_HPP__
00050 
00051 #include <vector>
00052 
00053 #if defined WIN32 || defined _WIN32
00054 #  ifndef WIN32
00055 #    define WIN32
00056 #  endif
00057 #  ifndef _WIN32
00058 #    define _WIN32
00059 #  endif
00060 #endif
00061 
00062 #if !defined WIN32 && !defined WINCE
00063 #  include <pthread.h>
00064 #endif
00065 
00066 #ifdef __BORLANDC__
00067 #  ifndef WIN32
00068 #    define WIN32
00069 #  endif
00070 #  ifndef _WIN32
00071 #    define _WIN32
00072 #  endif
00073 #  define CV_DLL
00074 #  undef _CV_ALWAYS_PROFILE_
00075 #  define _CV_ALWAYS_NO_PROFILE_
00076 #endif
00077 
00078 #ifndef FALSE
00079 #  define FALSE 0
00080 #endif
00081 #ifndef TRUE
00082 #  define TRUE 1
00083 #endif
00084 
00085 #define __BEGIN__ __CV_BEGIN__
00086 #define __END__ __CV_END__
00087 #define EXIT __CV_EXIT__
00088 
00089 #ifdef HAVE_IPP
00090 #  include "ipp.h"
00091 
00092 CV_INLINE IppiSize ippiSize(int width, int height)
00093 {
00094     IppiSize size = { width, height };
00095     return size;
00096 }
00097 #endif
00098 
00099 #ifndef IPPI_CALL
00100 #  define IPPI_CALL(func) CV_Assert((func) >= 0)
00101 #endif
00102 
00103 #if defined __SSE2__ || defined _M_X64  || (defined _M_IX86_FP && _M_IX86_FP >= 2)
00104 #  include "emmintrin.h"
00105 #  define CV_SSE 1
00106 #  define CV_SSE2 1
00107 #  if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
00108 #    include "pmmintrin.h"
00109 #    define CV_SSE3 1
00110 #  endif
00111 #  if defined __SSSE3__  || (defined _MSC_VER && _MSC_VER >= 1500)
00112 #    include "tmmintrin.h"
00113 #    define CV_SSSE3 1
00114 #  endif
00115 #  if defined __SSE4_1__ || (defined _MSC_VER && _MSC_VER >= 1500)
00116 #    include <smmintrin.h>
00117 #    define CV_SSE4_1 1
00118 #  endif
00119 #  if defined __SSE4_2__ || (defined _MSC_VER && _MSC_VER >= 1500)
00120 #    include <nmmintrin.h>
00121 #    define CV_SSE4_2 1
00122 #  endif
00123 #  if defined __AVX__ || (defined _MSC_FULL_VER && _MSC_FULL_VER >= 160040219)
00124 // MS Visual Studio 2010 (2012?) has no macro pre-defined to identify the use of /arch:AVX
00125 // See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32
00126 #    include <immintrin.h>
00127 #    define CV_AVX 1
00128 #    if defined(_XCR_XFEATURE_ENABLED_MASK)
00129 #      define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
00130 #    else
00131 #      define __xgetbv() 0
00132 #    endif
00133 #  endif
00134 #endif
00135 
00136 #ifdef __ARM_NEON__
00137 #  include <arm_neon.h>
00138 #  define CV_NEON 1
00139 #  define CPU_HAS_NEON_FEATURE (true)
00140 #endif
00141 
00142 #ifndef CV_SSE
00143 #  define CV_SSE 0
00144 #endif
00145 #ifndef CV_SSE2
00146 #  define CV_SSE2 0
00147 #endif
00148 #ifndef CV_SSE3
00149 #  define CV_SSE3 0
00150 #endif
00151 #ifndef CV_SSSE3
00152 #  define CV_SSSE3 0
00153 #endif
00154 #ifndef CV_SSE4_1
00155 #  define CV_SSE4_1 0
00156 #endif
00157 #ifndef CV_SSE4_2
00158 #  define CV_SSE4_2 0
00159 #endif
00160 #ifndef CV_AVX
00161 #  define CV_AVX 0
00162 #endif
00163 #ifndef CV_NEON
00164 #  define CV_NEON 0
00165 #endif
00166 
00167 #ifdef HAVE_TBB
00168 #  include "tbb/tbb_stddef.h"
00169 #  if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202
00170 #    include "tbb/tbb.h"
00171 #    include "tbb/task.h"
00172 #    undef min
00173 #    undef max
00174 #  else
00175 #    undef HAVE_TBB
00176 #  endif
00177 #endif
00178 
00179 #ifdef HAVE_EIGEN
00180 #  if defined __GNUC__ && defined __APPLE__
00181 #    pragma GCC diagnostic ignored "-Wshadow"
00182 #  endif
00183 #  include <Eigen/Core>
00184 #  include "opencv2/core/eigen.hpp"
00185 #endif
00186 
00187 #ifdef __cplusplus
00188 
00189 namespace cv
00190 {
00191 #ifdef HAVE_TBB
00192 
00193     typedef tbb::blocked_range<int> BlockedRange;
00194 
00195     template<typename Body> static inline
00196     void parallel_for( const BlockedRange& range, const Body& body )
00197     {
00198         tbb::parallel_for(range, body);
00199     }
00200 
00201     template<typename Iterator, typename Body> static inline
00202     void parallel_do( Iterator first, Iterator last, const Body& body )
00203     {
00204         tbb::parallel_do(first, last, body);
00205     }
00206 
00207     typedef tbb::split Split;
00208 
00209     template<typename Body> static inline
00210     void parallel_reduce( const BlockedRange& range, Body& body )
00211     {
00212         tbb::parallel_reduce(range, body);
00213     }
00214 
00215     typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
00216     typedef tbb::concurrent_vector<double> ConcurrentDoubleVector;
00217 #else
00218     class BlockedRange
00219     {
00220     public:
00221         BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
00222         BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
00223         int begin() const { return _begin; }
00224         int end() const { return _end; }
00225         int grainsize() const { return _grainsize; }
00226 
00227     protected:
00228         int _begin, _end, _grainsize;
00229     };
00230 
00231     template<typename Body> static inline
00232     void parallel_for( const BlockedRange& range, const Body& body )
00233     {
00234         body(range);
00235     }
00236     typedef std::vector<Rect> ConcurrentRectVector;
00237     typedef std::vector<double> ConcurrentDoubleVector;
00238 
00239     template<typename Iterator, typename Body> static inline
00240     void parallel_do( Iterator first, Iterator last, const Body& body )
00241     {
00242         for( ; first != last; ++first )
00243             body(*first);
00244     }
00245 
00246     class Split {};
00247 
00248     template<typename Body> static inline
00249     void parallel_reduce( const BlockedRange& range, Body& body )
00250     {
00251         body(range);
00252     }
00253 #endif
00254 } //namespace cv
00255 
00256 #define CV_INIT_ALGORITHM(classname, algname, memberinit) \
00257     static ::cv::Algorithm* create##classname() \
00258     { \
00259         return new classname; \
00260     } \
00261     \
00262     static ::cv::AlgorithmInfo& classname##_info() \
00263     { \
00264         static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname); \
00265         return classname##_info_var; \
00266     } \
00267     \
00268     static ::cv::AlgorithmInfo& classname##_info_auto = classname##_info(); \
00269     \
00270     ::cv::AlgorithmInfo* classname::info() const \
00271     { \
00272         static volatile bool initialized = false; \
00273         \
00274         if( !initialized ) \
00275         { \
00276             initialized = true; \
00277             classname obj; \
00278             memberinit; \
00279         } \
00280         return &classname##_info(); \
00281     }
00282 
00283 #endif //__cplusplus
00284 
00285 /* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */
00286 #define  CV_MAX_INLINE_MAT_OP_SIZE  10
00287 
00288 /* maximal linear size of matrix to allocate it on stack. */
00289 #define  CV_MAX_LOCAL_MAT_SIZE  32
00290 
00291 /* maximal size of local memory storage */
00292 #define  CV_MAX_LOCAL_SIZE  \
00293     (CV_MAX_LOCAL_MAT_SIZE*CV_MAX_LOCAL_MAT_SIZE*(int)sizeof(double))
00294 
00295 /* default image row align (in bytes) */
00296 #define  CV_DEFAULT_IMAGE_ROW_ALIGN  4
00297 
00298 /* matrices are continuous by default */
00299 #define  CV_DEFAULT_MAT_ROW_ALIGN  1
00300 
00301 /* maximum size of dynamic memory buffer.
00302    cvAlloc reports an error if a larger block is requested. */
00303 #define  CV_MAX_ALLOC_SIZE    (((size_t)1 << (sizeof(size_t)*8-2)))
00304 
00305 /* the alignment of all the allocated buffers */
00306 #define  CV_MALLOC_ALIGN    16
00307 
00308 /* default alignment for dynamic data strucutures, resided in storages. */
00309 #define  CV_STRUCT_ALIGN    ((int)sizeof(double))
00310 
00311 /* default storage block size */
00312 #define  CV_STORAGE_BLOCK_SIZE   ((1<<16) - 128)
00313 
00314 /* default memory block for sparse array elements */
00315 #define  CV_SPARSE_MAT_BLOCK    (1<<12)
00316 
00317 /* initial hash table size */
00318 #define  CV_SPARSE_HASH_SIZE0    (1<<10)
00319 
00320 /* maximal average node_count/hash_size ratio beyond which hash table is resized */
00321 #define  CV_SPARSE_HASH_RATIO    3
00322 
00323 /* max length of strings */
00324 #define  CV_MAX_STRLEN  1024
00325 
00326 #if 0 /*def  CV_CHECK_FOR_NANS*/
00327 #  define CV_CHECK_NANS( arr ) cvCheckArray((arr))
00328 #else
00329 #  define CV_CHECK_NANS( arr )
00330 #endif
00331 
00332 /****************************************************************************************\
00333 *                                  Common declarations                                   *
00334 \****************************************************************************************/
00335 
00336 /* get alloca declaration */
00337 #ifdef __GNUC__
00338 #  undef alloca
00339 #  define alloca __builtin_alloca
00340 #  define CV_HAVE_ALLOCA 1
00341 #elif defined WIN32 || defined _WIN32 || \
00342       defined WINCE || defined _MSC_VER || defined __BORLANDC__
00343 #  include <malloc.h>
00344 #  define CV_HAVE_ALLOCA 1
00345 #elif defined HAVE_ALLOCA_H
00346 #  include <alloca.h>
00347 #  define CV_HAVE_ALLOCA 1
00348 #elif defined HAVE_ALLOCA
00349 #  include <stdlib.h>
00350 #  define CV_HAVE_ALLOCA 1
00351 #else
00352 #  undef CV_HAVE_ALLOCA
00353 #endif
00354 
00355 #ifdef __GNUC__
00356 #  define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
00357 #elif defined _MSC_VER
00358 #  define CV_DECL_ALIGNED(x) __declspec(align(x))
00359 #else
00360 #  define CV_DECL_ALIGNED(x)
00361 #endif
00362 
00363 #if CV_HAVE_ALLOCA
00364 /* ! DO NOT make it an inline function */
00365 #  define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN )
00366 #endif
00367 
00368 #ifndef CV_IMPL
00369 #  define CV_IMPL CV_EXTERN_C
00370 #endif
00371 
00372 #define CV_DBG_BREAK() { volatile int* crashMe = 0; *crashMe = 0; }
00373 
00374 /* default step, set in case of continuous data
00375    to work around checks for valid step in some ipp functions */
00376 #define  CV_STUB_STEP     (1 << 30)
00377 
00378 #define  CV_SIZEOF_FLOAT ((int)sizeof(float))
00379 #define  CV_SIZEOF_SHORT ((int)sizeof(short))
00380 
00381 #define  CV_ORIGIN_TL  0
00382 #define  CV_ORIGIN_BL  1
00383 
00384 /* IEEE754 constants and macros */
00385 #define  CV_POS_INF       0x7f800000
00386 #define  CV_NEG_INF       0x807fffff /* CV_TOGGLE_FLT(0xff800000) */
00387 #define  CV_1F            0x3f800000
00388 #define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
00389 #define  CV_TOGGLE_DBL(x) \
00390     ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))
00391 
00392 #define  CV_NOP(a)      (a)
00393 #define  CV_ADD(a, b)   ((a) + (b))
00394 #define  CV_SUB(a, b)   ((a) - (b))
00395 #define  CV_MUL(a, b)   ((a) * (b))
00396 #define  CV_AND(a, b)   ((a) & (b))
00397 #define  CV_OR(a, b)    ((a) | (b))
00398 #define  CV_XOR(a, b)   ((a) ^ (b))
00399 #define  CV_ANDN(a, b)  (~(a) & (b))
00400 #define  CV_ORN(a, b)   (~(a) | (b))
00401 #define  CV_SQR(a)      ((a) * (a))
00402 
00403 #define  CV_LT(a, b)    ((a) < (b))
00404 #define  CV_LE(a, b)    ((a) <= (b))
00405 #define  CV_EQ(a, b)    ((a) == (b))
00406 #define  CV_NE(a, b)    ((a) != (b))
00407 #define  CV_GT(a, b)    ((a) > (b))
00408 #define  CV_GE(a, b)    ((a) >= (b))
00409 
00410 #define  CV_NONZERO(a)      ((a) != 0)
00411 #define  CV_NONZERO_FLT(a)  (((a)+(a)) != 0)
00412 
00413 /* general-purpose saturation macros */
00414 #define  CV_CAST_8U(t)  (uchar)(!((t) & ~255) ? (t) : (t) > 0 ? 255 : 0)
00415 #define  CV_CAST_8S(t)  (schar)(!(((t)+128) & ~255) ? (t) : (t) > 0 ? 127 : -128)
00416 #define  CV_CAST_16U(t) (ushort)(!((t) & ~65535) ? (t) : (t) > 0 ? 65535 : 0)
00417 #define  CV_CAST_16S(t) (short)(!(((t)+32768) & ~65535) ? (t) : (t) > 0 ? 32767 : -32768)
00418 #define  CV_CAST_32S(t) (int)(t)
00419 #define  CV_CAST_64S(t) (int64)(t)
00420 #define  CV_CAST_32F(t) (float)(t)
00421 #define  CV_CAST_64F(t) (double)(t)
00422 
00423 #define  CV_PASTE2(a,b) a##b
00424 #define  CV_PASTE(a,b)  CV_PASTE2(a,b)
00425 
00426 #define  CV_EMPTY
00427 #define  CV_MAKE_STR(a) #a
00428 
00429 #define  CV_ZERO_OBJ(x) memset((x), 0, sizeof(*(x)))
00430 
00431 #define  CV_DIM(static_array) ((int)(sizeof(static_array)/sizeof((static_array)[0])))
00432 
00433 #define  cvUnsupportedFormat "Unsupported format"
00434 
00435 CV_INLINE void* cvAlignPtr( const void* ptr, int align CV_DEFAULT(32) )
00436 {
00437     assert( (align & (align-1)) == 0 );
00438     return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
00439 }
00440 
00441 CV_INLINE int cvAlign( int size, int align )
00442 {
00443     assert( (align & (align-1)) == 0 && size < INT_MAX );
00444     return (size + align - 1) & -align;
00445 }
00446 
00447 CV_INLINE  CvSize  cvGetMatSize( const CvMat* mat )
00448 {
00449     CvSize size;
00450     size.width = mat->cols;
00451     size.height = mat->rows;
00452     return size;
00453 }
00454 
00455 #define  CV_DESCALE(x,n)     (((x) + (1 << ((n)-1))) >> (n))
00456 #define  CV_FLT_TO_FIX(x,n)  cvRound((x)*(1<<(n)))
00457 
00458 /****************************************************************************************\
00459 
00460   Generic implementation of QuickSort algorithm.
00461   ----------------------------------------------
00462   Using this macro user can declare customized sort function that can be much faster
00463   than built-in qsort function because of lower overhead on elements
00464   comparison and exchange. The macro takes less_than (or LT) argument - a macro or function
00465   that takes 2 arguments returns non-zero if the first argument should be before the second
00466   one in the sorted sequence and zero otherwise.
00467 
00468   Example:
00469 
00470     Suppose that the task is to sort points by ascending of y coordinates and if
00471     y's are equal x's should ascend.
00472 
00473     The code is:
00474     ------------------------------------------------------------------------------
00475            #define cmp_pts( pt1, pt2 ) \
00476                ((pt1).y < (pt2).y || ((pt1).y < (pt2).y && (pt1).x < (pt2).x))
00477 
00478            [static] CV_IMPLEMENT_QSORT( icvSortPoints, CvPoint, cmp_pts )
00479     ------------------------------------------------------------------------------
00480 
00481     After that the function "void icvSortPoints( CvPoint* array, size_t total, int aux );"
00482     is available to user.
00483 
00484   aux is an additional parameter, which can be used when comparing elements.
00485   The current implementation was derived from *BSD system qsort():
00486 
00487     * Copyright (c) 1992, 1993
00488     *  The Regents of the University of California.  All rights reserved.
00489     *
00490     * Redistribution and use in source and binary forms, with or without
00491     * modification, are permitted provided that the following conditions
00492     * are met:
00493     * 1. Redistributions of source code must retain the above copyright
00494     *    notice, this list of conditions and the following disclaimer.
00495     * 2. Redistributions in binary form must reproduce the above copyright
00496     *    notice, this list of conditions and the following disclaimer in the
00497     *    documentation and/or other materials provided with the distribution.
00498     * 3. All advertising materials mentioning features or use of this software
00499     *    must display the following acknowledgement:
00500     *  This product includes software developed by the University of
00501     *  California, Berkeley and its contributors.
00502     * 4. Neither the name of the University nor the names of its contributors
00503     *    may be used to endorse or promote products derived from this software
00504     *    without specific prior written permission.
00505     *
00506     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00507     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00508     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00509     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00510     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00511     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00512     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00513     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00514     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00515     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00516     * SUCH DAMAGE.
00517 
00518 \****************************************************************************************/
00519 
00520 #define CV_IMPLEMENT_QSORT_EX( func_name, T, LT, user_data_type )                   \
00521 void func_name( T *array, size_t total, user_data_type aux )                        \
00522 {                                                                                   \
00523     int isort_thresh = 7;                                                           \
00524     T t;                                                                            \
00525     int sp = 0;                                                                     \
00526                                                                                     \
00527     struct                                                                          \
00528     {                                                                               \
00529         T *lb;                                                                      \
00530         T *ub;                                                                      \
00531     }                                                                               \
00532     stack[48];                                                                      \
00533                                                                                     \
00534     aux = aux;                                                                      \
00535                                                                                     \
00536     if( total <= 1 )                                                                \
00537         return;                                                                     \
00538                                                                                     \
00539     stack[0].lb = array;                                                            \
00540     stack[0].ub = array + (total - 1);                                              \
00541                                                                                     \
00542     while( sp >= 0 )                                                                \
00543     {                                                                               \
00544         T* left = stack[sp].lb;                                                     \
00545         T* right = stack[sp--].ub;                                                  \
00546                                                                                     \
00547         for(;;)                                                                     \
00548         {                                                                           \
00549             int i, n = (int)(right - left) + 1, m;                                  \
00550             T* ptr;                                                                 \
00551             T* ptr2;                                                                \
00552                                                                                     \
00553             if( n <= isort_thresh )                                                 \
00554             {                                                                       \
00555             insert_sort:                                                            \
00556                 for( ptr = left + 1; ptr <= right; ptr++ )                          \
00557                 {                                                                   \
00558                     for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)   \
00559                         CV_SWAP( ptr2[0], ptr2[-1], t );                            \
00560                 }                                                                   \
00561                 break;                                                              \
00562             }                                                                       \
00563             else                                                                    \
00564             {                                                                       \
00565                 T* left0;                                                           \
00566                 T* left1;                                                           \
00567                 T* right0;                                                          \
00568                 T* right1;                                                          \
00569                 T* pivot;                                                           \
00570                 T* a;                                                               \
00571                 T* b;                                                               \
00572                 T* c;                                                               \
00573                 int swap_cnt = 0;                                                   \
00574                                                                                     \
00575                 left0 = left;                                                       \
00576                 right0 = right;                                                     \
00577                 pivot = left + (n/2);                                               \
00578                                                                                     \
00579                 if( n > 40 )                                                        \
00580                 {                                                                   \
00581                     int d = n / 8;                                                  \
00582                     a = left, b = left + d, c = left + 2*d;                         \
00583                     left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))     \
00584                                       : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \
00585                                                                                     \
00586                     a = pivot - d, b = pivot, c = pivot + d;                        \
00587                     pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))    \
00588                                       : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \
00589                                                                                     \
00590                     a = right - 2*d, b = right - d, c = right;                      \
00591                     right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))    \
00592                                       : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \
00593                 }                                                                   \
00594                                                                                     \
00595                 a = left, b = pivot, c = right;                                     \
00596                 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))        \
00597                                    : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));       \
00598                 if( pivot != left0 )                                                \
00599                 {                                                                   \
00600                     CV_SWAP( *pivot, *left0, t );                                   \
00601                     pivot = left0;                                                  \
00602                 }                                                                   \
00603                 left = left1 = left0 + 1;                                           \
00604                 right = right1 = right0;                                            \
00605                                                                                     \
00606                 for(;;)                                                             \
00607                 {                                                                   \
00608                     while( left <= right && !LT(*pivot, *left) )                    \
00609                     {                                                               \
00610                         if( !LT(*left, *pivot) )                                    \
00611                         {                                                           \
00612                             if( left > left1 )                                      \
00613                                 CV_SWAP( *left1, *left, t );                        \
00614                             swap_cnt = 1;                                           \
00615                             left1++;                                                \
00616                         }                                                           \
00617                         left++;                                                     \
00618                     }                                                               \
00619                                                                                     \
00620                     while( left <= right && !LT(*right, *pivot) )                   \
00621                     {                                                               \
00622                         if( !LT(*pivot, *right) )                                   \
00623                         {                                                           \
00624                             if( right < right1 )                                    \
00625                                 CV_SWAP( *right1, *right, t );                      \
00626                             swap_cnt = 1;                                           \
00627                             right1--;                                               \
00628                         }                                                           \
00629                         right--;                                                    \
00630                     }                                                               \
00631                                                                                     \
00632                     if( left > right )                                              \
00633                         break;                                                      \
00634                     CV_SWAP( *left, *right, t );                                    \
00635                     swap_cnt = 1;                                                   \
00636                     left++;                                                         \
00637                     right--;                                                        \
00638                 }                                                                   \
00639                                                                                     \
00640                 if( swap_cnt == 0 )                                                 \
00641                 {                                                                   \
00642                     left = left0, right = right0;                                   \
00643                     goto insert_sort;                                               \
00644                 }                                                                   \
00645                                                                                     \
00646                 n = MIN( (int)(left1 - left0), (int)(left - left1) );               \
00647                 for( i = 0; i < n; i++ )                                            \
00648                     CV_SWAP( left0[i], left[i-n], t );                              \
00649                                                                                     \
00650                 n = MIN( (int)(right0 - right1), (int)(right1 - right) );           \
00651                 for( i = 0; i < n; i++ )                                            \
00652                     CV_SWAP( left[i], right0[i-n+1], t );                           \
00653                 n = (int)(left - left1);                                            \
00654                 m = (int)(right1 - right);                                          \
00655                 if( n > 1 )                                                         \
00656                 {                                                                   \
00657                     if( m > 1 )                                                     \
00658                     {                                                               \
00659                         if( n > m )                                                 \
00660                         {                                                           \
00661                             stack[++sp].lb = left0;                                 \
00662                             stack[sp].ub = left0 + n - 1;                           \
00663                             left = right0 - m + 1, right = right0;                  \
00664                         }                                                           \
00665                         else                                                        \
00666                         {                                                           \
00667                             stack[++sp].lb = right0 - m + 1;                        \
00668                             stack[sp].ub = right0;                                  \
00669                             left = left0, right = left0 + n - 1;                    \
00670                         }                                                           \
00671                     }                                                               \
00672                     else                                                            \
00673                         left = left0, right = left0 + n - 1;                        \
00674                 }                                                                   \
00675                 else if( m > 1 )                                                    \
00676                     left = right0 - m + 1, right = right0;                          \
00677                 else                                                                \
00678                     break;                                                          \
00679             }                                                                       \
00680         }                                                                           \
00681     }                                                                               \
00682 }
00683 
00684 #define CV_IMPLEMENT_QSORT( func_name, T, cmp )  \
00685     CV_IMPLEMENT_QSORT_EX( func_name, T, cmp, int )
00686 
00687 /****************************************************************************************\
00688 *                     Structures and macros for integration with IPP                     *
00689 \****************************************************************************************/
00690 
00691 /* IPP-compatible return codes */
00692 typedef enum CvStatus
00693 {
00694     CV_BADMEMBLOCK_ERR          = -113,
00695     CV_INPLACE_NOT_SUPPORTED_ERR= -112,
00696     CV_UNMATCHED_ROI_ERR        = -111,
00697     CV_NOTFOUND_ERR             = -110,
00698     CV_BADCONVERGENCE_ERR       = -109,
00699 
00700     CV_BADDEPTH_ERR             = -107,
00701     CV_BADROI_ERR               = -106,
00702     CV_BADHEADER_ERR            = -105,
00703     CV_UNMATCHED_FORMATS_ERR    = -104,
00704     CV_UNSUPPORTED_COI_ERR      = -103,
00705     CV_UNSUPPORTED_CHANNELS_ERR = -102,
00706     CV_UNSUPPORTED_DEPTH_ERR    = -101,
00707     CV_UNSUPPORTED_FORMAT_ERR   = -100,
00708 
00709     CV_BADARG_ERR               = -49,  //ipp comp
00710     CV_NOTDEFINED_ERR           = -48,  //ipp comp
00711 
00712     CV_BADCHANNELS_ERR          = -47,  //ipp comp
00713     CV_BADRANGE_ERR             = -44,  //ipp comp
00714     CV_BADSTEP_ERR              = -29,  //ipp comp
00715 
00716     CV_BADFLAG_ERR              =  -12,
00717     CV_DIV_BY_ZERO_ERR          =  -11, //ipp comp
00718     CV_BADCOEF_ERR              =  -10,
00719 
00720     CV_BADFACTOR_ERR            =  -7,
00721     CV_BADPOINT_ERR             =  -6,
00722     CV_BADSCALE_ERR             =  -4,
00723     CV_OUTOFMEM_ERR             =  -3,
00724     CV_NULLPTR_ERR              =  -2,
00725     CV_BADSIZE_ERR              =  -1,
00726     CV_NO_ERR                   =   0,
00727     CV_OK                       =   CV_NO_ERR
00728 }
00729 CvStatus;
00730 
00731 #define CV_NOTHROW throw()
00732 
00733 typedef struct CvFuncTable
00734 {
00735     void*   fn_2d[CV_DEPTH_MAX];
00736 }
00737 CvFuncTable;
00738 
00739 typedef struct CvBigFuncTable
00740 {
00741     void*   fn_2d[CV_DEPTH_MAX*4];
00742 } CvBigFuncTable;
00743 
00744 #define CV_INIT_FUNC_TAB( tab, FUNCNAME, FLAG )         \
00745     (tab).fn_2d[CV_8U] = (void*)FUNCNAME##_8u##FLAG;    \
00746     (tab).fn_2d[CV_8S] = 0;                             \
00747     (tab).fn_2d[CV_16U] = (void*)FUNCNAME##_16u##FLAG;  \
00748     (tab).fn_2d[CV_16S] = (void*)FUNCNAME##_16s##FLAG;  \
00749     (tab).fn_2d[CV_32S] = (void*)FUNCNAME##_32s##FLAG;  \
00750     (tab).fn_2d[CV_32F] = (void*)FUNCNAME##_32f##FLAG;  \
00751     (tab).fn_2d[CV_64F] = (void*)FUNCNAME##_64f##FLAG
00752 
00753 #ifdef __cplusplus
00754 
00755 class CV_EXPORTS CvOpenGlFuncTab
00756 {
00757 public:
00758     virtual ~CvOpenGlFuncTab();
00759 
00760     virtual void genBuffers(int n, unsigned int* buffers) const = 0;
00761     virtual void deleteBuffers(int n, const unsigned int* buffers) const = 0;
00762 
00763     virtual void bufferData(unsigned int target, ptrdiff_t size, const void* data, unsigned int usage) const = 0;
00764     virtual void bufferSubData(unsigned int target, ptrdiff_t offset, ptrdiff_t size, const void* data) const = 0;
00765 
00766     virtual void bindBuffer(unsigned int target, unsigned int buffer) const = 0;
00767 
00768     virtual void* mapBuffer(unsigned int target, unsigned int access) const = 0;
00769     virtual void unmapBuffer(unsigned int target) const = 0;
00770 
00771     virtual void generateBitmapFont(const std::string& family, int height, int weight, bool italic, bool underline, int start, int count, int base) const = 0;
00772 
00773     virtual bool isGlContextInitialized() const = 0;
00774 };
00775 
00776 CV_EXPORTS void icvSetOpenGlFuncTab(const CvOpenGlFuncTab* tab);
00777 
00778 CV_EXPORTS bool icvCheckGlError(const char* file, const int line, const char* func = "");
00779 
00780 #if defined(__GNUC__)
00781     #define CV_CheckGlError() CV_DbgAssert( (::icvCheckGlError(__FILE__, __LINE__, __func__)) )
00782 #else
00783     #define CV_CheckGlError() CV_DbgAssert( (::icvCheckGlError(__FILE__, __LINE__)) )
00784 #endif
00785 
00786 #endif //__cplusplus
00787 
00788 #endif // __OPENCV_CORE_INTERNAL_HPP__