]> rtime.felk.cvut.cz Git - opencv.git/commitdiff
brand-new cxcore interface & implementation
authorvp153 <vp153@73c94f0f-984f-4a5f-82bc-2d8db8d8ee08>
Tue, 3 Mar 2009 16:00:09 +0000 (16:00 +0000)
committervp153 <vp153@73c94f0f-984f-4a5f-82bc-2d8db8d8ee08>
Tue, 3 Mar 2009 16:00:09 +0000 (16:00 +0000)
git-svn-id: https://code.ros.org/svn/opencv/trunk@1611 73c94f0f-984f-4a5f-82bc-2d8db8d8ee08

opencv/include/opencv/cxcompat.h [new file with mode: 0644]
opencv/include/opencv/cxcore.h
opencv/include/opencv/cxcore.hpp
opencv/include/opencv/cxerror.h
opencv/include/opencv/cxmisc.h
opencv/include/opencv/cxoperations.hpp [new file with mode: 0644]
opencv/include/opencv/cxtypes.h

diff --git a/opencv/include/opencv/cxcompat.h b/opencv/include/opencv/cxcompat.h
new file mode 100644 (file)
index 0000000..7ea8d4f
--- /dev/null
@@ -0,0 +1,2114 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of the copyright holders may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+
+#ifndef _CXCOMPAT_H_
+#define _CXCOMPAT_H_
+
+#ifdef __IPL_H__
+#define HAVE_IPL
+#endif
+
+#ifndef SKIP_INCLUDES
+  #if defined HAVE_IPL && !defined __IPL_H__
+    #ifndef _INC_WINDOWS
+        #define CV_PRETEND_WINDOWS
+        #define _INC_WINDOWS
+        typedef struct tagBITMAPINFOHEADER BITMAPINFOHEADER;
+        typedef int BOOL;
+    #endif
+    #if defined WIN32 || defined WIN64
+      #include "ipl.h"
+    #else
+      #include "ipl/ipl.h"
+    #endif
+    #ifdef CV_PRETEND_WINDOWS
+        #undef _INC_WINDOWS
+    #endif
+  #endif
+#endif // SKIP_INCLUDES
+
+#include "cxtypes.h"
+#include "cxerror.h"
+#include "cvver.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************************\
+*          Array allocation, deallocation, initialization and access to elements         *
+\****************************************************************************************/
+
+/* <malloc> wrapper.
+   If there is no enough memory, the function
+   (as well as other OpenCV functions that call cvAlloc)
+   raises an error. */
+CVAPI(void*)  cvAlloc( size_t size );
+
+/* <free> wrapper.
+   Here and further all the memory releasing functions
+   (that all call cvFree) take double pointer in order to
+   to clear pointer to the data after releasing it.
+   Passing pointer to NULL pointer is Ok: nothing happens in this case
+*/
+CVAPI(void)   cvFree_( void* ptr );
+#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0)
+
+/* Allocates and initializes IplImage header */
+CVAPI(IplImage*)  cvCreateImageHeader( CvSize size, int depth, int channels );
+
+/* Inializes IplImage header */
+CVAPI(IplImage*) cvInitImageHeader( IplImage* image, CvSize size, int depth,
+                                   int channels, int origin CV_DEFAULT(0),
+                                   int align CV_DEFAULT(4));
+
+/* Creates IPL image (header and data) */
+CVAPI(IplImage*)  cvCreateImage( CvSize size, int depth, int channels );
+
+/* Releases (i.e. deallocates) IPL image header */
+CVAPI(void)  cvReleaseImageHeader( IplImage** image );
+
+/* Releases IPL image header and data */
+CVAPI(void)  cvReleaseImage( IplImage** image );
+
+/* Creates a copy of IPL image (widthStep may differ) */
+CVAPI(IplImage*) cvCloneImage( const IplImage* image );
+
+/* Sets a Channel Of Interest (only a few functions support COI) -
+   use cvCopy to extract the selected channel and/or put it back */
+CVAPI(void)  cvSetImageCOI( IplImage* image, int coi );
+
+/* Retrieves image Channel Of Interest */
+CVAPI(int)  cvGetImageCOI( const IplImage* image );
+
+/* Sets image ROI (region of interest) (COI is not changed) */
+CVAPI(void)  cvSetImageROI( IplImage* image, CvRect rect );
+
+/* Resets image ROI and COI */
+CVAPI(void)  cvResetImageROI( IplImage* image );
+
+/* Retrieves image ROI */
+CVAPI(CvRect) cvGetImageROI( const IplImage* image );
+
+/* Allocates and initalizes CvMat header */
+CVAPI(CvMat*)  cvCreateMatHeader( int rows, int cols, int type );
+
+#define CV_AUTOSTEP  0x7fffffff
+
+/* Initializes CvMat header */
+CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols,
+                              int type, void* data CV_DEFAULT(NULL),
+                              int step CV_DEFAULT(CV_AUTOSTEP) );
+
+/* Allocates and initializes CvMat header and allocates data */
+CVAPI(CvMat*)  cvCreateMat( int rows, int cols, int type );
+
+/* Releases CvMat header and deallocates matrix data
+   (reference counting is used for data) */
+CVAPI(void)  cvReleaseMat( CvMat** mat );
+
+/* Decrements CvMat data reference counter and deallocates the data if
+   it reaches 0 */
+CV_INLINE  void  cvDecRefData( CvArr* arr )
+{
+    if( CV_IS_MAT( arr ))
+    {
+        CvMat* mat = (CvMat*)arr;
+        mat->data.ptr = NULL;
+        if( mat->refcount != NULL && --*mat->refcount == 0 )
+            cvFree( &mat->refcount );
+        mat->refcount = NULL;
+    }
+    else if( CV_IS_MATND( arr ))
+    {
+        CvMatND* mat = (CvMatND*)arr;
+        mat->data.ptr = NULL;
+        if( mat->refcount != NULL && --*mat->refcount == 0 )
+            cvFree( &mat->refcount );
+        mat->refcount = NULL;
+    }
+}
+
+/* Increments CvMat data reference counter */
+CV_INLINE  int  cvIncRefData( CvArr* arr )
+{
+    int refcount = 0;
+    if( CV_IS_MAT( arr ))
+    {
+        CvMat* mat = (CvMat*)arr;
+        if( mat->refcount != NULL )
+            refcount = ++*mat->refcount;
+    }
+    else if( CV_IS_MATND( arr ))
+    {
+        CvMatND* mat = (CvMatND*)arr;
+        if( mat->refcount != NULL )
+            refcount = ++*mat->refcount;
+    }
+    return refcount;
+}
+
+
+/* Creates an exact copy of the input matrix (except, may be, step value) */
+CVAPI(CvMat*) cvCloneMat( const CvMat* mat );
+
+
+/* Makes a new matrix from <rect> subrectangle of input array.
+   No data is copied */
+CVAPI(CvMat*) cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );
+#define cvGetSubArr cvGetSubRect
+
+/* Selects row span of the input array: arr(start_row:delta_row:end_row,:)
+    (end_row is not included into the span). */
+CVAPI(CvMat*) cvGetRows( const CvArr* arr, CvMat* submat,
+                        int start_row, int end_row,
+                        int delta_row CV_DEFAULT(1));
+
+CV_INLINE  CvMat*  cvGetRow( const CvArr* arr, CvMat* submat, int row )
+{
+    return cvGetRows( arr, submat, row, row + 1, 1 );
+}
+
+
+/* Selects column span of the input array: arr(:,start_col:end_col)
+   (end_col is not included into the span) */
+CVAPI(CvMat*) cvGetCols( const CvArr* arr, CvMat* submat,
+                        int start_col, int end_col );
+
+CV_INLINE  CvMat*  cvGetCol( const CvArr* arr, CvMat* submat, int col )
+{
+    return cvGetCols( arr, submat, col, col + 1 );
+}
+
+/* Select a diagonal of the input array.
+   (diag = 0 means the main diagonal, >0 means a diagonal above the main one,
+   <0 - below the main one).
+   The diagonal will be represented as a column (nx1 matrix). */
+CVAPI(CvMat*) cvGetDiag( const CvArr* arr, CvMat* submat,
+                            int diag CV_DEFAULT(0));
+
+/* low-level scalar <-> raw data conversion functions */
+CVAPI(void) cvScalarToRawData( const CvScalar* scalar, void* data, int type,
+                              int extend_to_12 CV_DEFAULT(0) );
+
+CVAPI(void) cvRawDataToScalar( const void* data, int type, CvScalar* scalar );
+
+/* Allocates and initializes CvMatND header */
+CVAPI(CvMatND*)  cvCreateMatNDHeader( int dims, const int* sizes, int type );
+
+/* Allocates and initializes CvMatND header and allocates data */
+CVAPI(CvMatND*)  cvCreateMatND( int dims, const int* sizes, int type );
+
+/* Initializes preallocated CvMatND header */
+CVAPI(CvMatND*)  cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
+                                    int type, void* data CV_DEFAULT(NULL) );
+
+/* Releases CvMatND */
+CV_INLINE  void  cvReleaseMatND( CvMatND** mat )
+{
+    cvReleaseMat( (CvMat**)mat );
+}
+
+/* Creates a copy of CvMatND (except, may be, steps) */
+CVAPI(CvMatND*) cvCloneMatND( const CvMatND* mat );
+
+/* Allocates and initializes CvSparseMat header and allocates data */
+CVAPI(CvSparseMat*)  cvCreateSparseMat( int dims, const int* sizes, int type );
+
+/* Releases CvSparseMat */
+CVAPI(void)  cvReleaseSparseMat( CvSparseMat** mat );
+
+/* Creates a copy of CvSparseMat (except, may be, zero items) */
+CVAPI(CvSparseMat*) cvCloneSparseMat( const CvSparseMat* mat );
+
+/* Initializes sparse array iterator
+   (returns the first node or NULL if the array is empty) */
+CVAPI(CvSparseNode*) cvInitSparseMatIterator( const CvSparseMat* mat,
+                                              CvSparseMatIterator* mat_iterator );
+
+// returns next sparse array node (or NULL if there is no more nodes)
+CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator )
+{
+    if( mat_iterator->node->next )
+        return mat_iterator->node = mat_iterator->node->next;
+    else
+    {
+        int idx;
+        for( idx = ++mat_iterator->curidx; idx < mat_iterator->mat->hashsize; idx++ )
+        {
+            CvSparseNode* node = (CvSparseNode*)mat_iterator->mat->hashtable[idx];
+            if( node )
+            {
+                mat_iterator->curidx = idx;
+                return mat_iterator->node = node;
+            }
+        }
+        return NULL;
+    }
+}
+
+/**************** matrix iterator: used for n-ary operations on dense arrays *********/
+
+#define CV_MAX_ARR 10
+
+typedef struct CvNArrayIterator
+{
+    int count; /* number of arrays */
+    int dims; /* number of dimensions to iterate */
+    CvSize size; /* maximal common linear size: { width = size, height = 1 } */
+    uchar* ptr[CV_MAX_ARR]; /* pointers to the array slices */
+    int stack[CV_MAX_DIM]; /* for internal use */
+    CvMatND* hdr[CV_MAX_ARR]; /* pointers to the headers of the
+                                 matrices that are processed */
+}
+CvNArrayIterator;
+
+#define CV_NO_DEPTH_CHECK     1
+#define CV_NO_CN_CHECK        2
+#define CV_NO_SIZE_CHECK      4
+
+/* initializes iterator that traverses through several arrays simulteneously
+   (the function together with cvNextArraySlice is used for
+    N-ari element-wise operations) */
+CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs,
+                                 const CvArr* mask, CvMatND* stubs,
+                                 CvNArrayIterator* array_iterator,
+                                 int flags CV_DEFAULT(0) );
+
+/* returns zero value if iteration is finished, non-zero (slice length) otherwise */
+CVAPI(int) cvNextNArraySlice( CvNArrayIterator* array_iterator );
+
+
+/* Returns type of array elements:
+   CV_8UC1 ... CV_64FC4 ... */
+CVAPI(int) cvGetElemType( const CvArr* arr );
+
+/* Retrieves number of an array dimensions and
+   optionally sizes of the dimensions */
+CVAPI(int) cvGetDims( const CvArr* arr, int* sizes CV_DEFAULT(NULL) );
+
+
+/* Retrieves size of a particular array dimension.
+   For 2d arrays cvGetDimSize(arr,0) returns number of rows (image height)
+   and cvGetDimSize(arr,1) returns number of columns (image width) */
+CVAPI(int) cvGetDimSize( const CvArr* arr, int index );
+
+
+/* ptr = &arr(idx0,idx1,...). All indexes are zero-based,
+   the major dimensions go first (e.g. (y,x) for 2D, (z,y,x) for 3D */
+CVAPI(uchar*) cvPtr1D( const CvArr* arr, int idx0, int* type CV_DEFAULT(NULL));
+CVAPI(uchar*) cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type CV_DEFAULT(NULL) );
+CVAPI(uchar*) cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2,
+                      int* type CV_DEFAULT(NULL));
+
+/* For CvMat or IplImage number of indices should be 2
+   (row index (y) goes first, column index (x) goes next).
+   For CvMatND or CvSparseMat number of infices should match number of <dims> and
+   indices order should match the array dimension order. */
+CVAPI(uchar*) cvPtrND( const CvArr* arr, const int* idx, int* type CV_DEFAULT(NULL),
+                      int create_node CV_DEFAULT(1),
+                      unsigned* precalc_hashval CV_DEFAULT(NULL));
+
+/* value = arr(idx0,idx1,...) */
+CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 );
+CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 );
+CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
+CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx );
+
+/* for 1-channel arrays */
+CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 );
+CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
+CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
+CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx );
+
+/* arr(idx0,idx1,...) = value */
+CVAPI(void) cvSet1D( CvArr* arr, int idx0, CvScalar value );
+CVAPI(void) cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
+CVAPI(void) cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
+CVAPI(void) cvSetND( CvArr* arr, const int* idx, CvScalar value );
+
+/* for 1-channel arrays */
+CVAPI(void) cvSetReal1D( CvArr* arr, int idx0, double value );
+CVAPI(void) cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );
+CVAPI(void) cvSetReal3D( CvArr* arr, int idx0,
+                        int idx1, int idx2, double value );
+CVAPI(void) cvSetRealND( CvArr* arr, const int* idx, double value );
+
+/* clears element of ND dense array,
+   in case of sparse arrays it deletes the specified node */
+CVAPI(void) cvClearND( CvArr* arr, const int* idx );
+
+/* Converts CvArr (IplImage or CvMat,...) to CvMat.
+   If the last parameter is non-zero, function can
+   convert multi(>2)-dimensional array to CvMat as long as
+   the last array's dimension is continous. The resultant
+   matrix will be have appropriate (a huge) number of rows */
+CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header,
+                       int* coi CV_DEFAULT(NULL),
+                       int allowND CV_DEFAULT(0));
+
+/* Converts CvArr (IplImage or CvMat) to IplImage */
+CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header );
+
+
+/* Changes a shape of multi-dimensional array.
+   new_cn == 0 means that number of channels remains unchanged.
+   new_dims == 0 means that number and sizes of dimensions remain the same
+   (unless they need to be changed to set the new number of channels)
+   if new_dims == 1, there is no need to specify new dimension sizes
+   The resultant configuration should be achievable w/o data copying.
+   If the resultant array is sparse, CvSparseMat header should be passed
+   to the function else if the result is 1 or 2 dimensional,
+   CvMat header should be passed to the function
+   else CvMatND header should be passed */
+CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr,
+                             int sizeof_header, CvArr* header,
+                             int new_cn, int new_dims, int* new_sizes );
+
+#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes )   \
+      cvReshapeMatND( (arr), sizeof(*(header)), (header),         \
+                      (new_cn), (new_dims), (new_sizes))
+
+CVAPI(CvMat*) cvReshape( const CvArr* arr, CvMat* header,
+                        int new_cn, int new_rows CV_DEFAULT(0) );
+
+/* Repeats source 2d array several times in both horizontal and
+   vertical direction to fill destination array */
+CVAPI(void) cvRepeat( const CvArr* src, CvArr* dst );
+
+/* Allocates array data */
+CVAPI(void)  cvCreateData( CvArr* arr );
+
+/* Releases array data */
+CVAPI(void)  cvReleaseData( CvArr* arr );
+
+/* Attaches user data to the array header. The step is reffered to
+   the pre-last dimension. That is, all the planes of the array
+   must be joint (w/o gaps) */
+CVAPI(void)  cvSetData( CvArr* arr, void* data, int step );
+
+/* Retrieves raw data of CvMat, IplImage or CvMatND.
+   In the latter case the function raises an error if
+   the array can not be represented as a matrix */
+CVAPI(void) cvGetRawData( const CvArr* arr, uchar** data,
+                         int* step CV_DEFAULT(NULL),
+                         CvSize* roi_size CV_DEFAULT(NULL));
+
+/* Returns width and height of array in elements */
+CVAPI(CvSize) cvGetSize( const CvArr* arr );
+
+/* Copies source array to destination array */
+CVAPI(void)  cvCopy( const CvArr* src, CvArr* dst,
+                     const CvArr* mask CV_DEFAULT(NULL) );
+
+/* Sets all or "masked" elements of input array
+   to the same value*/
+CVAPI(void)  cvSet( CvArr* arr, CvScalar value,
+                    const CvArr* mask CV_DEFAULT(NULL) );
+
+/* Clears all the array elements (sets them to 0) */
+CVAPI(void)  cvSetZero( CvArr* arr );
+#define cvZero  cvSetZero
+
+
+/* Splits a multi-channel array into the set of single-channel arrays or
+   extracts particular [color] plane */
+CVAPI(void)  cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,
+                      CvArr* dst2, CvArr* dst3 );
+
+/* Merges a set of single-channel arrays into the single multi-channel array
+   or inserts one particular [color] plane to the array */
+CVAPI(void)  cvMerge( const CvArr* src0, const CvArr* src1,
+                      const CvArr* src2, const CvArr* src3,
+                      CvArr* dst );
+
+/* Copies several channels from input arrays to
+   certain channels of output arrays */
+CVAPI(void)  cvMixChannels( const CvArr** src, int src_count,
+                            CvArr** dst, int dst_count,
+                            const int* from_to, int pair_count );
+
+/* Performs linear transformation on every source array element:
+   dst(x,y,c) = scale*src(x,y,c)+shift.
+   Arbitrary combination of input and output array depths are allowed
+   (number of channels must be the same), thus the function can be used
+   for type conversion */
+CVAPI(void)  cvConvertScale( const CvArr* src, CvArr* dst,
+                             double scale CV_DEFAULT(1),
+                             double shift CV_DEFAULT(0) );
+#define cvCvtScale cvConvertScale
+#define cvScale  cvConvertScale
+#define cvConvert( src, dst )  cvConvertScale( (src), (dst), 1, 0 )
+
+
+/* Performs linear transformation on every source array element,
+   stores absolute value of the result:
+   dst(x,y,c) = abs(scale*src(x,y,c)+shift).
+   destination array must have 8u type.
+   In other cases one may use cvConvertScale + cvAbsDiffS */
+CVAPI(void)  cvConvertScaleAbs( const CvArr* src, CvArr* dst,
+                                double scale CV_DEFAULT(1),
+                                double shift CV_DEFAULT(0) );
+#define cvCvtScaleAbs  cvConvertScaleAbs
+
+
+/* checks termination criteria validity and
+   sets eps to default_eps (if it is not set),
+   max_iter to default_max_iters (if it is not set)
+*/
+CVAPI(CvTermCriteria) cvCheckTermCriteria( CvTermCriteria criteria,
+                                           double default_eps,
+                                           int default_max_iters );
+
+/****************************************************************************************\
+*                   Arithmetic, logic and comparison operations                          *
+\****************************************************************************************/
+
+/* dst(mask) = src1(mask) + src2(mask) */
+CVAPI(void)  cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst,
+                    const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(mask) = src(mask) + value */
+CVAPI(void)  cvAddS( const CvArr* src, CvScalar value, CvArr* dst,
+                     const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(mask) = src1(mask) - src2(mask) */
+CVAPI(void)  cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst,
+                    const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(mask) = src(mask) - value = src(mask) + (-value) */
+CV_INLINE  void  cvSubS( const CvArr* src, CvScalar value, CvArr* dst,
+                         const CvArr* mask CV_DEFAULT(NULL))
+{
+    cvAddS( src, cvScalar( -value.val[0], -value.val[1], -value.val[2], -value.val[3]),
+            dst, mask );
+}
+
+/* dst(mask) = value - src(mask) */
+CVAPI(void)  cvSubRS( const CvArr* src, CvScalar value, CvArr* dst,
+                      const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = src1(idx) * src2(idx) * scale
+   (scaled element-wise multiplication of 2 arrays) */
+CVAPI(void)  cvMul( const CvArr* src1, const CvArr* src2,
+                    CvArr* dst, double scale CV_DEFAULT(1) );
+
+/* element-wise division/inversion with scaling:
+    dst(idx) = src1(idx) * scale / src2(idx)
+    or dst(idx) = scale / src2(idx) if src1 == 0 */
+CVAPI(void)  cvDiv( const CvArr* src1, const CvArr* src2,
+                    CvArr* dst, double scale CV_DEFAULT(1));
+
+/* dst = src1 * scale + src2 */
+CVAPI(void)  cvScaleAdd( const CvArr* src1, CvScalar scale,
+                         const CvArr* src2, CvArr* dst );
+#define cvAXPY( A, real_scalar, B, C ) cvScaleAdd(A, cvRealScalar(real_scalar), B, C)
+
+/* dst = src1 * alpha + src2 * beta + gamma */
+CVAPI(void)  cvAddWeighted( const CvArr* src1, double alpha,
+                            const CvArr* src2, double beta,
+                            double gamma, CvArr* dst );
+
+/* result = sum_i(src1(i) * src2(i)) (results for all channels are accumulated together) */
+CVAPI(double)  cvDotProduct( const CvArr* src1, const CvArr* src2 );
+
+/* dst(idx) = src1(idx) & src2(idx) */
+CVAPI(void) cvAnd( const CvArr* src1, const CvArr* src2,
+                  CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = src(idx) & value */
+CVAPI(void) cvAndS( const CvArr* src, CvScalar value,
+                   CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = src1(idx) | src2(idx) */
+CVAPI(void) cvOr( const CvArr* src1, const CvArr* src2,
+                 CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = src(idx) | value */
+CVAPI(void) cvOrS( const CvArr* src, CvScalar value,
+                  CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = src1(idx) ^ src2(idx) */
+CVAPI(void) cvXor( const CvArr* src1, const CvArr* src2,
+                  CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = src(idx) ^ value */
+CVAPI(void) cvXorS( const CvArr* src, CvScalar value,
+                   CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
+
+/* dst(idx) = ~src(idx) */
+CVAPI(void) cvNot( const CvArr* src, CvArr* dst );
+
+/* dst(idx) = lower(idx) <= src(idx) < upper(idx) */
+CVAPI(void) cvInRange( const CvArr* src, const CvArr* lower,
+                      const CvArr* upper, CvArr* dst );
+
+/* dst(idx) = lower <= src(idx) < upper */
+CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower,
+                       CvScalar upper, CvArr* dst );
+
+#define CV_CMP_EQ   0
+#define CV_CMP_GT   1
+#define CV_CMP_GE   2
+#define CV_CMP_LT   3
+#define CV_CMP_LE   4
+#define CV_CMP_NE   5
+
+/* The comparison operation support single-channel arrays only.
+   Destination image should be 8uC1 or 8sC1 */
+
+/* dst(idx) = src1(idx) _cmp_op_ src2(idx) */
+CVAPI(void) cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );
+
+/* dst(idx) = src1(idx) _cmp_op_ value */
+CVAPI(void) cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );
+
+/* dst(idx) = min(src1(idx),src2(idx)) */
+CVAPI(void) cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/* dst(idx) = max(src1(idx),src2(idx)) */
+CVAPI(void) cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/* dst(idx) = min(src(idx),value) */
+CVAPI(void) cvMinS( const CvArr* src, double value, CvArr* dst );
+
+/* dst(idx) = max(src(idx),value) */
+CVAPI(void) cvMaxS( const CvArr* src, double value, CvArr* dst );
+
+/* dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */
+CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/* dst(x,y,c) = abs(src(x,y,c) - value(c)) */
+CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );
+#define cvAbs( src, dst ) cvAbsDiffS( (src), (dst), cvScalarAll(0))
+
+/****************************************************************************************\
+*                                Math operations                                         *
+\****************************************************************************************/
+
+/* Does cartesian->polar coordinates conversion.
+   Either of output components (magnitude or angle) is optional */
+CVAPI(void)  cvCartToPolar( const CvArr* x, const CvArr* y,
+                            CvArr* magnitude, CvArr* angle CV_DEFAULT(NULL),
+                            int angle_in_degrees CV_DEFAULT(0));
+
+/* Does polar->cartesian coordinates conversion.
+   Either of output components (magnitude or angle) is optional.
+   If magnitude is missing it is assumed to be all 1's */
+CVAPI(void)  cvPolarToCart( const CvArr* magnitude, const CvArr* angle,
+                            CvArr* x, CvArr* y,
+                            int angle_in_degrees CV_DEFAULT(0));
+
+/* Does powering: dst(idx) = src(idx)^power */
+CVAPI(void)  cvPow( const CvArr* src, CvArr* dst, double power );
+
+/* Does exponention: dst(idx) = exp(src(idx)).
+   Overflow is not handled yet. Underflow is handled.
+   Maximal relative error is ~7e-6 for single-precision input */
+CVAPI(void)  cvExp( const CvArr* src, CvArr* dst );
+
+/* Calculates natural logarithms: dst(idx) = log(abs(src(idx))).
+   Logarithm of 0 gives large negative number(~-700)
+   Maximal relative error is ~3e-7 for single-precision output
+*/
+CVAPI(void)  cvLog( const CvArr* src, CvArr* dst );
+
+/* Fast arctangent calculation */
+CVAPI(float) cvFastArctan( float y, float x );
+
+/* Fast cubic root calculation */
+CVAPI(float)  cvCbrt( float value );
+
+/* Checks array values for NaNs, Infs or simply for too large numbers
+   (if CV_CHECK_RANGE is set). If CV_CHECK_QUIET is set,
+   no runtime errors is raised (function returns zero value in case of "bad" values).
+   Otherwise cvError is called */
+#define  CV_CHECK_RANGE    1
+#define  CV_CHECK_QUIET    2
+CVAPI(int)  cvCheckArr( const CvArr* arr, int flags CV_DEFAULT(0),
+                        double min_val CV_DEFAULT(0), double max_val CV_DEFAULT(0));
+#define cvCheckArray cvCheckArr
+
+#define CV_RAND_UNI      0
+#define CV_RAND_NORMAL   1
+CVAPI(void) cvRandArr( CvRNG* rng, CvArr* arr, int dist_type,
+                      CvScalar param1, CvScalar param2 );
+
+CVAPI(void) cvRandShuffle( CvArr* mat, CvRNG* rng,
+                           double iter_factor CV_DEFAULT(1.));
+
+#define CV_SORT_EVERY_ROW 0
+#define CV_SORT_EVERY_COLUMN 1
+#define CV_SORT_ASCENDING 0
+#define CV_SORT_DESCENDING 16
+
+CVAPI(void) cvSort( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
+                    CvArr* idxmat CV_DEFAULT(NULL),
+                    int flags CV_DEFAULT(0));
+
+/* Finds real roots of a cubic equation */
+CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots );
+
+/* Finds all real and complex roots of a polynomial equation */
+CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2,
+                       int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100));
+
+/****************************************************************************************\
+*                                Matrix operations                                       *
+\****************************************************************************************/
+
+/* Calculates cross product of two 3d vectors */
+CVAPI(void)  cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );
+
+/* Matrix transform: dst = A*B + C, C is optional */
+#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( (src1), (src2), 1., (src3), 1., (dst), 0 )
+#define cvMatMul( src1, src2, dst )  cvMatMulAdd( (src1), (src2), NULL, (dst))
+
+#define CV_GEMM_A_T 1
+#define CV_GEMM_B_T 2
+#define CV_GEMM_C_T 4
+/* Extended matrix transform:
+   dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T */
+CVAPI(void)  cvGEMM( const CvArr* src1, const CvArr* src2, double alpha,
+                     const CvArr* src3, double beta, CvArr* dst,
+                     int tABC CV_DEFAULT(0));
+#define cvMatMulAddEx cvGEMM
+
+/* Transforms each element of source array and stores
+   resultant vectors in destination array */
+CVAPI(void)  cvTransform( const CvArr* src, CvArr* dst,
+                          const CvMat* transmat,
+                          const CvMat* shiftvec CV_DEFAULT(NULL));
+#define cvMatMulAddS cvTransform
+
+/* Does perspective transform on every element of input array */
+CVAPI(void)  cvPerspectiveTransform( const CvArr* src, CvArr* dst,
+                                     const CvMat* mat );
+
+/* Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */
+CVAPI(void) cvMulTransposed( const CvArr* src, CvArr* dst, int order,
+                             const CvArr* delta CV_DEFAULT(NULL),
+                             double scale CV_DEFAULT(1.) );
+
+/* Tranposes matrix. Square matrices can be transposed in-place */
+CVAPI(void)  cvTranspose( const CvArr* src, CvArr* dst );
+#define cvT cvTranspose
+
+/* Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */
+CVAPI(void)  cvCompleteSymm( CvMat* matrix, int LtoR CV_DEFAULT(0) );
+
+/* Mirror array data around horizontal (flip=0),
+   vertical (flip=1) or both(flip=-1) axises:
+   cvFlip(src) flips images vertically and sequences horizontally (inplace) */
+CVAPI(void)  cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
+                     int flip_mode CV_DEFAULT(0));
+#define cvMirror cvFlip
+
+
+#define CV_SVD_MODIFY_A   1
+#define CV_SVD_U_T        2
+#define CV_SVD_V_T        4
+
+/* Performs Singular Value Decomposition of a matrix */
+CVAPI(void)   cvSVD( CvArr* A, CvArr* W, CvArr* U CV_DEFAULT(NULL),
+                     CvArr* V CV_DEFAULT(NULL), int flags CV_DEFAULT(0));
+
+/* Performs Singular Value Back Substitution (solves A*X = B):
+   flags must be the same as in cvSVD */
+CVAPI(void)   cvSVBkSb( const CvArr* W, const CvArr* U,
+                        const CvArr* V, const CvArr* B,
+                        CvArr* X, int flags );
+
+#define CV_LU  0
+#define CV_SVD 1
+#define CV_SVD_SYM 2
+#define CV_CHOLESKY 3
+#define CV_QR  4
+#define CV_NORMAL 16
+
+/* Inverts matrix */
+CVAPI(double)  cvInvert( const CvArr* src, CvArr* dst,
+                         int method CV_DEFAULT(CV_LU));
+#define cvInv cvInvert
+
+/* Solves linear system (src1)*(dst) = (src2)
+   (returns 0 if src1 is a singular and CV_LU method is used) */
+CVAPI(int)  cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst,
+                     int method CV_DEFAULT(CV_LU));
+
+/* Calculates determinant of input matrix */
+CVAPI(double) cvDet( const CvArr* mat );
+
+/* Calculates trace of the matrix (sum of elements on the main diagonal) */
+CVAPI(CvScalar) cvTrace( const CvArr* mat );
+
+/* Finds eigen values and vectors of a symmetric matrix */
+CVAPI(void)  cvEigenVV( CvArr* mat, CvArr* evects,
+                        CvArr* evals, double eps CV_DEFAULT(0));
+
+/* Makes an identity matrix (mat_ij = i == j) */
+CVAPI(void)  cvSetIdentity( CvArr* mat, CvScalar value CV_DEFAULT(cvRealScalar(1)) );
+
+/* Fills matrix with given range of numbers */
+CVAPI(CvArr*)  cvRange( CvArr* mat, double start, double end );
+
+/* Calculates covariation matrix for a set of vectors */
+/* transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */
+#define CV_COVAR_SCRAMBLED 0
+
+/* [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */
+#define CV_COVAR_NORMAL    1
+
+/* do not calc average (i.e. mean vector) - use the input vector instead
+   (useful for calculating covariance matrix by parts) */
+#define CV_COVAR_USE_AVG   2
+
+/* scale the covariance matrix coefficients by number of the vectors */
+#define CV_COVAR_SCALE     4
+
+/* all the input vectors are stored in a single matrix, as its rows */
+#define CV_COVAR_ROWS      8
+
+/* all the input vectors are stored in a single matrix, as its columns */
+#define CV_COVAR_COLS     16
+
+CVAPI(void)  cvCalcCovarMatrix( const CvArr** vects, int count,
+                                CvArr* cov_mat, CvArr* avg, int flags );
+
+#define CV_PCA_DATA_AS_ROW 0
+#define CV_PCA_DATA_AS_COL 1
+#define CV_PCA_USE_AVG 2
+CVAPI(void)  cvCalcPCA( const CvArr* data, CvArr* mean,
+                        CvArr* eigenvals, CvArr* eigenvects, int flags );
+
+CVAPI(void)  cvProjectPCA( const CvArr* data, const CvArr* mean,
+                           const CvArr* eigenvects, CvArr* result );
+
+CVAPI(void)  cvBackProjectPCA( const CvArr* proj, const CvArr* mean,
+                               const CvArr* eigenvects, CvArr* result );
+
+/* Calculates Mahalanobis(weighted) distance */
+CVAPI(double)  cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* mat );
+#define cvMahalonobis  cvMahalanobis
+
+/****************************************************************************************\
+*                                    Array Statistics                                    *
+\****************************************************************************************/
+
+/* Finds sum of array elements */
+CVAPI(CvScalar)  cvSum( const CvArr* arr );
+
+/* Calculates number of non-zero pixels */
+CVAPI(int)  cvCountNonZero( const CvArr* arr );
+
+/* Calculates mean value of array elements */
+CVAPI(CvScalar)  cvAvg( const CvArr* arr, const CvArr* mask CV_DEFAULT(NULL) );
+
+/* Calculates mean and standard deviation of pixel values */
+CVAPI(void)  cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev,
+                       const CvArr* mask CV_DEFAULT(NULL) );
+
+/* Finds global minimum, maximum and their positions */
+CVAPI(void)  cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
+                          CvPoint* min_loc CV_DEFAULT(NULL),
+                          CvPoint* max_loc CV_DEFAULT(NULL),
+                          const CvArr* mask CV_DEFAULT(NULL) );
+
+/* types of array norm */
+#define CV_C            1
+#define CV_L1           2
+#define CV_L2           4
+#define CV_NORM_MASK    7
+#define CV_RELATIVE     8
+#define CV_DIFF         16
+#define CV_MINMAX       32
+
+#define CV_DIFF_C       (CV_DIFF | CV_C)
+#define CV_DIFF_L1      (CV_DIFF | CV_L1)
+#define CV_DIFF_L2      (CV_DIFF | CV_L2)
+#define CV_RELATIVE_C   (CV_RELATIVE | CV_C)
+#define CV_RELATIVE_L1  (CV_RELATIVE | CV_L1)
+#define CV_RELATIVE_L2  (CV_RELATIVE | CV_L2)
+
+/* Finds norm, difference norm or relative difference norm for an array (or two arrays) */
+CVAPI(double)  cvNorm( const CvArr* arr1, const CvArr* arr2 CV_DEFAULT(NULL),
+                       int norm_type CV_DEFAULT(CV_L2),
+                       const CvArr* mask CV_DEFAULT(NULL) );
+
+CVAPI(void)  cvNormalize( const CvArr* src, CvArr* dst,
+                          double a CV_DEFAULT(1.), double b CV_DEFAULT(0.),
+                          int norm_type CV_DEFAULT(CV_L2),
+                          const CvArr* mask CV_DEFAULT(NULL) );
+
+
+#define CV_REDUCE_SUM 0
+#define CV_REDUCE_AVG 1
+#define CV_REDUCE_MAX 2
+#define CV_REDUCE_MIN 3
+
+CVAPI(void)  cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1),
+                       int op CV_DEFAULT(CV_REDUCE_SUM) );
+
+/****************************************************************************************\
+*                      Discrete Linear Transforms and Related Functions                  *
+\****************************************************************************************/
+
+#define CV_DXT_FORWARD  0
+#define CV_DXT_INVERSE  1
+#define CV_DXT_SCALE    2 /* divide result by size of array */
+#define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE)
+#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE
+#define CV_DXT_ROWS     4 /* transform each row individually */
+#define CV_DXT_MUL_CONJ 8 /* conjugate the second argument of cvMulSpectrums */
+
+/* Discrete Fourier Transform:
+    complex->complex,
+    real->ccs (forward),
+    ccs->real (inverse) */
+CVAPI(void)  cvDFT( const CvArr* src, CvArr* dst, int flags,
+                    int nonzero_rows CV_DEFAULT(0) );
+#define cvFFT cvDFT
+
+/* Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y)) */
+CVAPI(void)  cvMulSpectrums( const CvArr* src1, const CvArr* src2,
+                             CvArr* dst, int flags );
+
+/* Finds optimal DFT vector size >= size0 */
+CVAPI(int)  cvGetOptimalDFTSize( int size0 );
+
+/* Discrete Cosine Transform */
+CVAPI(void)  cvDCT( const CvArr* src, CvArr* dst, int flags );
+
+/****************************************************************************************\
+*                              Dynamic data structures                                   *
+\****************************************************************************************/
+
+/* Calculates length of sequence slice (with support of negative indices). */
+CVAPI(int) cvSliceLength( CvSlice slice, const CvSeq* seq );
+
+
+/* Creates new memory storage.
+   block_size == 0 means that default,
+   somewhat optimal size, is used (currently, it is 64K) */
+CVAPI(CvMemStorage*)  cvCreateMemStorage( int block_size CV_DEFAULT(0));
+
+
+/* Creates a memory storage that will borrow memory blocks from parent storage */
+CVAPI(CvMemStorage*)  cvCreateChildMemStorage( CvMemStorage* parent );
+
+
+/* Releases memory storage. All the children of a parent must be released before
+   the parent. A child storage returns all the blocks to parent when it is released */
+CVAPI(void)  cvReleaseMemStorage( CvMemStorage** storage );
+
+
+/* Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos)
+   to reuse memory allocated for the storage - cvClearSeq,cvClearSet ...
+   do not free any memory.
+   A child storage returns all the blocks to the parent when it is cleared */
+CVAPI(void)  cvClearMemStorage( CvMemStorage* storage );
+
+/* Remember a storage "free memory" position */
+CVAPI(void)  cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );
+
+/* Restore a storage "free memory" position */
+CVAPI(void)  cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos );
+
+/* Allocates continuous buffer of the specified size in the storage */
+CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size );
+
+/* Allocates string in memory storage */
+CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr,
+                                        int len CV_DEFAULT(-1) );
+
+/* Creates new empty sequence that will reside in the specified storage */
+CVAPI(CvSeq*)  cvCreateSeq( int seq_flags, int header_size,
+                            int elem_size, CvMemStorage* storage );
+
+/* Changes default size (granularity) of sequence blocks.
+   The default size is ~1Kbyte */
+CVAPI(void)  cvSetSeqBlockSize( CvSeq* seq, int delta_elems );
+
+
+/* Adds new element to the end of sequence. Returns pointer to the element */
+CVAPI(schar*)  cvSeqPush( CvSeq* seq, void* element CV_DEFAULT(NULL));
+
+
+/* Adds new element to the beginning of sequence. Returns pointer to it */
+CVAPI(schar*)  cvSeqPushFront( CvSeq* seq, void* element CV_DEFAULT(NULL));
+
+
+/* Removes the last element from sequence and optionally saves it */
+CVAPI(void)  cvSeqPop( CvSeq* seq, void* element CV_DEFAULT(NULL));
+
+
+/* Removes the first element from sequence and optioanally saves it */
+CVAPI(void)  cvSeqPopFront( CvSeq* seq, void* element CV_DEFAULT(NULL));
+
+
+#define CV_FRONT 1
+#define CV_BACK 0
+/* Adds several new elements to the end of sequence */
+CVAPI(void)  cvSeqPushMulti( CvSeq* seq, void* elements,
+                             int count, int in_front CV_DEFAULT(0) );
+
+/* Removes several elements from the end of sequence and optionally saves them */
+CVAPI(void)  cvSeqPopMulti( CvSeq* seq, void* elements,
+                            int count, int in_front CV_DEFAULT(0) );
+
+/* Inserts a new element in the middle of sequence.
+   cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem) */
+CVAPI(schar*)  cvSeqInsert( CvSeq* seq, int before_index,
+                            void* element CV_DEFAULT(NULL));
+
+/* Removes specified sequence element */
+CVAPI(void)  cvSeqRemove( CvSeq* seq, int index );
+
+
+/* Removes all the elements from the sequence. The freed memory
+   can be reused later only by the same sequence unless cvClearMemStorage
+   or cvRestoreMemStoragePos is called */
+CVAPI(void)  cvClearSeq( CvSeq* seq );
+
+
+/* Retrieves pointer to specified sequence element.
+   Negative indices are supported and mean counting from the end
+   (e.g -1 means the last sequence element) */
+CVAPI(schar*)  cvGetSeqElem( const CvSeq* seq, int index );
+
+/* Calculates index of the specified sequence element.
+   Returns -1 if element does not belong to the sequence */
+CVAPI(int)  cvSeqElemIdx( const CvSeq* seq, const void* element,
+                         CvSeqBlock** block CV_DEFAULT(NULL) );
+
+/* Initializes sequence writer. The new elements will be added to the end of sequence */
+CVAPI(void)  cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer );
+
+
+/* Combination of cvCreateSeq and cvStartAppendToSeq */
+CVAPI(void)  cvStartWriteSeq( int seq_flags, int header_size,
+                              int elem_size, CvMemStorage* storage,
+                              CvSeqWriter* writer );
+
+/* Closes sequence writer, updates sequence header and returns pointer
+   to the resultant sequence
+   (which may be useful if the sequence was created using cvStartWriteSeq))
+*/
+CVAPI(CvSeq*)  cvEndWriteSeq( CvSeqWriter* writer );
+
+
+/* Updates sequence header. May be useful to get access to some of previously
+   written elements via cvGetSeqElem or sequence reader */
+CVAPI(void)   cvFlushSeqWriter( CvSeqWriter* writer );
+
+
+/* Initializes sequence reader.
+   The sequence can be read in forward or backward direction */
+CVAPI(void) cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader,
+                           int reverse CV_DEFAULT(0) );
+
+
+/* Returns current sequence reader position (currently observed sequence element) */
+CVAPI(int)  cvGetSeqReaderPos( CvSeqReader* reader );
+
+
+/* Changes sequence reader position. It may seek to an absolute or
+   to relative to the current position */
+CVAPI(void)   cvSetSeqReaderPos( CvSeqReader* reader, int index,
+                                 int is_relative CV_DEFAULT(0));
+
+/* Copies sequence content to a continuous piece of memory */
+CVAPI(void*)  cvCvtSeqToArray( const CvSeq* seq, void* elements,
+                               CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ) );
+
+/* Creates sequence header for array.
+   After that all the operations on sequences that do not alter the content
+   can be applied to the resultant sequence */
+CVAPI(CvSeq*) cvMakeSeqHeaderForArray( int seq_type, int header_size,
+                                       int elem_size, void* elements, int total,
+                                       CvSeq* seq, CvSeqBlock* block );
+
+/* Extracts sequence slice (with or without copying sequence elements) */
+CVAPI(CvSeq*) cvSeqSlice( const CvSeq* seq, CvSlice slice,
+                         CvMemStorage* storage CV_DEFAULT(NULL),
+                         int copy_data CV_DEFAULT(0));
+
+CV_INLINE CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage CV_DEFAULT(NULL))
+{
+    return cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 );
+}
+
+/* Removes sequence slice */
+CVAPI(void)  cvSeqRemoveSlice( CvSeq* seq, CvSlice slice );
+
+/* Inserts a sequence or array into another sequence */
+CVAPI(void)  cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
+
+/* a < b ? -1 : a > b ? 1 : 0 */
+typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata );
+
+/* Sorts sequence in-place given element comparison function */
+CVAPI(void) cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata CV_DEFAULT(NULL) );
+
+/* Finds element in a [sorted] sequence */
+CVAPI(schar*) cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func,
+                           int is_sorted, int* elem_idx,
+                           void* userdata CV_DEFAULT(NULL) );
+
+/* Reverses order of sequence elements in-place */
+CVAPI(void) cvSeqInvert( CvSeq* seq );
+
+/* Splits sequence into one or more equivalence classes using the specified criteria */
+CVAPI(int)  cvSeqPartition( const CvSeq* seq, CvMemStorage* storage,
+                            CvSeq** labels, CvCmpFunc is_equal, void* userdata );
+
+/************ Internal sequence functions ************/
+CVAPI(void)  cvChangeSeqBlock( void* reader, int direction );
+CVAPI(void)  cvCreateSeqBlock( CvSeqWriter* writer );
+
+
+/* Creates a new set */
+CVAPI(CvSet*)  cvCreateSet( int set_flags, int header_size,
+                            int elem_size, CvMemStorage* storage );
+
+/* Adds new element to the set and returns pointer to it */
+CVAPI(int)  cvSetAdd( CvSet* set_header, CvSetElem* elem CV_DEFAULT(NULL),
+                      CvSetElem** inserted_elem CV_DEFAULT(NULL) );
+
+/* Fast variant of cvSetAdd */
+CV_INLINE  CvSetElem* cvSetNew( CvSet* set_header )
+{
+    CvSetElem* elem = set_header->free_elems;
+    if( elem )
+    {
+        set_header->free_elems = elem->next_free;
+        elem->flags = elem->flags & CV_SET_ELEM_IDX_MASK;
+        set_header->active_count++;
+    }
+    else
+        cvSetAdd( set_header, NULL, (CvSetElem**)&elem );
+    return elem;
+}
+
+/* Removes set element given its pointer */
+CV_INLINE  void cvSetRemoveByPtr( CvSet* set_header, void* elem )
+{
+    CvSetElem* _elem = (CvSetElem*)elem;
+    assert( _elem->flags >= 0 /*&& (elem->flags & CV_SET_ELEM_IDX_MASK) < set_header->total*/ );
+    _elem->next_free = set_header->free_elems;
+    _elem->flags = (_elem->flags & CV_SET_ELEM_IDX_MASK) | CV_SET_ELEM_FREE_FLAG;
+    set_header->free_elems = _elem;
+    set_header->active_count--;
+}
+
+/* Removes element from the set by its index  */
+CVAPI(void)   cvSetRemove( CvSet* set_header, int index );
+
+/* Returns a set element by index. If the element doesn't belong to the set,
+   NULL is returned */
+CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int index )
+{
+    CvSetElem* elem = (CvSetElem*)cvGetSeqElem( (CvSeq*)set_header, index );
+    return elem && CV_IS_SET_ELEM( elem ) ? elem : 0;
+}
+
+/* Removes all the elements from the set */
+CVAPI(void)  cvClearSet( CvSet* set_header );
+
+/* Creates new graph */
+CVAPI(CvGraph*)  cvCreateGraph( int graph_flags, int header_size,
+                                int vtx_size, int edge_size,
+                                CvMemStorage* storage );
+
+/* Adds new vertex to the graph */
+CVAPI(int)  cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx CV_DEFAULT(NULL),
+                           CvGraphVtx** inserted_vtx CV_DEFAULT(NULL) );
+
+
+/* Removes vertex from the graph together with all incident edges */
+CVAPI(int)  cvGraphRemoveVtx( CvGraph* graph, int index );
+CVAPI(int)  cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx );
+
+
+/* Link two vertices specifed by indices or pointers if they
+   are not connected or return pointer to already existing edge
+   connecting the vertices.
+   Functions return 1 if a new edge was created, 0 otherwise */
+CVAPI(int)  cvGraphAddEdge( CvGraph* graph,
+                            int start_idx, int end_idx,
+                            const CvGraphEdge* edge CV_DEFAULT(NULL),
+                            CvGraphEdge** inserted_edge CV_DEFAULT(NULL) );
+
+CVAPI(int)  cvGraphAddEdgeByPtr( CvGraph* graph,
+                               CvGraphVtx* start_vtx, CvGraphVtx* end_vtx,
+                               const CvGraphEdge* edge CV_DEFAULT(NULL),
+                               CvGraphEdge** inserted_edge CV_DEFAULT(NULL) );
+
+/* Remove edge connecting two vertices */
+CVAPI(void)  cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx );
+CVAPI(void)  cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx,
+                                     CvGraphVtx* end_vtx );
+
+/* Find edge connecting two vertices */
+CVAPI(CvGraphEdge*)  cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx );
+CVAPI(CvGraphEdge*)  cvFindGraphEdgeByPtr( const CvGraph* graph,
+                                           const CvGraphVtx* start_vtx,
+                                           const CvGraphVtx* end_vtx );
+#define cvGraphFindEdge cvFindGraphEdge
+#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr
+
+/* Remove all vertices and edges from the graph */
+CVAPI(void)  cvClearGraph( CvGraph* graph );
+
+
+/* Count number of edges incident to the vertex */
+CVAPI(int)  cvGraphVtxDegree( const CvGraph* graph, int vtx_idx );
+CVAPI(int)  cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx );
+
+
+/* Retrieves graph vertex by given index */
+#define cvGetGraphVtx( graph, idx ) (CvGraphVtx*)cvGetSetElem((CvSet*)(graph), (idx))
+
+/* Retrieves index of a graph vertex given its pointer */
+#define cvGraphVtxIdx( graph, vtx ) ((vtx)->flags & CV_SET_ELEM_IDX_MASK)
+
+/* Retrieves index of a graph edge given its pointer */
+#define cvGraphEdgeIdx( graph, edge ) ((edge)->flags & CV_SET_ELEM_IDX_MASK)
+
+#define cvGraphGetVtxCount( graph ) ((graph)->active_count)
+#define cvGraphGetEdgeCount( graph ) ((graph)->edges->active_count)
+
+#define  CV_GRAPH_VERTEX        1
+#define  CV_GRAPH_TREE_EDGE     2
+#define  CV_GRAPH_BACK_EDGE     4
+#define  CV_GRAPH_FORWARD_EDGE  8
+#define  CV_GRAPH_CROSS_EDGE    16
+#define  CV_GRAPH_ANY_EDGE      30
+#define  CV_GRAPH_NEW_TREE      32
+#define  CV_GRAPH_BACKTRACKING  64
+#define  CV_GRAPH_OVER          -1
+
+#define  CV_GRAPH_ALL_ITEMS    -1
+
+/* flags for graph vertices and edges */
+#define  CV_GRAPH_ITEM_VISITED_FLAG  (1 << 30)
+#define  CV_IS_GRAPH_VERTEX_VISITED(vtx) \
+    (((CvGraphVtx*)(vtx))->flags & CV_GRAPH_ITEM_VISITED_FLAG)
+#define  CV_IS_GRAPH_EDGE_VISITED(edge) \
+    (((CvGraphEdge*)(edge))->flags & CV_GRAPH_ITEM_VISITED_FLAG)
+#define  CV_GRAPH_SEARCH_TREE_NODE_FLAG   (1 << 29)
+#define  CV_GRAPH_FORWARD_EDGE_FLAG       (1 << 28)
+
+typedef struct CvGraphScanner
+{
+    CvGraphVtx* vtx;       /* current graph vertex (or current edge origin) */
+    CvGraphVtx* dst;       /* current graph edge destination vertex */
+    CvGraphEdge* edge;     /* current edge */
+
+    CvGraph* graph;        /* the graph */
+    CvSeq*   stack;        /* the graph vertex stack */
+    int      index;        /* the lower bound of certainly visited vertices */
+    int      mask;         /* event mask */
+}
+CvGraphScanner;
+
+/* Creates new graph scanner. */
+CVAPI(CvGraphScanner*)  cvCreateGraphScanner( CvGraph* graph,
+                                             CvGraphVtx* vtx CV_DEFAULT(NULL),
+                                             int mask CV_DEFAULT(CV_GRAPH_ALL_ITEMS));
+
+/* Releases graph scanner. */
+CVAPI(void) cvReleaseGraphScanner( CvGraphScanner** scanner );
+
+/* Get next graph element */
+CVAPI(int)  cvNextGraphItem( CvGraphScanner* scanner );
+
+/* Creates a copy of graph */
+CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );
+
+/****************************************************************************************\
+*                                     Drawing                                            *
+\****************************************************************************************/
+
+/****************************************************************************************\
+*       Drawing functions work with images/matrices of arbitrary type.                   *
+*       For color images the channel order is BGR[A]                                     *
+*       Antialiasing is supported only for 8-bit image now.                              *
+*       All the functions include parameter color that means rgb value (that may be      *
+*       constructed with CV_RGB macro) for color images and brightness                   *
+*       for grayscale images.                                                            *
+*       If a drawn figure is partially or completely outside of the image, it is clipped.*
+\****************************************************************************************/
+
+#define CV_RGB( r, g, b )  cvScalar( (b), (g), (r), 0 )
+#define CV_FILLED -1
+
+#define CV_AA 16
+
+/* Draws 4-connected, 8-connected or antialiased line segment connecting two points */
+CVAPI(void)  cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,
+                     CvScalar color, int thickness CV_DEFAULT(1),
+                     int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
+
+/* Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
+   if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn */
+CVAPI(void)  cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2,
+                          CvScalar color, int thickness CV_DEFAULT(1),
+                          int line_type CV_DEFAULT(8),
+                          int shift CV_DEFAULT(0));
+
+/* Draws a circle with specified center and radius.
+   Thickness works in the same way as with cvRectangle */
+CVAPI(void)  cvCircle( CvArr* img, CvPoint center, int radius,
+                       CvScalar color, int thickness CV_DEFAULT(1),
+                       int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
+
+/* Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
+   depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
+   is rotated by <angle>. All the angles are in degrees */
+CVAPI(void)  cvEllipse( CvArr* img, CvPoint center, CvSize axes,
+                        double angle, double start_angle, double end_angle,
+                        CvScalar color, int thickness CV_DEFAULT(1),
+                        int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
+
+CV_INLINE  void  cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color,
+                               int thickness CV_DEFAULT(1),
+                               int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) )
+{
+    CvSize axes;
+    axes.width = cvRound(box.size.height*0.5);
+    axes.height = cvRound(box.size.width*0.5);
+
+    cvEllipse( img, cvPointFrom32f( box.center ), axes, box.angle,
+               0, 360, color, thickness, line_type, shift );
+}
+
+/* Fills convex or monotonous polygon. */
+CVAPI(void)  cvFillConvexPoly( CvArr* img, CvPoint* pts, int npts, CvScalar color,
+                               int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
+
+/* Fills an area bounded by one or more arbitrary polygons */
+CVAPI(void)  cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours, CvScalar color,
+                         int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
+
+/* Draws one or more polygonal curves */
+CVAPI(void)  cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours,
+                         int is_closed, CvScalar color, int thickness CV_DEFAULT(1),
+                         int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
+
+#define cvDrawRect cvRectangle
+#define cvDrawLine cvLine
+#define cvDrawCircle cvCircle
+#define cvDrawEllipse cvEllipse
+#define cvDrawPolyLine cvPolyLine
+
+/* Clips the line segment connecting *pt1 and *pt2
+   by the rectangular window
+   (0<=x<img_size.width, 0<=y<img_size.height). */
+CVAPI(int) cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );
+
+/* Initializes line iterator. Initially, line_iterator->ptr will point
+   to pt1 (or pt2, see left_to_right description) location in the image.
+   Returns the number of pixels on the line between the ending points. */
+CVAPI(int)  cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
+                                CvLineIterator* line_iterator,
+                                int connectivity CV_DEFAULT(8),
+                                int left_to_right CV_DEFAULT(0));
+
+/* Moves iterator to the next line point */
+#define CV_NEXT_LINE_POINT( line_iterator )                     \
+{                                                               \
+    int _line_iterator_mask = (line_iterator).err < 0 ? -1 : 0; \
+    (line_iterator).err += (line_iterator).minus_delta +        \
+        ((line_iterator).plus_delta & _line_iterator_mask);     \
+    (line_iterator).ptr += (line_iterator).minus_step +         \
+        ((line_iterator).plus_step & _line_iterator_mask);      \
+}
+
+
+/* basic font types */
+#define CV_FONT_HERSHEY_SIMPLEX         0
+#define CV_FONT_HERSHEY_PLAIN           1
+#define CV_FONT_HERSHEY_DUPLEX          2
+#define CV_FONT_HERSHEY_COMPLEX         3
+#define CV_FONT_HERSHEY_TRIPLEX         4
+#define CV_FONT_HERSHEY_COMPLEX_SMALL   5
+#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX  6
+#define CV_FONT_HERSHEY_SCRIPT_COMPLEX  7
+
+/* font flags */
+#define CV_FONT_ITALIC                 16
+
+#define CV_FONT_VECTOR0    CV_FONT_HERSHEY_SIMPLEX
+
+/* Font structure */
+typedef struct CvFont
+{
+    int         font_face; /* =CV_FONT_* */
+    const int*  ascii; /* font data and metrics */
+    const int*  greek;
+    const int*  cyrillic;
+    float       hscale, vscale;
+    float       shear; /* slope coefficient: 0 - normal, >0 - italic */
+    int         thickness; /* letters thickness */
+    float       dx; /* horizontal interval between letters */
+    int         line_type;
+}
+CvFont;
+
+/* Initializes font structure used further in cvPutText */
+CVAPI(void)  cvInitFont( CvFont* font, int font_face,
+                         double hscale, double vscale,
+                         double shear CV_DEFAULT(0),
+                         int thickness CV_DEFAULT(1),
+                         int line_type CV_DEFAULT(8));
+
+CV_INLINE CvFont cvFont( double scale, int thickness CV_DEFAULT(1) )
+{
+    CvFont font;
+    cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, scale, scale, 0, thickness, CV_AA );
+    return font;
+}
+
+/* Renders text stroke with specified font and color at specified location.
+   CvFont should be initialized with cvInitFont */
+CVAPI(void)  cvPutText( CvArr* img, const char* text, CvPoint org,
+                        const CvFont* font, CvScalar color );
+
+/* Calculates bounding box of text stroke (useful for alignment) */
+CVAPI(void)  cvGetTextSize( const char* text_string, const CvFont* font,
+                            CvSize* text_size, int* baseline );
+
+/* Unpacks color value, if arrtype is CV_8UC?, <color> is treated as
+   packed color value, otherwise the first channels (depending on arrtype)
+   of destination scalar are set to the same value = <color> */
+CVAPI(CvScalar)  cvColorToScalar( double packed_color, int arrtype );
+
+/* Returns the polygon points which make up the given ellipse.  The ellipse is define by
+   the box of size 'axes' rotated 'angle' around the 'center'.  A partial sweep
+   of the ellipse arc can be done by spcifying arc_start and arc_end to be something
+   other than 0 and 360, respectively.  The input array 'pts' must be large enough to
+   hold the result.  The total number of points stored into 'pts' is returned by this
+   function. */
+CVAPI(int) cvEllipse2Poly( CvPoint center, CvSize axes,
+                 int angle, int arc_start, int arc_end, CvPoint * pts, int delta );
+
+/* Draws contour outlines or filled interiors on the image */
+CVAPI(void)  cvDrawContours( CvArr *img, CvSeq* contour,
+                             CvScalar external_color, CvScalar hole_color,
+                             int max_level, int thickness CV_DEFAULT(1),
+                             int line_type CV_DEFAULT(8),
+                             CvPoint offset CV_DEFAULT(cvPoint(0,0)));
+
+/* Does look-up transformation. Elements of the source array
+   (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */
+CVAPI(void) cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );
+
+
+/******************* Iteration through the sequence tree *****************/
+typedef struct CvTreeNodeIterator
+{
+    const void* node;
+    int level;
+    int max_level;
+}
+CvTreeNodeIterator;
+
+CVAPI(void) cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator,
+                                   const void* first, int max_level );
+CVAPI(void*) cvNextTreeNode( CvTreeNodeIterator* tree_iterator );
+CVAPI(void*) cvPrevTreeNode( CvTreeNodeIterator* tree_iterator );
+
+/* Inserts sequence into tree with specified "parent" sequence.
+   If parent is equal to frame (e.g. the most external contour),
+   then added contour will have null pointer to parent. */
+CVAPI(void) cvInsertNodeIntoTree( void* node, void* parent, void* frame );
+
+/* Removes contour from tree (together with the contour children). */
+CVAPI(void) cvRemoveNodeFromTree( void* node, void* frame );
+
+/* Gathers pointers to all the sequences,
+   accessible from the <first>, to the single sequence */
+CVAPI(CvSeq*) cvTreeToNodeSeq( const void* first, int header_size,
+                              CvMemStorage* storage );
+
+/* The function implements the K-means algorithm for clustering an array of sample
+   vectors in a specified number of classes */
+#define CV_KMEANS_USE_INITIAL_LABELS    1
+CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels,
+                      CvTermCriteria termcrit, int attempts CV_DEFAULT(1),
+                      CvRNG* rng CV_DEFAULT(0), int flags CV_DEFAULT(0),
+                      CvArr* _centers CV_DEFAULT(0), double* compactness CV_DEFAULT(0) );
+
+/****************************************************************************************\
+*                                    System functions                                    *
+\****************************************************************************************/
+
+/* Add the function pointers table with associated information to the IPP primitives list */
+CVAPI(int)  cvRegisterModule( const CvModuleInfo* module_info );
+
+/* Loads optimized functions from IPP, MKL etc. or switches back to pure C code */
+CVAPI(int)  cvUseOptimized( int on_off );
+
+/* Retrieves information about the registered modules and loaded optimized plugins */
+CVAPI(void)  cvGetModuleInfo( const char* module_name,
+                              const char** version,
+                              const char** loaded_addon_plugins );
+
+/* Get current OpenCV error status */
+CVAPI(int) cvGetErrStatus( void );
+
+/* Sets error status silently */
+CVAPI(void) cvSetErrStatus( int status );
+
+#define CV_ErrModeLeaf     0   /* Print error and exit program */
+#define CV_ErrModeParent   1   /* Print error and continue */
+#define CV_ErrModeSilent   2   /* Don't print and continue */
+
+/* Retrives current error processing mode */
+CVAPI(int)  cvGetErrMode( void );
+
+/* Sets error processing mode, returns previously used mode */
+CVAPI(int) cvSetErrMode( int mode );
+
+/* Sets error status and performs some additonal actions (displaying message box,
+   writing message to stderr, terminating application etc.)
+   depending on the current error mode */
+CVAPI(void) cvError( int status, const char* func_name,
+                    const char* err_msg, const char* file_name, int line );
+
+/* Retrieves textual description of the error given its code */
+CVAPI(const char*) cvErrorStr( int status );
+
+/* Retrieves detailed information about the last error occured */
+CVAPI(int) cvGetErrInfo( const char** errcode_desc, const char** description,
+                        const char** filename, int* line );
+
+/* Maps IPP error codes to the counterparts from OpenCV */
+CVAPI(int) cvErrorFromIppStatus( int ipp_status );
+
+typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name,
+                    const char* err_msg, const char* file_name, int line, void* userdata );
+
+/* Assigns a new error-handling function */
+CVAPI(CvErrorCallback) cvRedirectError( CvErrorCallback error_handler,
+                                       void* userdata CV_DEFAULT(NULL),
+                                       void** prev_userdata CV_DEFAULT(NULL) );
+
+/*
+    Output to:
+        cvNulDevReport - nothing
+        cvStdErrReport - console(fprintf(stderr,...))
+        cvGuiBoxReport - MessageBox(WIN32)
+*/
+CVAPI(int) cvNulDevReport( int status, const char* func_name, const char* err_msg,
+                          const char* file_name, int line, void* userdata );
+
+CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_msg,
+                          const char* file_name, int line, void* userdata );
+
+CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg,
+                          const char* file_name, int line, void* userdata );
+
+typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata);
+typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata);
+
+/* Set user-defined memory managment functions (substitutors for malloc and free) that
+   will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage) */
+CVAPI(void) cvSetMemoryManager( CvAllocFunc alloc_func CV_DEFAULT(NULL),
+                               CvFreeFunc free_func CV_DEFAULT(NULL),
+                               void* userdata CV_DEFAULT(NULL));
+
+
+typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader)
+                            (int,int,int,char*,char*,int,int,int,int,int,
+                            IplROI*,IplImage*,void*,IplTileInfo*);
+typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int);
+typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int);
+typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int);
+typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*);
+
+/* Makes OpenCV use IPL functions for IplImage allocation/deallocation */
+CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
+                               Cv_iplAllocateImageData allocate_data,
+                               Cv_iplDeallocate deallocate,
+                               Cv_iplCreateROI create_roi,
+                               Cv_iplCloneImage clone_image );
+
+#define CV_TURN_ON_IPL_COMPATIBILITY()                                  \
+    cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage,         \
+                        iplDeallocate, iplCreateROI, iplCloneImage )
+
+/****************************************************************************************\
+*                                    Data Persistence                                    *
+\****************************************************************************************/
+
+/********************************** High-level functions ********************************/
+
+/* opens existing or creates new file storage */
+CVAPI(CvFileStorage*)  cvOpenFileStorage( const char* filename,
+                                          CvMemStorage* memstorage,
+                                          int flags );
+
+/* closes file storage and deallocates buffers */
+CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs );
+
+/* returns attribute value or 0 (NULL) if there is no such attribute */
+CVAPI(const char*) cvAttrValue( const CvAttrList* attr, const char* attr_name );
+
+/* starts writing compound structure (map or sequence) */
+CVAPI(void) cvStartWriteStruct( CvFileStorage* fs, const char* name,
+                                int struct_flags, const char* type_name CV_DEFAULT(NULL),
+                                CvAttrList attributes CV_DEFAULT(cvAttrList()));
+
+/* finishes writing compound structure */
+CVAPI(void) cvEndWriteStruct( CvFileStorage* fs );
+
+/* writes an integer */
+CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value );
+
+/* writes a floating-point number */
+CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value );
+
+/* writes a string */
+CVAPI(void) cvWriteString( CvFileStorage* fs, const char* name,
+                           const char* str, int quote CV_DEFAULT(0) );
+
+/* writes a comment */
+CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment,
+                            int eol_comment );
+
+/* writes instance of a standard type (matrix, image, sequence, graph etc.)
+   or user-defined type */
+CVAPI(void) cvWrite( CvFileStorage* fs, const char* name, const void* ptr,
+                         CvAttrList attributes CV_DEFAULT(cvAttrList()));
+
+/* starts the next stream */
+CVAPI(void) cvStartNextStream( CvFileStorage* fs );
+
+/* helper function: writes multiple integer or floating-point numbers */
+CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src,
+                                int len, const char* dt );
+
+/* returns the hash entry corresponding to the specified literal key string or 0
+   if there is no such a key in the storage */
+CVAPI(CvStringHashNode*) cvGetHashedKey( CvFileStorage* fs, const char* name,
+                                        int len CV_DEFAULT(-1),
+                                        int create_missing CV_DEFAULT(0));
+
+/* returns file node with the specified key within the specified map
+   (collection of named nodes) */
+CVAPI(CvFileNode*) cvGetRootFileNode( const CvFileStorage* fs,
+                                     int stream_index CV_DEFAULT(0) );
+
+/* returns file node with the specified key within the specified map
+   (collection of named nodes) */
+CVAPI(CvFileNode*) cvGetFileNode( CvFileStorage* fs, CvFileNode* map,
+                                 const CvStringHashNode* key,
+                                 int create_missing CV_DEFAULT(0) );
+
+/* this is a slower version of cvGetFileNode that takes the key as a literal string */
+CVAPI(CvFileNode*) cvGetFileNodeByName( const CvFileStorage* fs,
+                                       const CvFileNode* map,
+                                       const char* name );
+
+CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) )
+{
+    return !node ? default_value :
+        CV_NODE_IS_INT(node->tag) ? node->data.i :
+        CV_NODE_IS_REAL(node->tag) ? cvRound(node->data.f) : 0x7fffffff;
+}
+
+
+CV_INLINE int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map,
+                         const char* name, int default_value CV_DEFAULT(0) )
+{
+    return cvReadInt( cvGetFileNodeByName( fs, map, name ), default_value );
+}
+
+
+CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEFAULT(0.) )
+{
+    return !node ? default_value :
+        CV_NODE_IS_INT(node->tag) ? (double)node->data.i :
+        CV_NODE_IS_REAL(node->tag) ? node->data.f : 1e300;
+}
+
+
+CV_INLINE double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map,
+                        const char* name, double default_value CV_DEFAULT(0.) )
+{
+    return cvReadReal( cvGetFileNodeByName( fs, map, name ), default_value );
+}
+
+
+CV_INLINE const char* cvReadString( const CvFileNode* node,
+                        const char* default_value CV_DEFAULT(NULL) )
+{
+    return !node ? default_value : CV_NODE_IS_STRING(node->tag) ? node->data.str.ptr : 0;
+}
+
+
+CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map,
+                        const char* name, const char* default_value CV_DEFAULT(NULL) )
+{
+    return cvReadString( cvGetFileNodeByName( fs, map, name ), default_value );
+}
+
+
+/* decodes standard or user-defined object and returns it */
+CVAPI(void*) cvRead( CvFileStorage* fs, CvFileNode* node,
+                        CvAttrList* attributes CV_DEFAULT(NULL));
+
+/* decodes standard or user-defined object and returns it */
+CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map,
+                              const char* name, CvAttrList* attributes CV_DEFAULT(NULL) )
+{
+    return cvRead( fs, cvGetFileNodeByName( fs, map, name ), attributes );
+}
+
+
+/* starts reading data from sequence or scalar numeric node */
+CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src,
+                               CvSeqReader* reader );
+
+/* reads multiple numbers and stores them to array */
+CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
+                               int count, void* dst, const char* dt );
+
+/* combination of two previous functions for easier reading of whole sequences */
+CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src,
+                          void* dst, const char* dt );
+
+/* writes a copy of file node to file storage */
+CVAPI(void) cvWriteFileNode( CvFileStorage* fs, const char* new_node_name,
+                            const CvFileNode* node, int embed );
+
+/* returns name of file node */
+CVAPI(const char*) cvGetFileNodeName( const CvFileNode* node );
+
+/*********************************** Adding own types ***********************************/
+
+CVAPI(void) cvRegisterType( const CvTypeInfo* info );
+CVAPI(void) cvUnregisterType( const char* type_name );
+CVAPI(CvTypeInfo*) cvFirstType(void);
+CVAPI(CvTypeInfo*) cvFindType( const char* type_name );
+CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr );
+
+/* universal functions */
+CVAPI(void) cvRelease( void** struct_ptr );
+CVAPI(void*) cvClone( const void* struct_ptr );
+
+/* simple API for reading/writing data */
+CVAPI(void) cvSave( const char* filename, const void* struct_ptr,
+                    const char* name CV_DEFAULT(NULL),
+                    const char* comment CV_DEFAULT(NULL),
+                    CvAttrList attributes CV_DEFAULT(cvAttrList()));
+CVAPI(void*) cvLoad( const char* filename,
+                     CvMemStorage* memstorage CV_DEFAULT(NULL),
+                     const char* name CV_DEFAULT(NULL),
+                     const char** real_name CV_DEFAULT(NULL) );
+
+/*********************************** Measuring Execution Time ***************************/
+
+/* helper functions for RNG initialization and accurate time measurement:
+   uses internal clock counter on x86 */
+CVAPI(int64)  cvGetTickCount( void );
+CVAPI(double) cvGetTickFrequency( void );
+
+/*********************************** Multi-Threading ************************************/
+
+/* retrieve/set the number of threads used in OpenMP implementations */
+CVAPI(int)  cvGetNumThreads( void );
+CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) );
+/* get index of the thread being executed */
+CVAPI(int)  cvGetThreadNum( void );
+
+/*************** Convenience functions for better interaction with HighGUI **************/
+
+typedef IplImage* (CV_CDECL * CvLoadImageFunc)( const char* filename, int colorness );
+typedef CvMat* (CV_CDECL * CvLoadImageMFunc)( const char* filename, int colorness );
+typedef int (CV_CDECL * CvSaveImageFunc)( const char* filename, const CvArr* image );
+typedef void (CV_CDECL * CvShowImageFunc)( const char* windowname, const CvArr* image );
+
+CVAPI(int) cvSetImageIOFunctions( CvLoadImageFunc _load_image, CvLoadImageMFunc _load_image_m,
+                            CvSaveImageFunc _save_image, CvShowImageFunc _show_image );
+
+#define CV_SET_IMAGE_IO_FUNCTIONS() \
+    cvSetImageIOFunctions( cvLoadImage, cvLoadImageM, cvSaveImage, cvShowImage )
+
+#ifdef __cplusplus
+}
+
+class CV_EXPORTS CvImage
+{
+public:
+    CvImage() : image(0), refcount(0) {}
+    CvImage( CvSize size, int depth, int channels )
+    {
+        image = cvCreateImage( size, depth, channels );
+        refcount = image ? new int(1) : 0;
+    }
+
+    CvImage( IplImage* img ) : image(img)
+    {
+        refcount = image ? new int(1) : 0;
+    }
+
+    CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
+    {
+        if( refcount ) ++(*refcount);
+    }
+
+    CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
+    { load( filename, imgname, color ); }
+
+    CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
+    { read( fs, mapname, imgname ); }
+
+    CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
+    { read( fs, seqname, idx ); }
+
+    ~CvImage()
+    {
+        if( refcount && !(--*refcount) )
+        {
+            cvReleaseImage( &image );
+            delete refcount;
+        }
+    }
+
+    CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
+
+    void create( CvSize size, int depth, int channels )
+    {
+        if( !image || !refcount ||
+            image->width != size.width || image->height != size.height ||
+            image->depth != depth || image->nChannels != channels )
+            attach( cvCreateImage( size, depth, channels ));
+    }
+
+    void release() { detach(); }
+    void clear() { detach(); }
+
+    void attach( IplImage* img, bool use_refcount=true )
+    {
+        if( refcount && --*refcount == 0 )
+        {
+            cvReleaseImage( &image );
+            delete refcount;
+        }
+        image = img;
+        refcount = use_refcount && image ? new int(1) : 0;
+    }
+
+    void detach()
+    {
+        if( refcount && --*refcount == 0 )
+        {
+            cvReleaseImage( &image );
+            delete refcount;
+        }
+        image = 0;
+        refcount = 0;
+    }
+
+    bool load( const char* filename, const char* imgname=0, int color=-1 );
+    bool read( CvFileStorage* fs, const char* mapname, const char* imgname );
+    bool read( CvFileStorage* fs, const char* seqname, int idx );
+    void save( const char* filename, const char* imgname );
+    void write( CvFileStorage* fs, const char* imgname );
+
+    void show( const char* window_name );
+    bool is_valid() { return image != 0; }
+
+    int width() const { return image ? image->width : 0; }
+    int height() const { return image ? image->height : 0; }
+
+    CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
+
+    CvSize roi_size() const
+    {
+        return !image ? cvSize(0,0) :
+            !image->roi ? cvSize(image->width,image->height) :
+            cvSize(image->roi->width, image->roi->height);
+    }
+
+    CvRect roi() const
+    {
+        return !image ? cvRect(0,0,0,0) :
+            !image->roi ? cvRect(0,0,image->width,image->height) :
+            cvRect(image->roi->xOffset,image->roi->yOffset,
+                   image->roi->width,image->roi->height);
+    }
+
+    int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
+
+    void set_roi(CvRect roi) { cvSetImageROI(image,roi); }
+    void reset_roi() { cvResetImageROI(image); }
+    void set_coi(int coi) { cvSetImageCOI(image,coi); }
+    int depth() const { return image ? image->depth : 0; }
+    int channels() const { return image ? image->nChannels : 0; }
+    int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
+
+    uchar* data() { return image ? (uchar*)image->imageData : 0; }
+    const uchar* data() const { return image ? (const uchar*)image->imageData : 0; }
+    int step() const { return image ? image->widthStep : 0; }
+    int origin() const { return image ? image->origin : 0; }
+
+    uchar* roi_row(int y)
+    {
+        assert(0<=y);
+        assert(!image ?
+                1 : image->roi ?
+                y<image->roi->height : y<image->height);
+        
+        return !image ? 0 :
+            !image->roi ?
+                (uchar*)(image->imageData + y*image->widthStep) :
+                (uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
+                image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
+    }
+
+    const uchar* roi_row(int y) const
+    {
+        assert(0<=y);
+        assert(!image ?
+                1 : image->roi ?
+                y<image->roi->height : y<image->height); 
+
+        return !image ? 0 :
+            !image->roi ?
+                (const uchar*)(image->imageData + y*image->widthStep) :
+                (const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
+                image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
+    }
+
+    operator const IplImage* () const { return image; }
+    operator IplImage* () { return image; }
+
+    CvImage& operator = (const CvImage& img)
+    {
+        if( img.refcount )
+            ++*img.refcount;
+        if( refcount && !(--*refcount) )
+            cvReleaseImage( &image );
+        image=img.image;
+        refcount=img.refcount;
+        return *this;
+    }
+
+protected:
+    IplImage* image;
+    int* refcount;
+};
+
+
+class CV_EXPORTS CvMatrix
+{
+public:
+    CvMatrix() : matrix(0) {}
+    CvMatrix( int rows, int cols, int type )
+    { matrix = cvCreateMat( rows, cols, type ); }
+
+    CvMatrix( int rows, int cols, int type, CvMat* hdr,
+              void* data=0, int step=CV_AUTOSTEP )
+    { matrix = cvInitMatHeader( hdr, rows, cols, type, data, step ); }
+
+    CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
+
+    CvMatrix( int rows, int cols, int type, void* data, int step=CV_AUTOSTEP )
+    { matrix = cvCreateMatHeader( rows, cols, type );
+      cvSetData( matrix, data, step ); }
+
+    CvMatrix( CvMat* m )
+    { matrix = m; }
+
+    CvMatrix( const CvMatrix& m )
+    {
+        matrix = m.matrix;
+        addref();
+    }
+
+    CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
+    {  load( filename, matname, color ); }
+
+    CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
+    {  read( fs, mapname, matname ); }
+
+    CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
+    {  read( fs, seqname, idx ); }
+
+    ~CvMatrix()
+    {
+        release();
+    }
+
+    CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
+
+    void set( CvMat* m, bool add_ref )
+    {
+        release();
+        matrix = m;
+        if( add_ref )
+            addref();
+    }
+
+    void create( int rows, int cols, int type )
+    {
+        if( !matrix || !matrix->refcount ||
+            matrix->rows != rows || matrix->cols != cols ||
+            CV_MAT_TYPE(matrix->type) != type )
+            set( cvCreateMat( rows, cols, type ), false );
+    }
+
+    void addref() const
+    {
+        if( matrix )
+        {
+            if( matrix->hdr_refcount )
+                ++matrix->hdr_refcount;
+            else if( matrix->refcount )
+                ++*matrix->refcount;
+        }
+    }
+
+    void release()
+    {
+        if( matrix )
+        {
+            if( matrix->hdr_refcount )
+            {
+                if( --matrix->hdr_refcount == 0 )
+                    cvReleaseMat( &matrix );
+            }
+            else if( matrix->refcount )
+            {
+                if( --*matrix->refcount == 0 )
+                    cvFree( &matrix->refcount );
+            }
+            matrix = 0;
+        }
+    }
+
+    void clear()
+    {
+        release();
+    }
+
+    bool load( const char* filename, const char* matname=0, int color=-1 );
+    bool read( CvFileStorage* fs, const char* mapname, const char* matname );
+    bool read( CvFileStorage* fs, const char* seqname, int idx );
+    void save( const char* filename, const char* matname );
+    void write( CvFileStorage* fs, const char* matname );
+
+    void show( const char* window_name );
+
+    bool is_valid() { return matrix != 0; }
+
+    int rows() const { return matrix ? matrix->rows : 0; }
+    int cols() const { return matrix ? matrix->cols : 0; }
+
+    CvSize size() const
+    {
+        return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
+    }
+
+    int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; }
+    int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; }
+    int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; }
+    int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; }
+
+    uchar* data() { return matrix ? matrix->data.ptr : 0; }
+    const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
+    int step() const { return matrix ? matrix->step : 0; }
+
+    void set_data( void* data, int step=CV_AUTOSTEP )
+    { cvSetData( matrix, data, step ); }
+
+    uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
+    const uchar* row(int i) const
+    { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
+
+    operator const CvMat* () const { return matrix; }
+    operator CvMat* () { return matrix; }
+
+    CvMatrix& operator = (const CvMatrix& _m)
+    {
+        _m.addref();
+        release();
+        matrix = _m.matrix;
+        return *this;
+    }
+
+protected:
+    CvMat* matrix;
+};
+
+
+// classes for automatic module/RTTI data registration/unregistration
+struct CV_EXPORTS CvModule
+{
+    CvModule( CvModuleInfo* _info );
+    ~CvModule();
+    CvModuleInfo* info;
+
+    static CvModuleInfo* first;
+    static CvModuleInfo* last;
+};
+
+struct CV_EXPORTS CvType
+{
+    CvType( const char* type_name,
+            CvIsInstanceFunc is_instance, CvReleaseFunc release=0,
+            CvReadFunc read=0, CvWriteFunc write=0, CvCloneFunc clone=0 );
+    ~CvType();
+    CvTypeInfo* info;
+
+    static CvTypeInfo* first;
+    static CvTypeInfo* last;
+};
+
+#endif
+
+#endif /*_CXCOMPAT_H_*/
index 26ee21cd2c1c0638cfbcd17f236fa1ba50b69d08..652efb7b911db02863f71238050d3fbd4328d424 100644 (file)
-/*M///////////////////////////////////////////////////////////////////////////////////////
-//
-//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-//  By downloading, copying, installing or using the software you agree to this license.
-//  If you do not agree to this license, do not download, install,
-//  copy or use the software.
-//
-//
-//                        Intel License Agreement
-//                For Open Source Computer Vision Library
-//
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-//   * Redistribution's of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//
-//   * Redistribution's in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//
-//   * The name of Intel Corporation may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
-
-
-#ifndef _CXCORE_H_
-#define _CXCORE_H_
-
-#ifdef __IPL_H__
-#define HAVE_IPL
-#endif
-
-#ifndef SKIP_INCLUDES
-  #if defined HAVE_IPL && !defined __IPL_H__
-    #ifndef _INC_WINDOWS
-        #define CV_PRETEND_WINDOWS
-        #define _INC_WINDOWS
-        typedef struct tagBITMAPINFOHEADER BITMAPINFOHEADER;
-        typedef int BOOL;
-    #endif
-    #if defined WIN32 || defined WIN64
-      #include "ipl.h"
-    #else
-      #include "ipl/ipl.h"
-    #endif
-    #ifdef CV_PRETEND_WINDOWS
-        #undef _INC_WINDOWS
-    #endif
-  #endif
-#endif // SKIP_INCLUDES
-
-#include "cxtypes.h"
-#include "cxerror.h"
-#include "cvver.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/****************************************************************************************\
-*          Array allocation, deallocation, initialization and access to elements         *
-\****************************************************************************************/
-
-/* <malloc> wrapper.
-   If there is no enough memory, the function
-   (as well as other OpenCV functions that call cvAlloc)
-   raises an error. */
-CVAPI(void*)  cvAlloc( size_t size );
-
-/* <free> wrapper.
-   Here and further all the memory releasing functions
-   (that all call cvFree) take double pointer in order to
-   to clear pointer to the data after releasing it.
-   Passing pointer to NULL pointer is Ok: nothing happens in this case
-*/
-CVAPI(void)   cvFree_( void* ptr );
-#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0)
-
-/* Allocates and initializes IplImage header */
-CVAPI(IplImage*)  cvCreateImageHeader( CvSize size, int depth, int channels );
-
-/* Inializes IplImage header */
-CVAPI(IplImage*) cvInitImageHeader( IplImage* image, CvSize size, int depth,
-                                   int channels, int origin CV_DEFAULT(0),
-                                   int align CV_DEFAULT(4));
-
-/* Creates IPL image (header and data) */
-CVAPI(IplImage*)  cvCreateImage( CvSize size, int depth, int channels );
-
-/* Releases (i.e. deallocates) IPL image header */
-CVAPI(void)  cvReleaseImageHeader( IplImage** image );
-
-/* Releases IPL image header and data */
-CVAPI(void)  cvReleaseImage( IplImage** image );
-
-/* Creates a copy of IPL image (widthStep may differ) */
-CVAPI(IplImage*) cvCloneImage( const IplImage* image );
-
-/* Sets a Channel Of Interest (only a few functions support COI) -
-   use cvCopy to extract the selected channel and/or put it back */
-CVAPI(void)  cvSetImageCOI( IplImage* image, int coi );
-
-/* Retrieves image Channel Of Interest */
-CVAPI(int)  cvGetImageCOI( const IplImage* image );
-
-/* Sets image ROI (region of interest) (COI is not changed) */
-CVAPI(void)  cvSetImageROI( IplImage* image, CvRect rect );
-
-/* Resets image ROI and COI */
-CVAPI(void)  cvResetImageROI( IplImage* image );
-
-/* Retrieves image ROI */
-CVAPI(CvRect) cvGetImageROI( const IplImage* image );
-
-/* Allocates and initalizes CvMat header */
-CVAPI(CvMat*)  cvCreateMatHeader( int rows, int cols, int type );
-
-#define CV_AUTOSTEP  0x7fffffff
-
-/* Initializes CvMat header */
-CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols,
-                              int type, void* data CV_DEFAULT(NULL),
-                              int step CV_DEFAULT(CV_AUTOSTEP) );
-
-/* Allocates and initializes CvMat header and allocates data */
-CVAPI(CvMat*)  cvCreateMat( int rows, int cols, int type );
-
-/* Releases CvMat header and deallocates matrix data
-   (reference counting is used for data) */
-CVAPI(void)  cvReleaseMat( CvMat** mat );
-
-/* Decrements CvMat data reference counter and deallocates the data if
-   it reaches 0 */
-CV_INLINE  void  cvDecRefData( CvArr* arr )
-{
-    if( CV_IS_MAT( arr ))
-    {
-        CvMat* mat = (CvMat*)arr;
-        mat->data.ptr = NULL;
-        if( mat->refcount != NULL && --*mat->refcount == 0 )
-            cvFree( &mat->refcount );
-        mat->refcount = NULL;
-    }
-    else if( CV_IS_MATND( arr ))
-    {
-        CvMatND* mat = (CvMatND*)arr;
-        mat->data.ptr = NULL;
-        if( mat->refcount != NULL && --*mat->refcount == 0 )
-            cvFree( &mat->refcount );
-        mat->refcount = NULL;
-    }
-}
-
-/* Increments CvMat data reference counter */
-CV_INLINE  int  cvIncRefData( CvArr* arr )
-{
-    int refcount = 0;
-    if( CV_IS_MAT( arr ))
-    {
-        CvMat* mat = (CvMat*)arr;
-        if( mat->refcount != NULL )
-            refcount = ++*mat->refcount;
-    }
-    else if( CV_IS_MATND( arr ))
-    {
-        CvMatND* mat = (CvMatND*)arr;
-        if( mat->refcount != NULL )
-            refcount = ++*mat->refcount;
-    }
-    return refcount;
-}
-
-
-/* Creates an exact copy of the input matrix (except, may be, step value) */
-CVAPI(CvMat*) cvCloneMat( const CvMat* mat );
-
-
-/* Makes a new matrix from <rect> subrectangle of input array.
-   No data is copied */
-CVAPI(CvMat*) cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );
-#define cvGetSubArr cvGetSubRect
-
-/* Selects row span of the input array: arr(start_row:delta_row:end_row,:)
-    (end_row is not included into the span). */
-CVAPI(CvMat*) cvGetRows( const CvArr* arr, CvMat* submat,
-                        int start_row, int end_row,
-                        int delta_row CV_DEFAULT(1));
-
-CV_INLINE  CvMat*  cvGetRow( const CvArr* arr, CvMat* submat, int row )
-{
-    return cvGetRows( arr, submat, row, row + 1, 1 );
-}
-
-
-/* Selects column span of the input array: arr(:,start_col:end_col)
-   (end_col is not included into the span) */
-CVAPI(CvMat*) cvGetCols( const CvArr* arr, CvMat* submat,
-                        int start_col, int end_col );
-
-CV_INLINE  CvMat*  cvGetCol( const CvArr* arr, CvMat* submat, int col )
-{
-    return cvGetCols( arr, submat, col, col + 1 );
-}
-
-/* Select a diagonal of the input array.
-   (diag = 0 means the main diagonal, >0 means a diagonal above the main one,
-   <0 - below the main one).
-   The diagonal will be represented as a column (nx1 matrix). */
-CVAPI(CvMat*) cvGetDiag( const CvArr* arr, CvMat* submat,
-                            int diag CV_DEFAULT(0));
-
-/* low-level scalar <-> raw data conversion functions */
-CVAPI(void) cvScalarToRawData( const CvScalar* scalar, void* data, int type,
-                              int extend_to_12 CV_DEFAULT(0) );
-
-CVAPI(void) cvRawDataToScalar( const void* data, int type, CvScalar* scalar );
-
-/* Allocates and initializes CvMatND header */
-CVAPI(CvMatND*)  cvCreateMatNDHeader( int dims, const int* sizes, int type );
-
-/* Allocates and initializes CvMatND header and allocates data */
-CVAPI(CvMatND*)  cvCreateMatND( int dims, const int* sizes, int type );
-
-/* Initializes preallocated CvMatND header */
-CVAPI(CvMatND*)  cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
-                                    int type, void* data CV_DEFAULT(NULL) );
-
-/* Releases CvMatND */
-CV_INLINE  void  cvReleaseMatND( CvMatND** mat )
-{
-    cvReleaseMat( (CvMat**)mat );
-}
-
-/* Creates a copy of CvMatND (except, may be, steps) */
-CVAPI(CvMatND*) cvCloneMatND( const CvMatND* mat );
-
-/* Allocates and initializes CvSparseMat header and allocates data */
-CVAPI(CvSparseMat*)  cvCreateSparseMat( int dims, const int* sizes, int type );
-
-/* Releases CvSparseMat */
-CVAPI(void)  cvReleaseSparseMat( CvSparseMat** mat );
-
-/* Creates a copy of CvSparseMat (except, may be, zero items) */
-CVAPI(CvSparseMat*) cvCloneSparseMat( const CvSparseMat* mat );
-
-/* Initializes sparse array iterator
-   (returns the first node or NULL if the array is empty) */
-CVAPI(CvSparseNode*) cvInitSparseMatIterator( const CvSparseMat* mat,
-                                              CvSparseMatIterator* mat_iterator );
-
-// returns next sparse array node (or NULL if there is no more nodes)
-CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator )
-{
-    if( mat_iterator->node->next )
-        return mat_iterator->node = mat_iterator->node->next;
-    else
-    {
-        int idx;
-        for( idx = ++mat_iterator->curidx; idx < mat_iterator->mat->hashsize; idx++ )
-        {
-            CvSparseNode* node = (CvSparseNode*)mat_iterator->mat->hashtable[idx];
-            if( node )
-            {
-                mat_iterator->curidx = idx;
-                return mat_iterator->node = node;
-            }
-        }
-        return NULL;
-    }
-}
-
-/**************** matrix iterator: used for n-ary operations on dense arrays *********/
-
-#define CV_MAX_ARR 10
-
-typedef struct CvNArrayIterator
-{
-    int count; /* number of arrays */
-    int dims; /* number of dimensions to iterate */
-    CvSize size; /* maximal common linear size: { width = size, height = 1 } */
-    uchar* ptr[CV_MAX_ARR]; /* pointers to the array slices */
-    int stack[CV_MAX_DIM]; /* for internal use */
-    CvMatND* hdr[CV_MAX_ARR]; /* pointers to the headers of the
-                                 matrices that are processed */
-}
-CvNArrayIterator;
-
-#define CV_NO_DEPTH_CHECK     1
-#define CV_NO_CN_CHECK        2
-#define CV_NO_SIZE_CHECK      4
-
-/* initializes iterator that traverses through several arrays simulteneously
-   (the function together with cvNextArraySlice is used for
-    N-ari element-wise operations) */
-CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs,
-                                 const CvArr* mask, CvMatND* stubs,
-                                 CvNArrayIterator* array_iterator,
-                                 int flags CV_DEFAULT(0) );
-
-/* returns zero value if iteration is finished, non-zero (slice length) otherwise */
-CVAPI(int) cvNextNArraySlice( CvNArrayIterator* array_iterator );
-
-
-/* Returns type of array elements:
-   CV_8UC1 ... CV_64FC4 ... */
-CVAPI(int) cvGetElemType( const CvArr* arr );
-
-/* Retrieves number of an array dimensions and
-   optionally sizes of the dimensions */
-CVAPI(int) cvGetDims( const CvArr* arr, int* sizes CV_DEFAULT(NULL) );
-
-
-/* Retrieves size of a particular array dimension.
-   For 2d arrays cvGetDimSize(arr,0) returns number of rows (image height)
-   and cvGetDimSize(arr,1) returns number of columns (image width) */
-CVAPI(int) cvGetDimSize( const CvArr* arr, int index );
-
-
-/* ptr = &arr(idx0,idx1,...). All indexes are zero-based,
-   the major dimensions go first (e.g. (y,x) for 2D, (z,y,x) for 3D */
-CVAPI(uchar*) cvPtr1D( const CvArr* arr, int idx0, int* type CV_DEFAULT(NULL));
-CVAPI(uchar*) cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type CV_DEFAULT(NULL) );
-CVAPI(uchar*) cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2,
-                      int* type CV_DEFAULT(NULL));
-
-/* For CvMat or IplImage number of indices should be 2
-   (row index (y) goes first, column index (x) goes next).
-   For CvMatND or CvSparseMat number of infices should match number of <dims> and
-   indices order should match the array dimension order. */
-CVAPI(uchar*) cvPtrND( const CvArr* arr, const int* idx, int* type CV_DEFAULT(NULL),
-                      int create_node CV_DEFAULT(1),
-                      unsigned* precalc_hashval CV_DEFAULT(NULL));
-
-/* value = arr(idx0,idx1,...) */
-CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 );
-CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 );
-CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
-CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx );
-
-/* for 1-channel arrays */
-CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 );
-CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
-CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
-CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx );
-
-/* arr(idx0,idx1,...) = value */
-CVAPI(void) cvSet1D( CvArr* arr, int idx0, CvScalar value );
-CVAPI(void) cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
-CVAPI(void) cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
-CVAPI(void) cvSetND( CvArr* arr, const int* idx, CvScalar value );
-
-/* for 1-channel arrays */
-CVAPI(void) cvSetReal1D( CvArr* arr, int idx0, double value );
-CVAPI(void) cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );
-CVAPI(void) cvSetReal3D( CvArr* arr, int idx0,
-                        int idx1, int idx2, double value );
-CVAPI(void) cvSetRealND( CvArr* arr, const int* idx, double value );
-
-/* clears element of ND dense array,
-   in case of sparse arrays it deletes the specified node */
-CVAPI(void) cvClearND( CvArr* arr, const int* idx );
-
-/* Converts CvArr (IplImage or CvMat,...) to CvMat.
-   If the last parameter is non-zero, function can
-   convert multi(>2)-dimensional array to CvMat as long as
-   the last array's dimension is continous. The resultant
-   matrix will be have appropriate (a huge) number of rows */
-CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header,
-                       int* coi CV_DEFAULT(NULL),
-                       int allowND CV_DEFAULT(0));
-
-/* Converts CvArr (IplImage or CvMat) to IplImage */
-CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header );
-
-
-/* Changes a shape of multi-dimensional array.
-   new_cn == 0 means that number of channels remains unchanged.
-   new_dims == 0 means that number and sizes of dimensions remain the same
-   (unless they need to be changed to set the new number of channels)
-   if new_dims == 1, there is no need to specify new dimension sizes
-   The resultant configuration should be achievable w/o data copying.
-   If the resultant array is sparse, CvSparseMat header should be passed
-   to the function else if the result is 1 or 2 dimensional,
-   CvMat header should be passed to the function
-   else CvMatND header should be passed */
-CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr,
-                             int sizeof_header, CvArr* header,
-                             int new_cn, int new_dims, int* new_sizes );
-
-#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes )   \
-      cvReshapeMatND( (arr), sizeof(*(header)), (header),         \
-                      (new_cn), (new_dims), (new_sizes))
-
-CVAPI(CvMat*) cvReshape( const CvArr* arr, CvMat* header,
-                        int new_cn, int new_rows CV_DEFAULT(0) );
-
-/* Repeats source 2d array several times in both horizontal and
-   vertical direction to fill destination array */
-CVAPI(void) cvRepeat( const CvArr* src, CvArr* dst );
-
-/* Allocates array data */
-CVAPI(void)  cvCreateData( CvArr* arr );
-
-/* Releases array data */
-CVAPI(void)  cvReleaseData( CvArr* arr );
-
-/* Attaches user data to the array header. The step is reffered to
-   the pre-last dimension. That is, all the planes of the array
-   must be joint (w/o gaps) */
-CVAPI(void)  cvSetData( CvArr* arr, void* data, int step );
-
-/* Retrieves raw data of CvMat, IplImage or CvMatND.
-   In the latter case the function raises an error if
-   the array can not be represented as a matrix */
-CVAPI(void) cvGetRawData( const CvArr* arr, uchar** data,
-                         int* step CV_DEFAULT(NULL),
-                         CvSize* roi_size CV_DEFAULT(NULL));
-
-/* Returns width and height of array in elements */
-CVAPI(CvSize) cvGetSize( const CvArr* arr );
-
-/* Copies source array to destination array */
-CVAPI(void)  cvCopy( const CvArr* src, CvArr* dst,
-                     const CvArr* mask CV_DEFAULT(NULL) );
-
-/* Sets all or "masked" elements of input array
-   to the same value*/
-CVAPI(void)  cvSet( CvArr* arr, CvScalar value,
-                    const CvArr* mask CV_DEFAULT(NULL) );
-
-/* Clears all the array elements (sets them to 0) */
-CVAPI(void)  cvSetZero( CvArr* arr );
-#define cvZero  cvSetZero
-
-
-/* Splits a multi-channel array into the set of single-channel arrays or
-   extracts particular [color] plane */
-CVAPI(void)  cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,
-                      CvArr* dst2, CvArr* dst3 );
-
-/* Merges a set of single-channel arrays into the single multi-channel array
-   or inserts one particular [color] plane to the array */
-CVAPI(void)  cvMerge( const CvArr* src0, const CvArr* src1,
-                      const CvArr* src2, const CvArr* src3,
-                      CvArr* dst );
-
-/* Copies several channels from input arrays to
-   certain channels of output arrays */
-CVAPI(void)  cvMixChannels( const CvArr** src, int src_count,
-                            CvArr** dst, int dst_count,
-                            const int* from_to, int pair_count );
-
-/* Performs linear transformation on every source array element:
-   dst(x,y,c) = scale*src(x,y,c)+shift.
-   Arbitrary combination of input and output array depths are allowed
-   (number of channels must be the same), thus the function can be used
-   for type conversion */
-CVAPI(void)  cvConvertScale( const CvArr* src, CvArr* dst,
-                             double scale CV_DEFAULT(1),
-                             double shift CV_DEFAULT(0) );
-#define cvCvtScale cvConvertScale
-#define cvScale  cvConvertScale
-#define cvConvert( src, dst )  cvConvertScale( (src), (dst), 1, 0 )
-
-
-/* Performs linear transformation on every source array element,
-   stores absolute value of the result:
-   dst(x,y,c) = abs(scale*src(x,y,c)+shift).
-   destination array must have 8u type.
-   In other cases one may use cvConvertScale + cvAbsDiffS */
-CVAPI(void)  cvConvertScaleAbs( const CvArr* src, CvArr* dst,
-                                double scale CV_DEFAULT(1),
-                                double shift CV_DEFAULT(0) );
-#define cvCvtScaleAbs  cvConvertScaleAbs
-
-
-/* checks termination criteria validity and
-   sets eps to default_eps (if it is not set),
-   max_iter to default_max_iters (if it is not set)
-*/
-CVAPI(CvTermCriteria) cvCheckTermCriteria( CvTermCriteria criteria,
-                                           double default_eps,
-                                           int default_max_iters );
-
-/****************************************************************************************\
-*                   Arithmetic, logic and comparison operations                          *
-\****************************************************************************************/
-
-/* dst(mask) = src1(mask) + src2(mask) */
-CVAPI(void)  cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst,
-                    const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(mask) = src(mask) + value */
-CVAPI(void)  cvAddS( const CvArr* src, CvScalar value, CvArr* dst,
-                     const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(mask) = src1(mask) - src2(mask) */
-CVAPI(void)  cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst,
-                    const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(mask) = src(mask) - value = src(mask) + (-value) */
-CV_INLINE  void  cvSubS( const CvArr* src, CvScalar value, CvArr* dst,
-                         const CvArr* mask CV_DEFAULT(NULL))
-{
-    cvAddS( src, cvScalar( -value.val[0], -value.val[1], -value.val[2], -value.val[3]),
-            dst, mask );
-}
-
-/* dst(mask) = value - src(mask) */
-CVAPI(void)  cvSubRS( const CvArr* src, CvScalar value, CvArr* dst,
-                      const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = src1(idx) * src2(idx) * scale
-   (scaled element-wise multiplication of 2 arrays) */
-CVAPI(void)  cvMul( const CvArr* src1, const CvArr* src2,
-                    CvArr* dst, double scale CV_DEFAULT(1) );
-
-/* element-wise division/inversion with scaling:
-    dst(idx) = src1(idx) * scale / src2(idx)
-    or dst(idx) = scale / src2(idx) if src1 == 0 */
-CVAPI(void)  cvDiv( const CvArr* src1, const CvArr* src2,
-                    CvArr* dst, double scale CV_DEFAULT(1));
-
-/* dst = src1 * scale + src2 */
-CVAPI(void)  cvScaleAdd( const CvArr* src1, CvScalar scale,
-                         const CvArr* src2, CvArr* dst );
-#define cvAXPY( A, real_scalar, B, C ) cvScaleAdd(A, cvRealScalar(real_scalar), B, C)
-
-/* dst = src1 * alpha + src2 * beta + gamma */
-CVAPI(void)  cvAddWeighted( const CvArr* src1, double alpha,
-                            const CvArr* src2, double beta,
-                            double gamma, CvArr* dst );
-
-/* result = sum_i(src1(i) * src2(i)) (results for all channels are accumulated together) */
-CVAPI(double)  cvDotProduct( const CvArr* src1, const CvArr* src2 );
-
-/* dst(idx) = src1(idx) & src2(idx) */
-CVAPI(void) cvAnd( const CvArr* src1, const CvArr* src2,
-                  CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = src(idx) & value */
-CVAPI(void) cvAndS( const CvArr* src, CvScalar value,
-                   CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = src1(idx) | src2(idx) */
-CVAPI(void) cvOr( const CvArr* src1, const CvArr* src2,
-                 CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = src(idx) | value */
-CVAPI(void) cvOrS( const CvArr* src, CvScalar value,
-                  CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = src1(idx) ^ src2(idx) */
-CVAPI(void) cvXor( const CvArr* src1, const CvArr* src2,
-                  CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = src(idx) ^ value */
-CVAPI(void) cvXorS( const CvArr* src, CvScalar value,
-                   CvArr* dst, const CvArr* mask CV_DEFAULT(NULL));
-
-/* dst(idx) = ~src(idx) */
-CVAPI(void) cvNot( const CvArr* src, CvArr* dst );
-
-/* dst(idx) = lower(idx) <= src(idx) < upper(idx) */
-CVAPI(void) cvInRange( const CvArr* src, const CvArr* lower,
-                      const CvArr* upper, CvArr* dst );
-
-/* dst(idx) = lower <= src(idx) < upper */
-CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower,
-                       CvScalar upper, CvArr* dst );
-
-#define CV_CMP_EQ   0
-#define CV_CMP_GT   1
-#define CV_CMP_GE   2
-#define CV_CMP_LT   3
-#define CV_CMP_LE   4
-#define CV_CMP_NE   5
-
-/* The comparison operation support single-channel arrays only.
-   Destination image should be 8uC1 or 8sC1 */
-
-/* dst(idx) = src1(idx) _cmp_op_ src2(idx) */
-CVAPI(void) cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );
-
-/* dst(idx) = src1(idx) _cmp_op_ value */
-CVAPI(void) cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );
-
-/* dst(idx) = min(src1(idx),src2(idx)) */
-CVAPI(void) cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );
-
-/* dst(idx) = max(src1(idx),src2(idx)) */
-CVAPI(void) cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );
-
-/* dst(idx) = min(src(idx),value) */
-CVAPI(void) cvMinS( const CvArr* src, double value, CvArr* dst );
-
-/* dst(idx) = max(src(idx),value) */
-CVAPI(void) cvMaxS( const CvArr* src, double value, CvArr* dst );
-
-/* dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */
-CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
-
-/* dst(x,y,c) = abs(src(x,y,c) - value(c)) */
-CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );
-#define cvAbs( src, dst ) cvAbsDiffS( (src), (dst), cvScalarAll(0))
-
-/****************************************************************************************\
-*                                Math operations                                         *
-\****************************************************************************************/
-
-/* Does cartesian->polar coordinates conversion.
-   Either of output components (magnitude or angle) is optional */
-CVAPI(void)  cvCartToPolar( const CvArr* x, const CvArr* y,
-                            CvArr* magnitude, CvArr* angle CV_DEFAULT(NULL),
-                            int angle_in_degrees CV_DEFAULT(0));
-
-/* Does polar->cartesian coordinates conversion.
-   Either of output components (magnitude or angle) is optional.
-   If magnitude is missing it is assumed to be all 1's */
-CVAPI(void)  cvPolarToCart( const CvArr* magnitude, const CvArr* angle,
-                            CvArr* x, CvArr* y,
-                            int angle_in_degrees CV_DEFAULT(0));
-
-/* Does powering: dst(idx) = src(idx)^power */
-CVAPI(void)  cvPow( const CvArr* src, CvArr* dst, double power );
-
-/* Does exponention: dst(idx) = exp(src(idx)).
-   Overflow is not handled yet. Underflow is handled.
-   Maximal relative error is ~7e-6 for single-precision input */
-CVAPI(void)  cvExp( const CvArr* src, CvArr* dst );
-
-/* Calculates natural logarithms: dst(idx) = log(abs(src(idx))).
-   Logarithm of 0 gives large negative number(~-700)
-   Maximal relative error is ~3e-7 for single-precision output
-*/
-CVAPI(void)  cvLog( const CvArr* src, CvArr* dst );
-
-/* Fast arctangent calculation */
-CVAPI(float) cvFastArctan( float y, float x );
-
-/* Fast cubic root calculation */
-CVAPI(float)  cvCbrt( float value );
-
-/* Checks array values for NaNs, Infs or simply for too large numbers
-   (if CV_CHECK_RANGE is set). If CV_CHECK_QUIET is set,
-   no runtime errors is raised (function returns zero value in case of "bad" values).
-   Otherwise cvError is called */
-#define  CV_CHECK_RANGE    1
-#define  CV_CHECK_QUIET    2
-CVAPI(int)  cvCheckArr( const CvArr* arr, int flags CV_DEFAULT(0),
-                        double min_val CV_DEFAULT(0), double max_val CV_DEFAULT(0));
-#define cvCheckArray cvCheckArr
-
-#define CV_RAND_UNI      0
-#define CV_RAND_NORMAL   1
-CVAPI(void) cvRandArr( CvRNG* rng, CvArr* arr, int dist_type,
-                      CvScalar param1, CvScalar param2 );
-
-CVAPI(void) cvRandShuffle( CvArr* mat, CvRNG* rng,
-                           double iter_factor CV_DEFAULT(1.));
-
-#define CV_SORT_EVERY_ROW 0
-#define CV_SORT_EVERY_COLUMN 1
-#define CV_SORT_ASCENDING 0
-#define CV_SORT_DESCENDING 16
-
-CVAPI(void) cvSort( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
-                    CvArr* idxmat CV_DEFAULT(NULL),
-                    int flags CV_DEFAULT(0));
-
-/* Finds real roots of a cubic equation */
-CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots );
-
-/* Finds all real and complex roots of a polynomial equation */
-CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2,
-                       int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100));
-
-/****************************************************************************************\
-*                                Matrix operations                                       *
-\****************************************************************************************/
-
-/* Calculates cross product of two 3d vectors */
-CVAPI(void)  cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );
-
-/* Matrix transform: dst = A*B + C, C is optional */
-#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( (src1), (src2), 1., (src3), 1., (dst), 0 )
-#define cvMatMul( src1, src2, dst )  cvMatMulAdd( (src1), (src2), NULL, (dst))
-
-#define CV_GEMM_A_T 1
-#define CV_GEMM_B_T 2
-#define CV_GEMM_C_T 4
-/* Extended matrix transform:
-   dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T */
-CVAPI(void)  cvGEMM( const CvArr* src1, const CvArr* src2, double alpha,
-                     const CvArr* src3, double beta, CvArr* dst,
-                     int tABC CV_DEFAULT(0));
-#define cvMatMulAddEx cvGEMM
-
-/* Transforms each element of source array and stores
-   resultant vectors in destination array */
-CVAPI(void)  cvTransform( const CvArr* src, CvArr* dst,
-                          const CvMat* transmat,
-                          const CvMat* shiftvec CV_DEFAULT(NULL));
-#define cvMatMulAddS cvTransform
-
-/* Does perspective transform on every element of input array */
-CVAPI(void)  cvPerspectiveTransform( const CvArr* src, CvArr* dst,
-                                     const CvMat* mat );
-
-/* Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */
-CVAPI(void) cvMulTransposed( const CvArr* src, CvArr* dst, int order,
-                             const CvArr* delta CV_DEFAULT(NULL),
-                             double scale CV_DEFAULT(1.) );
-
-/* Tranposes matrix. Square matrices can be transposed in-place */
-CVAPI(void)  cvTranspose( const CvArr* src, CvArr* dst );
-#define cvT cvTranspose
-
-/* Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */
-CVAPI(void)  cvCompleteSymm( CvMat* matrix, int LtoR CV_DEFAULT(0) );
-
-/* Mirror array data around horizontal (flip=0),
-   vertical (flip=1) or both(flip=-1) axises:
-   cvFlip(src) flips images vertically and sequences horizontally (inplace) */
-CVAPI(void)  cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL),
-                     int flip_mode CV_DEFAULT(0));
-#define cvMirror cvFlip
-
-
-#define CV_SVD_MODIFY_A   1
-#define CV_SVD_U_T        2
-#define CV_SVD_V_T        4
-
-/* Performs Singular Value Decomposition of a matrix */
-CVAPI(void)   cvSVD( CvArr* A, CvArr* W, CvArr* U CV_DEFAULT(NULL),
-                     CvArr* V CV_DEFAULT(NULL), int flags CV_DEFAULT(0));
-
-/* Performs Singular Value Back Substitution (solves A*X = B):
-   flags must be the same as in cvSVD */
-CVAPI(void)   cvSVBkSb( const CvArr* W, const CvArr* U,
-                        const CvArr* V, const CvArr* B,
-                        CvArr* X, int flags );
-
-#define CV_LU  0
-#define CV_SVD 1
-#define CV_SVD_SYM 2
-#define CV_CHOLESKY 3
-#define CV_QR  4
-#define CV_NORMAL 16
-
-/* Inverts matrix */
-CVAPI(double)  cvInvert( const CvArr* src, CvArr* dst,
-                         int method CV_DEFAULT(CV_LU));
-#define cvInv cvInvert
-
-/* Solves linear system (src1)*(dst) = (src2)
-   (returns 0 if src1 is a singular and CV_LU method is used) */
-CVAPI(int)  cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst,
-                     int method CV_DEFAULT(CV_LU));
-
-/* Calculates determinant of input matrix */
-CVAPI(double) cvDet( const CvArr* mat );
-
-/* Calculates trace of the matrix (sum of elements on the main diagonal) */
-CVAPI(CvScalar) cvTrace( const CvArr* mat );
-
-/* Finds eigen values and vectors of a symmetric matrix */
-CVAPI(void)  cvEigenVV( CvArr* mat, CvArr* evects,
-                        CvArr* evals, double eps CV_DEFAULT(0));
-
-/* Makes an identity matrix (mat_ij = i == j) */
-CVAPI(void)  cvSetIdentity( CvArr* mat, CvScalar value CV_DEFAULT(cvRealScalar(1)) );
-
-/* Fills matrix with given range of numbers */
-CVAPI(CvArr*)  cvRange( CvArr* mat, double start, double end );
-
-/* Calculates covariation matrix for a set of vectors */
-/* transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */
-#define CV_COVAR_SCRAMBLED 0
-
-/* [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */
-#define CV_COVAR_NORMAL    1
-
-/* do not calc average (i.e. mean vector) - use the input vector instead
-   (useful for calculating covariance matrix by parts) */
-#define CV_COVAR_USE_AVG   2
-
-/* scale the covariance matrix coefficients by number of the vectors */
-#define CV_COVAR_SCALE     4
-
-/* all the input vectors are stored in a single matrix, as its rows */
-#define CV_COVAR_ROWS      8
-
-/* all the input vectors are stored in a single matrix, as its columns */
-#define CV_COVAR_COLS     16
-
-CVAPI(void)  cvCalcCovarMatrix( const CvArr** vects, int count,
-                                CvArr* cov_mat, CvArr* avg, int flags );
-
-#define CV_PCA_DATA_AS_ROW 0
-#define CV_PCA_DATA_AS_COL 1
-#define CV_PCA_USE_AVG 2
-CVAPI(void)  cvCalcPCA( const CvArr* data, CvArr* mean,
-                        CvArr* eigenvals, CvArr* eigenvects, int flags );
-
-CVAPI(void)  cvProjectPCA( const CvArr* data, const CvArr* mean,
-                           const CvArr* eigenvects, CvArr* result );
-
-CVAPI(void)  cvBackProjectPCA( const CvArr* proj, const CvArr* mean,
-                               const CvArr* eigenvects, CvArr* result );
-
-/* Calculates Mahalanobis(weighted) distance */
-CVAPI(double)  cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );
-#define cvMahalonobis  cvMahalanobis
-
-/****************************************************************************************\
-*                                    Array Statistics                                    *
-\****************************************************************************************/
-
-/* Finds sum of array elements */
-CVAPI(CvScalar)  cvSum( const CvArr* arr );
-
-/* Calculates number of non-zero pixels */
-CVAPI(int)  cvCountNonZero( const CvArr* arr );
-
-/* Calculates mean value of array elements */
-CVAPI(CvScalar)  cvAvg( const CvArr* arr, const CvArr* mask CV_DEFAULT(NULL) );
-
-/* Calculates mean and standard deviation of pixel values */
-CVAPI(void)  cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev,
-                       const CvArr* mask CV_DEFAULT(NULL) );
-
-/* Finds global minimum, maximum and their positions */
-CVAPI(void)  cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
-                          CvPoint* min_loc CV_DEFAULT(NULL),
-                          CvPoint* max_loc CV_DEFAULT(NULL),
-                          const CvArr* mask CV_DEFAULT(NULL) );
-
-/* types of array norm */
-#define CV_C            1
-#define CV_L1           2
-#define CV_L2           4
-#define CV_NORM_MASK    7
-#define CV_RELATIVE     8
-#define CV_DIFF         16
-#define CV_MINMAX       32
-
-#define CV_DIFF_C       (CV_DIFF | CV_C)
-#define CV_DIFF_L1      (CV_DIFF | CV_L1)
-#define CV_DIFF_L2      (CV_DIFF | CV_L2)
-#define CV_RELATIVE_C   (CV_RELATIVE | CV_C)
-#define CV_RELATIVE_L1  (CV_RELATIVE | CV_L1)
-#define CV_RELATIVE_L2  (CV_RELATIVE | CV_L2)
-
-/* Finds norm, difference norm or relative difference norm for an array (or two arrays) */
-CVAPI(double)  cvNorm( const CvArr* arr1, const CvArr* arr2 CV_DEFAULT(NULL),
-                       int norm_type CV_DEFAULT(CV_L2),
-                       const CvArr* mask CV_DEFAULT(NULL) );
-
-CVAPI(void)  cvNormalize( const CvArr* src, CvArr* dst,
-                          double a CV_DEFAULT(1.), double b CV_DEFAULT(0.),
-                          int norm_type CV_DEFAULT(CV_L2),
-                          const CvArr* mask CV_DEFAULT(NULL) );
-
-
-#define CV_REDUCE_SUM 0
-#define CV_REDUCE_AVG 1
-#define CV_REDUCE_MAX 2
-#define CV_REDUCE_MIN 3
-
-CVAPI(void)  cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1),
-                       int op CV_DEFAULT(CV_REDUCE_SUM) );
-
-/****************************************************************************************\
-*                      Discrete Linear Transforms and Related Functions                  *
-\****************************************************************************************/
-
-#define CV_DXT_FORWARD  0
-#define CV_DXT_INVERSE  1
-#define CV_DXT_SCALE    2 /* divide result by size of array */
-#define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE)
-#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE
-#define CV_DXT_ROWS     4 /* transform each row individually */
-#define CV_DXT_MUL_CONJ 8 /* conjugate the second argument of cvMulSpectrums */
-
-/* Discrete Fourier Transform:
-    complex->complex,
-    real->ccs (forward),
-    ccs->real (inverse) */
-CVAPI(void)  cvDFT( const CvArr* src, CvArr* dst, int flags,
-                    int nonzero_rows CV_DEFAULT(0) );
-#define cvFFT cvDFT
-
-/* Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y)) */
-CVAPI(void)  cvMulSpectrums( const CvArr* src1, const CvArr* src2,
-                             CvArr* dst, int flags );
-
-/* Finds optimal DFT vector size >= size0 */
-CVAPI(int)  cvGetOptimalDFTSize( int size0 );
-
-/* Discrete Cosine Transform */
-CVAPI(void)  cvDCT( const CvArr* src, CvArr* dst, int flags );
-
-/****************************************************************************************\
-*                              Dynamic data structures                                   *
-\****************************************************************************************/
-
-/* Calculates length of sequence slice (with support of negative indices). */
-CVAPI(int) cvSliceLength( CvSlice slice, const CvSeq* seq );
-
-
-/* Creates new memory storage.
-   block_size == 0 means that default,
-   somewhat optimal size, is used (currently, it is 64K) */
-CVAPI(CvMemStorage*)  cvCreateMemStorage( int block_size CV_DEFAULT(0));
-
-
-/* Creates a memory storage that will borrow memory blocks from parent storage */
-CVAPI(CvMemStorage*)  cvCreateChildMemStorage( CvMemStorage* parent );
-
-
-/* Releases memory storage. All the children of a parent must be released before
-   the parent. A child storage returns all the blocks to parent when it is released */
-CVAPI(void)  cvReleaseMemStorage( CvMemStorage** storage );
-
-
-/* Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos)
-   to reuse memory allocated for the storage - cvClearSeq,cvClearSet ...
-   do not free any memory.
-   A child storage returns all the blocks to the parent when it is cleared */
-CVAPI(void)  cvClearMemStorage( CvMemStorage* storage );
-
-/* Remember a storage "free memory" position */
-CVAPI(void)  cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );
-
-/* Restore a storage "free memory" position */
-CVAPI(void)  cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos );
-
-/* Allocates continuous buffer of the specified size in the storage */
-CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size );
-
-/* Allocates string in memory storage */
-CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr,
-                                        int len CV_DEFAULT(-1) );
-
-/* Creates new empty sequence that will reside in the specified storage */
-CVAPI(CvSeq*)  cvCreateSeq( int seq_flags, int header_size,
-                            int elem_size, CvMemStorage* storage );
-
-/* Changes default size (granularity) of sequence blocks.
-   The default size is ~1Kbyte */
-CVAPI(void)  cvSetSeqBlockSize( CvSeq* seq, int delta_elems );
-
-
-/* Adds new element to the end of sequence. Returns pointer to the element */
-CVAPI(schar*)  cvSeqPush( CvSeq* seq, void* element CV_DEFAULT(NULL));
-
-
-/* Adds new element to the beginning of sequence. Returns pointer to it */
-CVAPI(schar*)  cvSeqPushFront( CvSeq* seq, void* element CV_DEFAULT(NULL));
-
-
-/* Removes the last element from sequence and optionally saves it */
-CVAPI(void)  cvSeqPop( CvSeq* seq, void* element CV_DEFAULT(NULL));
-
-
-/* Removes the first element from sequence and optioanally saves it */
-CVAPI(void)  cvSeqPopFront( CvSeq* seq, void* element CV_DEFAULT(NULL));
-
-
-#define CV_FRONT 1
-#define CV_BACK 0
-/* Adds several new elements to the end of sequence */
-CVAPI(void)  cvSeqPushMulti( CvSeq* seq, void* elements,
-                             int count, int in_front CV_DEFAULT(0) );
-
-/* Removes several elements from the end of sequence and optionally saves them */
-CVAPI(void)  cvSeqPopMulti( CvSeq* seq, void* elements,
-                            int count, int in_front CV_DEFAULT(0) );
-
-/* Inserts a new element in the middle of sequence.
-   cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem) */
-CVAPI(schar*)  cvSeqInsert( CvSeq* seq, int before_index,
-                            void* element CV_DEFAULT(NULL));
-
-/* Removes specified sequence element */
-CVAPI(void)  cvSeqRemove( CvSeq* seq, int index );
-
-
-/* Removes all the elements from the sequence. The freed memory
-   can be reused later only by the same sequence unless cvClearMemStorage
-   or cvRestoreMemStoragePos is called */
-CVAPI(void)  cvClearSeq( CvSeq* seq );
-
-
-/* Retrieves pointer to specified sequence element.
-   Negative indices are supported and mean counting from the end
-   (e.g -1 means the last sequence element) */
-CVAPI(schar*)  cvGetSeqElem( const CvSeq* seq, int index );
-
-/* Calculates index of the specified sequence element.
-   Returns -1 if element does not belong to the sequence */
-CVAPI(int)  cvSeqElemIdx( const CvSeq* seq, const void* element,
-                         CvSeqBlock** block CV_DEFAULT(NULL) );
-
-/* Initializes sequence writer. The new elements will be added to the end of sequence */
-CVAPI(void)  cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer );
-
-
-/* Combination of cvCreateSeq and cvStartAppendToSeq */
-CVAPI(void)  cvStartWriteSeq( int seq_flags, int header_size,
-                              int elem_size, CvMemStorage* storage,
-                              CvSeqWriter* writer );
-
-/* Closes sequence writer, updates sequence header and returns pointer
-   to the resultant sequence
-   (which may be useful if the sequence was created using cvStartWriteSeq))
-*/
-CVAPI(CvSeq*)  cvEndWriteSeq( CvSeqWriter* writer );
-
-
-/* Updates sequence header. May be useful to get access to some of previously
-   written elements via cvGetSeqElem or sequence reader */
-CVAPI(void)   cvFlushSeqWriter( CvSeqWriter* writer );
-
-
-/* Initializes sequence reader.
-   The sequence can be read in forward or backward direction */
-CVAPI(void) cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader,
-                           int reverse CV_DEFAULT(0) );
-
-
-/* Returns current sequence reader position (currently observed sequence element) */
-CVAPI(int)  cvGetSeqReaderPos( CvSeqReader* reader );
-
-
-/* Changes sequence reader position. It may seek to an absolute or
-   to relative to the current position */
-CVAPI(void)   cvSetSeqReaderPos( CvSeqReader* reader, int index,
-                                 int is_relative CV_DEFAULT(0));
-
-/* Copies sequence content to a continuous piece of memory */
-CVAPI(void*)  cvCvtSeqToArray( const CvSeq* seq, void* elements,
-                               CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ) );
-
-/* Creates sequence header for array.
-   After that all the operations on sequences that do not alter the content
-   can be applied to the resultant sequence */
-CVAPI(CvSeq*) cvMakeSeqHeaderForArray( int seq_type, int header_size,
-                                       int elem_size, void* elements, int total,
-                                       CvSeq* seq, CvSeqBlock* block );
-
-/* Extracts sequence slice (with or without copying sequence elements) */
-CVAPI(CvSeq*) cvSeqSlice( const CvSeq* seq, CvSlice slice,
-                         CvMemStorage* storage CV_DEFAULT(NULL),
-                         int copy_data CV_DEFAULT(0));
-
-CV_INLINE CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage CV_DEFAULT(NULL))
-{
-    return cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 );
-}
-
-/* Removes sequence slice */
-CVAPI(void)  cvSeqRemoveSlice( CvSeq* seq, CvSlice slice );
-
-/* Inserts a sequence or array into another sequence */
-CVAPI(void)  cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
-
-/* a < b ? -1 : a > b ? 1 : 0 */
-typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata );
-
-/* Sorts sequence in-place given element comparison function */
-CVAPI(void) cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata CV_DEFAULT(NULL) );
-
-/* Finds element in a [sorted] sequence */
-CVAPI(schar*) cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func,
-                           int is_sorted, int* elem_idx,
-                           void* userdata CV_DEFAULT(NULL) );
-
-/* Reverses order of sequence elements in-place */
-CVAPI(void) cvSeqInvert( CvSeq* seq );
-
-/* Splits sequence into one or more equivalence classes using the specified criteria */
-CVAPI(int)  cvSeqPartition( const CvSeq* seq, CvMemStorage* storage,
-                            CvSeq** labels, CvCmpFunc is_equal, void* userdata );
-
-/************ Internal sequence functions ************/
-CVAPI(void)  cvChangeSeqBlock( void* reader, int direction );
-CVAPI(void)  cvCreateSeqBlock( CvSeqWriter* writer );
-
-
-/* Creates a new set */
-CVAPI(CvSet*)  cvCreateSet( int set_flags, int header_size,
-                            int elem_size, CvMemStorage* storage );
-
-/* Adds new element to the set and returns pointer to it */
-CVAPI(int)  cvSetAdd( CvSet* set_header, CvSetElem* elem CV_DEFAULT(NULL),
-                      CvSetElem** inserted_elem CV_DEFAULT(NULL) );
-
-/* Fast variant of cvSetAdd */
-CV_INLINE  CvSetElem* cvSetNew( CvSet* set_header )
-{
-    CvSetElem* elem = set_header->free_elems;
-    if( elem )
-    {
-        set_header->free_elems = elem->next_free;
-        elem->flags = elem->flags & CV_SET_ELEM_IDX_MASK;
-        set_header->active_count++;
-    }
-    else
-        cvSetAdd( set_header, NULL, (CvSetElem**)&elem );
-    return elem;
-}
-
-/* Removes set element given its pointer */
-CV_INLINE  void cvSetRemoveByPtr( CvSet* set_header, void* elem )
-{
-    CvSetElem* _elem = (CvSetElem*)elem;
-    assert( _elem->flags >= 0 /*&& (elem->flags & CV_SET_ELEM_IDX_MASK) < set_header->total*/ );
-    _elem->next_free = set_header->free_elems;
-    _elem->flags = (_elem->flags & CV_SET_ELEM_IDX_MASK) | CV_SET_ELEM_FREE_FLAG;
-    set_header->free_elems = _elem;
-    set_header->active_count--;
-}
-
-/* Removes element from the set by its index  */
-CVAPI(void)   cvSetRemove( CvSet* set_header, int index );
-
-/* Returns a set element by index. If the element doesn't belong to the set,
-   NULL is returned */
-CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int index )
-{
-    CvSetElem* elem = (CvSetElem*)cvGetSeqElem( (CvSeq*)set_header, index );
-    return elem && CV_IS_SET_ELEM( elem ) ? elem : 0;
-}
-
-/* Removes all the elements from the set */
-CVAPI(void)  cvClearSet( CvSet* set_header );
-
-/* Creates new graph */
-CVAPI(CvGraph*)  cvCreateGraph( int graph_flags, int header_size,
-                                int vtx_size, int edge_size,
-                                CvMemStorage* storage );
-
-/* Adds new vertex to the graph */
-CVAPI(int)  cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx CV_DEFAULT(NULL),
-                           CvGraphVtx** inserted_vtx CV_DEFAULT(NULL) );
-
-
-/* Removes vertex from the graph together with all incident edges */
-CVAPI(int)  cvGraphRemoveVtx( CvGraph* graph, int index );
-CVAPI(int)  cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx );
-
-
-/* Link two vertices specifed by indices or pointers if they
-   are not connected or return pointer to already existing edge
-   connecting the vertices.
-   Functions return 1 if a new edge was created, 0 otherwise */
-CVAPI(int)  cvGraphAddEdge( CvGraph* graph,
-                            int start_idx, int end_idx,
-                            const CvGraphEdge* edge CV_DEFAULT(NULL),
-                            CvGraphEdge** inserted_edge CV_DEFAULT(NULL) );
-
-CVAPI(int)  cvGraphAddEdgeByPtr( CvGraph* graph,
-                               CvGraphVtx* start_vtx, CvGraphVtx* end_vtx,
-                               const CvGraphEdge* edge CV_DEFAULT(NULL),
-                               CvGraphEdge** inserted_edge CV_DEFAULT(NULL) );
-
-/* Remove edge connecting two vertices */
-CVAPI(void)  cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx );
-CVAPI(void)  cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx,
-                                     CvGraphVtx* end_vtx );
-
-/* Find edge connecting two vertices */
-CVAPI(CvGraphEdge*)  cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx );
-CVAPI(CvGraphEdge*)  cvFindGraphEdgeByPtr( const CvGraph* graph,
-                                           const CvGraphVtx* start_vtx,
-                                           const CvGraphVtx* end_vtx );
-#define cvGraphFindEdge cvFindGraphEdge
-#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr
-
-/* Remove all vertices and edges from the graph */
-CVAPI(void)  cvClearGraph( CvGraph* graph );
-
-
-/* Count number of edges incident to the vertex */
-CVAPI(int)  cvGraphVtxDegree( const CvGraph* graph, int vtx_idx );
-CVAPI(int)  cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx );
-
-
-/* Retrieves graph vertex by given index */
-#define cvGetGraphVtx( graph, idx ) (CvGraphVtx*)cvGetSetElem((CvSet*)(graph), (idx))
-
-/* Retrieves index of a graph vertex given its pointer */
-#define cvGraphVtxIdx( graph, vtx ) ((vtx)->flags & CV_SET_ELEM_IDX_MASK)
-
-/* Retrieves index of a graph edge given its pointer */
-#define cvGraphEdgeIdx( graph, edge ) ((edge)->flags & CV_SET_ELEM_IDX_MASK)
-
-#define cvGraphGetVtxCount( graph ) ((graph)->active_count)
-#define cvGraphGetEdgeCount( graph ) ((graph)->edges->active_count)
-
-#define  CV_GRAPH_VERTEX        1
-#define  CV_GRAPH_TREE_EDGE     2
-#define  CV_GRAPH_BACK_EDGE     4
-#define  CV_GRAPH_FORWARD_EDGE  8
-#define  CV_GRAPH_CROSS_EDGE    16
-#define  CV_GRAPH_ANY_EDGE      30
-#define  CV_GRAPH_NEW_TREE      32
-#define  CV_GRAPH_BACKTRACKING  64
-#define  CV_GRAPH_OVER          -1
-
-#define  CV_GRAPH_ALL_ITEMS    -1
-
-/* flags for graph vertices and edges */
-#define  CV_GRAPH_ITEM_VISITED_FLAG  (1 << 30)
-#define  CV_IS_GRAPH_VERTEX_VISITED(vtx) \
-    (((CvGraphVtx*)(vtx))->flags & CV_GRAPH_ITEM_VISITED_FLAG)
-#define  CV_IS_GRAPH_EDGE_VISITED(edge) \
-    (((CvGraphEdge*)(edge))->flags & CV_GRAPH_ITEM_VISITED_FLAG)
-#define  CV_GRAPH_SEARCH_TREE_NODE_FLAG   (1 << 29)
-#define  CV_GRAPH_FORWARD_EDGE_FLAG       (1 << 28)
-
-typedef struct CvGraphScanner
-{
-    CvGraphVtx* vtx;       /* current graph vertex (or current edge origin) */
-    CvGraphVtx* dst;       /* current graph edge destination vertex */
-    CvGraphEdge* edge;     /* current edge */
-
-    CvGraph* graph;        /* the graph */
-    CvSeq*   stack;        /* the graph vertex stack */
-    int      index;        /* the lower bound of certainly visited vertices */
-    int      mask;         /* event mask */
-}
-CvGraphScanner;
-
-/* Creates new graph scanner. */
-CVAPI(CvGraphScanner*)  cvCreateGraphScanner( CvGraph* graph,
-                                             CvGraphVtx* vtx CV_DEFAULT(NULL),
-                                             int mask CV_DEFAULT(CV_GRAPH_ALL_ITEMS));
-
-/* Releases graph scanner. */
-CVAPI(void) cvReleaseGraphScanner( CvGraphScanner** scanner );
-
-/* Get next graph element */
-CVAPI(int)  cvNextGraphItem( CvGraphScanner* scanner );
-
-/* Creates a copy of graph */
-CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );
-
-/****************************************************************************************\
-*                                     Drawing                                            *
-\****************************************************************************************/
-
-/****************************************************************************************\
-*       Drawing functions work with images/matrices of arbitrary type.                   *
-*       For color images the channel order is BGR[A]                                     *
-*       Antialiasing is supported only for 8-bit image now.                              *
-*       All the functions include parameter color that means rgb value (that may be      *
-*       constructed with CV_RGB macro) for color images and brightness                   *
-*       for grayscale images.                                                            *
-*       If a drawn figure is partially or completely outside of the image, it is clipped.*
-\****************************************************************************************/
-
-#define CV_RGB( r, g, b )  cvScalar( (b), (g), (r), 0 )
-#define CV_FILLED -1
-
-#define CV_AA 16
-
-/* Draws 4-connected, 8-connected or antialiased line segment connecting two points */
-CVAPI(void)  cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,
-                     CvScalar color, int thickness CV_DEFAULT(1),
-                     int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
-
-/* Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
-   if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn */
-CVAPI(void)  cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2,
-                          CvScalar color, int thickness CV_DEFAULT(1),
-                          int line_type CV_DEFAULT(8),
-                          int shift CV_DEFAULT(0));
-
-/* Draws a circle with specified center and radius.
-   Thickness works in the same way as with cvRectangle */
-CVAPI(void)  cvCircle( CvArr* img, CvPoint center, int radius,
-                       CvScalar color, int thickness CV_DEFAULT(1),
-                       int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
-
-/* Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
-   depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
-   is rotated by <angle>. All the angles are in degrees */
-CVAPI(void)  cvEllipse( CvArr* img, CvPoint center, CvSize axes,
-                        double angle, double start_angle, double end_angle,
-                        CvScalar color, int thickness CV_DEFAULT(1),
-                        int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
-
-CV_INLINE  void  cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color,
-                               int thickness CV_DEFAULT(1),
-                               int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) )
-{
-    CvSize axes;
-    axes.width = cvRound(box.size.height*0.5);
-    axes.height = cvRound(box.size.width*0.5);
-
-    cvEllipse( img, cvPointFrom32f( box.center ), axes, box.angle,
-               0, 360, color, thickness, line_type, shift );
-}
-
-/* Fills convex or monotonous polygon. */
-CVAPI(void)  cvFillConvexPoly( CvArr* img, CvPoint* pts, int npts, CvScalar color,
-                               int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
-
-/* Fills an area bounded by one or more arbitrary polygons */
-CVAPI(void)  cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours, CvScalar color,
-                         int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
-
-/* Draws one or more polygonal curves */
-CVAPI(void)  cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours,
-                         int is_closed, CvScalar color, int thickness CV_DEFAULT(1),
-                         int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
-
-#define cvDrawRect cvRectangle
-#define cvDrawLine cvLine
-#define cvDrawCircle cvCircle
-#define cvDrawEllipse cvEllipse
-#define cvDrawPolyLine cvPolyLine
-
-/* Clips the line segment connecting *pt1 and *pt2
-   by the rectangular window
-   (0<=x<img_size.width, 0<=y<img_size.height). */
-CVAPI(int) cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );
-
-/* Initializes line iterator. Initially, line_iterator->ptr will point
-   to pt1 (or pt2, see left_to_right description) location in the image.
-   Returns the number of pixels on the line between the ending points. */
-CVAPI(int)  cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
-                                CvLineIterator* line_iterator,
-                                int connectivity CV_DEFAULT(8),
-                                int left_to_right CV_DEFAULT(0));
-
-/* Moves iterator to the next line point */
-#define CV_NEXT_LINE_POINT( line_iterator )                     \
-{                                                               \
-    int _line_iterator_mask = (line_iterator).err < 0 ? -1 : 0; \
-    (line_iterator).err += (line_iterator).minus_delta +        \
-        ((line_iterator).plus_delta & _line_iterator_mask);     \
-    (line_iterator).ptr += (line_iterator).minus_step +         \
-        ((line_iterator).plus_step & _line_iterator_mask);      \
-}
-
-
-/* basic font types */
-#define CV_FONT_HERSHEY_SIMPLEX         0
-#define CV_FONT_HERSHEY_PLAIN           1
-#define CV_FONT_HERSHEY_DUPLEX          2
-#define CV_FONT_HERSHEY_COMPLEX         3
-#define CV_FONT_HERSHEY_TRIPLEX         4
-#define CV_FONT_HERSHEY_COMPLEX_SMALL   5
-#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX  6
-#define CV_FONT_HERSHEY_SCRIPT_COMPLEX  7
-
-/* font flags */
-#define CV_FONT_ITALIC                 16
-
-#define CV_FONT_VECTOR0    CV_FONT_HERSHEY_SIMPLEX
-
-/* Font structure */
-typedef struct CvFont
-{
-    int         font_face; /* =CV_FONT_* */
-    const int*  ascii; /* font data and metrics */
-    const int*  greek;
-    const int*  cyrillic;
-    float       hscale, vscale;
-    float       shear; /* slope coefficient: 0 - normal, >0 - italic */
-    int         thickness; /* letters thickness */
-    float       dx; /* horizontal interval between letters */
-    int         line_type;
-}
-CvFont;
-
-/* Initializes font structure used further in cvPutText */
-CVAPI(void)  cvInitFont( CvFont* font, int font_face,
-                         double hscale, double vscale,
-                         double shear CV_DEFAULT(0),
-                         int thickness CV_DEFAULT(1),
-                         int line_type CV_DEFAULT(8));
-
-CV_INLINE CvFont cvFont( double scale, int thickness CV_DEFAULT(1) )
-{
-    CvFont font;
-    cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, scale, scale, 0, thickness, CV_AA );
-    return font;
-}
-
-/* Renders text stroke with specified font and color at specified location.
-   CvFont should be initialized with cvInitFont */
-CVAPI(void)  cvPutText( CvArr* img, const char* text, CvPoint org,
-                        const CvFont* font, CvScalar color );
-
-/* Calculates bounding box of text stroke (useful for alignment) */
-CVAPI(void)  cvGetTextSize( const char* text_string, const CvFont* font,
-                            CvSize* text_size, int* baseline );
-
-/* Unpacks color value, if arrtype is CV_8UC?, <color> is treated as
-   packed color value, otherwise the first channels (depending on arrtype)
-   of destination scalar are set to the same value = <color> */
-CVAPI(CvScalar)  cvColorToScalar( double packed_color, int arrtype );
-
-/* Returns the polygon points which make up the given ellipse.  The ellipse is define by
-   the box of size 'axes' rotated 'angle' around the 'center'.  A partial sweep
-   of the ellipse arc can be done by spcifying arc_start and arc_end to be something
-   other than 0 and 360, respectively.  The input array 'pts' must be large enough to
-   hold the result.  The total number of points stored into 'pts' is returned by this
-   function. */
-CVAPI(int) cvEllipse2Poly( CvPoint center, CvSize axes,
-                 int angle, int arc_start, int arc_end, CvPoint * pts, int delta );
-
-/* Draws contour outlines or filled interiors on the image */
-CVAPI(void)  cvDrawContours( CvArr *img, CvSeq* contour,
-                            CvScalar external_color, CvScalar hole_color,
-                            int max_level, int thickness CV_DEFAULT(1),
-                            int line_type CV_DEFAULT(8),
-                            CvPoint offset CV_DEFAULT(cvPoint(0,0)));
-
-/* Does look-up transformation. Elements of the source array
-   (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */
-CVAPI(void) cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );
-
-
-/******************* Iteration through the sequence tree *****************/
-typedef struct CvTreeNodeIterator
-{
-    const void* node;
-    int level;
-    int max_level;
-}
-CvTreeNodeIterator;
-
-CVAPI(void) cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator,
-                                   const void* first, int max_level );
-CVAPI(void*) cvNextTreeNode( CvTreeNodeIterator* tree_iterator );
-CVAPI(void*) cvPrevTreeNode( CvTreeNodeIterator* tree_iterator );
-
-/* Inserts sequence into tree with specified "parent" sequence.
-   If parent is equal to frame (e.g. the most external contour),
-   then added contour will have null pointer to parent. */
-CVAPI(void) cvInsertNodeIntoTree( void* node, void* parent, void* frame );
-
-/* Removes contour from tree (together with the contour children). */
-CVAPI(void) cvRemoveNodeFromTree( void* node, void* frame );
-
-/* Gathers pointers to all the sequences,
-   accessible from the <first>, to the single sequence */
-CVAPI(CvSeq*) cvTreeToNodeSeq( const void* first, int header_size,
-                              CvMemStorage* storage );
-
-/* The function implements the K-means algorithm for clustering an array of sample
-   vectors in a specified number of classes */
-#define CV_KMEANS_USE_INITIAL_LABELS    1
-CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels,
-                      CvTermCriteria termcrit, int attempts CV_DEFAULT(1),
-                      CvRNG* rng CV_DEFAULT(0), int flags CV_DEFAULT(0),
-                      CvArr* _centers CV_DEFAULT(0), double* compactness CV_DEFAULT(0) );
-
-/****************************************************************************************\
-*                                    System functions                                    *
-\****************************************************************************************/
-
-/* Add the function pointers table with associated information to the IPP primitives list */
-CVAPI(int)  cvRegisterModule( const CvModuleInfo* module_info );
-
-/* Loads optimized functions from IPP, MKL etc. or switches back to pure C code */
-CVAPI(int)  cvUseOptimized( int on_off );
-
-/* Retrieves information about the registered modules and loaded optimized plugins */
-CVAPI(void)  cvGetModuleInfo( const char* module_name,
-                              const char** version,
-                              const char** loaded_addon_plugins );
-
-/* Get current OpenCV error status */
-CVAPI(int) cvGetErrStatus( void );
-
-/* Sets error status silently */
-CVAPI(void) cvSetErrStatus( int status );
-
-#define CV_ErrModeLeaf     0   /* Print error and exit program */
-#define CV_ErrModeParent   1   /* Print error and continue */
-#define CV_ErrModeSilent   2   /* Don't print and continue */
-
-/* Retrives current error processing mode */
-CVAPI(int)  cvGetErrMode( void );
-
-/* Sets error processing mode, returns previously used mode */
-CVAPI(int) cvSetErrMode( int mode );
-
-/* Sets error status and performs some additonal actions (displaying message box,
-   writing message to stderr, terminating application etc.)
-   depending on the current error mode */
-CVAPI(void) cvError( int status, const char* func_name,
-                    const char* err_msg, const char* file_name, int line );
-
-/* Retrieves textual description of the error given its code */
-CVAPI(const char*) cvErrorStr( int status );
-
-/* Retrieves detailed information about the last error occured */
-CVAPI(int) cvGetErrInfo( const char** errcode_desc, const char** description,
-                        const char** filename, int* line );
-
-/* Maps IPP error codes to the counterparts from OpenCV */
-CVAPI(int) cvErrorFromIppStatus( int ipp_status );
-
-typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name,
-                    const char* err_msg, const char* file_name, int line, void* userdata );
-
-/* Assigns a new error-handling function */
-CVAPI(CvErrorCallback) cvRedirectError( CvErrorCallback error_handler,
-                                       void* userdata CV_DEFAULT(NULL),
-                                       void** prev_userdata CV_DEFAULT(NULL) );
-
-/*
-    Output to:
-        cvNulDevReport - nothing
-        cvStdErrReport - console(fprintf(stderr,...))
-        cvGuiBoxReport - MessageBox(WIN32)
-*/
-CVAPI(int) cvNulDevReport( int status, const char* func_name, const char* err_msg,
-                          const char* file_name, int line, void* userdata );
-
-CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_msg,
-                          const char* file_name, int line, void* userdata );
-
-CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg,
-                          const char* file_name, int line, void* userdata );
-
-typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata);
-typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata);
-
-/* Set user-defined memory managment functions (substitutors for malloc and free) that
-   will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage) */
-CVAPI(void) cvSetMemoryManager( CvAllocFunc alloc_func CV_DEFAULT(NULL),
-                               CvFreeFunc free_func CV_DEFAULT(NULL),
-                               void* userdata CV_DEFAULT(NULL));
-
-
-typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader)
-                            (int,int,int,char*,char*,int,int,int,int,int,
-                            IplROI*,IplImage*,void*,IplTileInfo*);
-typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int);
-typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int);
-typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int);
-typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*);
-
-/* Makes OpenCV use IPL functions for IplImage allocation/deallocation */
-CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
-                               Cv_iplAllocateImageData allocate_data,
-                               Cv_iplDeallocate deallocate,
-                               Cv_iplCreateROI create_roi,
-                               Cv_iplCloneImage clone_image );
-
-#define CV_TURN_ON_IPL_COMPATIBILITY()                                  \
-    cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage,         \
-                        iplDeallocate, iplCreateROI, iplCloneImage )
-
-/****************************************************************************************\
-*                                    Data Persistence                                    *
-\****************************************************************************************/
-
-/********************************** High-level functions ********************************/
-
-/* opens existing or creates new file storage */
-CVAPI(CvFileStorage*)  cvOpenFileStorage( const char* filename,
-                                          CvMemStorage* memstorage,
-                                          int flags );
-
-/* closes file storage and deallocates buffers */
-CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs );
-
-/* returns attribute value or 0 (NULL) if there is no such attribute */
-CVAPI(const char*) cvAttrValue( const CvAttrList* attr, const char* attr_name );
-
-/* starts writing compound structure (map or sequence) */
-CVAPI(void) cvStartWriteStruct( CvFileStorage* fs, const char* name,
-                                int struct_flags, const char* type_name CV_DEFAULT(NULL),
-                                CvAttrList attributes CV_DEFAULT(cvAttrList()));
-
-/* finishes writing compound structure */
-CVAPI(void) cvEndWriteStruct( CvFileStorage* fs );
-
-/* writes an integer */
-CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value );
-
-/* writes a floating-point number */
-CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value );
-
-/* writes a string */
-CVAPI(void) cvWriteString( CvFileStorage* fs, const char* name,
-                           const char* str, int quote CV_DEFAULT(0) );
-
-/* writes a comment */
-CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment,
-                            int eol_comment );
-
-/* writes instance of a standard type (matrix, image, sequence, graph etc.)
-   or user-defined type */
-CVAPI(void) cvWrite( CvFileStorage* fs, const char* name, const void* ptr,
-                         CvAttrList attributes CV_DEFAULT(cvAttrList()));
-
-/* starts the next stream */
-CVAPI(void) cvStartNextStream( CvFileStorage* fs );
-
-/* helper function: writes multiple integer or floating-point numbers */
-CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src,
-                                int len, const char* dt );
-
-/* returns the hash entry corresponding to the specified literal key string or 0
-   if there is no such a key in the storage */
-CVAPI(CvStringHashNode*) cvGetHashedKey( CvFileStorage* fs, const char* name,
-                                        int len CV_DEFAULT(-1),
-                                        int create_missing CV_DEFAULT(0));
-
-/* returns file node with the specified key within the specified map
-   (collection of named nodes) */
-CVAPI(CvFileNode*) cvGetRootFileNode( const CvFileStorage* fs,
-                                     int stream_index CV_DEFAULT(0) );
-
-/* returns file node with the specified key within the specified map
-   (collection of named nodes) */
-CVAPI(CvFileNode*) cvGetFileNode( CvFileStorage* fs, CvFileNode* map,
-                                 const CvStringHashNode* key,
-                                 int create_missing CV_DEFAULT(0) );
-
-/* this is a slower version of cvGetFileNode that takes the key as a literal string */
-CVAPI(CvFileNode*) cvGetFileNodeByName( const CvFileStorage* fs,
-                                       const CvFileNode* map,
-                                       const char* name );
-
-CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) )
-{
-    return !node ? default_value :
-        CV_NODE_IS_INT(node->tag) ? node->data.i :
-        CV_NODE_IS_REAL(node->tag) ? cvRound(node->data.f) : 0x7fffffff;
-}
-
-
-CV_INLINE int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map,
-                         const char* name, int default_value CV_DEFAULT(0) )
-{
-    return cvReadInt( cvGetFileNodeByName( fs, map, name ), default_value );
-}
-
-
-CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEFAULT(0.) )
-{
-    return !node ? default_value :
-        CV_NODE_IS_INT(node->tag) ? (double)node->data.i :
-        CV_NODE_IS_REAL(node->tag) ? node->data.f : 1e300;
-}
-
-
-CV_INLINE double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map,
-                        const char* name, double default_value CV_DEFAULT(0.) )
-{
-    return cvReadReal( cvGetFileNodeByName( fs, map, name ), default_value );
-}
-
-
-CV_INLINE const char* cvReadString( const CvFileNode* node,
-                        const char* default_value CV_DEFAULT(NULL) )
-{
-    return !node ? default_value : CV_NODE_IS_STRING(node->tag) ? node->data.str.ptr : 0;
-}
-
-
-CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map,
-                        const char* name, const char* default_value CV_DEFAULT(NULL) )
-{
-    return cvReadString( cvGetFileNodeByName( fs, map, name ), default_value );
-}
-
-
-/* decodes standard or user-defined object and returns it */
-CVAPI(void*) cvRead( CvFileStorage* fs, CvFileNode* node,
-                        CvAttrList* attributes CV_DEFAULT(NULL));
-
-/* decodes standard or user-defined object and returns it */
-CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map,
-                              const char* name, CvAttrList* attributes CV_DEFAULT(NULL) )
-{
-    return cvRead( fs, cvGetFileNodeByName( fs, map, name ), attributes );
-}
-
-
-/* starts reading data from sequence or scalar numeric node */
-CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src,
-                               CvSeqReader* reader );
-
-/* reads multiple numbers and stores them to array */
-CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
-                               int count, void* dst, const char* dt );
-
-/* combination of two previous functions for easier reading of whole sequences */
-CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src,
-                          void* dst, const char* dt );
-
-/* writes a copy of file node to file storage */
-CVAPI(void) cvWriteFileNode( CvFileStorage* fs, const char* new_node_name,
-                            const CvFileNode* node, int embed );
-
-/* returns name of file node */
-CVAPI(const char*) cvGetFileNodeName( const CvFileNode* node );
-
-/*********************************** Adding own types ***********************************/
-
-CVAPI(void) cvRegisterType( const CvTypeInfo* info );
-CVAPI(void) cvUnregisterType( const char* type_name );
-CVAPI(CvTypeInfo*) cvFirstType(void);
-CVAPI(CvTypeInfo*) cvFindType( const char* type_name );
-CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr );
-
-/* universal functions */
-CVAPI(void) cvRelease( void** struct_ptr );
-CVAPI(void*) cvClone( const void* struct_ptr );
-
-/* simple API for reading/writing data */
-CVAPI(void) cvSave( const char* filename, const void* struct_ptr,
-                    const char* name CV_DEFAULT(NULL),
-                    const char* comment CV_DEFAULT(NULL),
-                    CvAttrList attributes CV_DEFAULT(cvAttrList()));
-CVAPI(void*) cvLoad( const char* filename,
-                     CvMemStorage* memstorage CV_DEFAULT(NULL),
-                     const char* name CV_DEFAULT(NULL),
-                     const char** real_name CV_DEFAULT(NULL) );
-
-/*********************************** Measuring Execution Time ***************************/
-
-/* helper functions for RNG initialization and accurate time measurement:
-   uses internal clock counter on x86 */
-CVAPI(int64)  cvGetTickCount( void );
-CVAPI(double) cvGetTickFrequency( void );
-
-/*********************************** Multi-Threading ************************************/
-
-/* retrieve/set the number of threads used in OpenMP implementations */
-CVAPI(int)  cvGetNumThreads( void );
-CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) );
-/* get index of the thread being executed */
-CVAPI(int)  cvGetThreadNum( void );
-
-/*************** Convenience functions for better interaction with HighGUI **************/
-
-typedef IplImage* (CV_CDECL * CvLoadImageFunc)( const char* filename, int colorness );
-typedef CvMat* (CV_CDECL * CvLoadImageMFunc)( const char* filename, int colorness );
-typedef int (CV_CDECL * CvSaveImageFunc)( const char* filename, const CvArr* image );
-typedef void (CV_CDECL * CvShowImageFunc)( const char* windowname, const CvArr* image );
-
-CVAPI(int) cvSetImageIOFunctions( CvLoadImageFunc _load_image, CvLoadImageMFunc _load_image_m,
-                            CvSaveImageFunc _save_image, CvShowImageFunc _show_image );
-
-#define CV_SET_IMAGE_IO_FUNCTIONS() \
-    cvSetImageIOFunctions( cvLoadImage, cvLoadImageM, cvSaveImage, cvShowImage )
-
-#ifdef __cplusplus
-}
-
-#include "cxcore.hpp"
-#endif
-
-#endif /*_CXCORE_H_*/
+/*M///////////////////////////////////////////////////////////////////////////////////////\r
+//\r
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
+//\r
+//  By downloading, copying, installing or using the software you agree to this license.\r
+//  If you do not agree to this license, do not download, install,\r
+//  copy or use the software.\r
+//\r
+//\r
+//                           License Agreement\r
+//                For Open Source Computer Vision Library\r
+//\r
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.\r
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.\r
+// Third party copyrights are property of their respective owners.\r
+//\r
+// Redistribution and use in source and binary forms, with or without modification,\r
+// are permitted provided that the following conditions are met:\r
+//\r
+//   * Redistribution's of source code must retain the above copyright notice,\r
+//     this list of conditions and the following disclaimer.\r
+//\r
+//   * Redistribution's in binary form must reproduce the above copyright notice,\r
+//     this list of conditions and the following disclaimer in the documentation\r
+//     and/or other materials provided with the distribution.\r
+//\r
+//   * The name of the copyright holders may not be used to endorse or promote products\r
+//     derived from this software without specific prior written permission.\r
+//\r
+// This software is provided by the copyright holders and contributors "as is" and\r
+// any express or implied warranties, including, but not limited to, the implied\r
+// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
+// In no event shall the Intel Corporation or contributors be liable for any direct,\r
+// indirect, incidental, special, exemplary, or consequential damages\r
+// (including, but not limited to, procurement of substitute goods or services;\r
+// loss of use, data, or profits; or business interruption) however caused\r
+// and on any theory of liability, whether in contract, strict liability,\r
+// or tort (including negligence or otherwise) arising in any way out of\r
+// the use of this software, even if advised of the possibility of such damage.\r
+//\r
+//M*/\r
+\r
+\r
+#ifndef _CXCORE_H_\r
+#define _CXCORE_H_\r
+\r
+#include "cxcore.hpp"\r
+\r
+#endif /*_CXCORE_H_*/\r
index 62ef1764d61462612f46284dae093ba6d51e64d5..a8967085c82f894a2613357a59bac35ab2257fdb 100644 (file)
@@ -7,10 +7,11 @@
 //  copy or use the software.
 //
 //
-//                        Intel License Agreement
+//                           License Agreement
 //                For Open Source Computer Vision Library
 //
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
 // Third party copyrights are property of their respective owners.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -23,7 +24,7 @@
 //     this list of conditions and the following disclaimer in the documentation
 //     and/or other materials provided with the distribution.
 //
-//   * The name of Intel Corporation may not be used to endorse or promote products
+//   * The name of the copyright holders may not be used to endorse or promote products
 //     derived from this software without specific prior written permission.
 //
 // This software is provided by the copyright holders and contributors "as is" and
 //
 //M*/
 
-
 #ifndef _CXCORE_HPP_
 #define _CXCORE_HPP_
 
-class CV_EXPORTS CvImage
-{
-public:
-    CvImage() : image(0), refcount(0) {}
-    CvImage( CvSize size, int depth, int channels )
-    {
-        image = cvCreateImage( size, depth, channels );
-        refcount = image ? new int(1) : 0;
-    }
+#include "cxtypes.h"
+#include "cxerror.h"
+#include "cvver.h"
+#include "cxmisc.h"
 
-    CvImage( IplImage* img ) : image(img)
-    {
-        refcount = image ? new int(1) : 0;
-    }
+#ifdef __cplusplus
 
-    CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
-    {
-        if( refcount ) ++(*refcount);
-    }
+#include <algorithm>
+#include <complex>
+#include <map>
+#include <new>
+#include <string>
+#include <vector>
 
-    CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
-    { load( filename, imgname, color ); }
+namespace cv {
 
-    CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
-    { read( fs, mapname, imgname ); }
+template<typename T> struct CV_EXPORTS Size_;
+template<typename T> struct CV_EXPORTS Point_;
+template<typename T> struct CV_EXPORTS Rect_;
 
-    CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
-    { read( fs, seqname, idx ); }
+typedef std::string String;
 
-    ~CvImage()
+struct CV_EXPORTS Exception
+{
+    Exception() { code = 0; line = 0; }
+    Exception(int _code, const String& _err, const String& _func, const String& _file, int _line)
+        : code(_code), err(_err), func(_func), file(_file), line(_line) {}
+    Exception(const Exception& exc)
+        : code(exc.code), err(exc.err), func(exc.func), file(exc.file), line(exc.line) {}
+    Exception& operator = (const Exception& exc)
     {
-        if( refcount && !(--*refcount) )
+        if( this != &exc )
         {
-            cvReleaseImage( &image );
-            delete refcount;
+            code = exc.code; err = exc.err; func = exc.func; file = exc.file; line = exc.line;
         }
+        return *this;
     }
 
-    CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
+    int code;
+    String err;
+    String func;
+    String file;
+    int line;
+};
 
-    void create( CvSize size, int depth, int channels )
-    {
-        if( !image || !refcount ||
-            image->width != size.width || image->height != size.height ||
-            image->depth != depth || image->nChannels != channels )
-            attach( cvCreateImage( size, depth, channels ));
-    }
+CV_EXPORTS String format( const char* fmt, ... );
+CV_EXPORTS void error( const Exception& exc );
 
-    void release() { detach(); }
-    void clear() { detach(); }
+#ifdef __GNUC__
+#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, __func__, __FILE__, __LINE__) )
+#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, __func__, __FILE__, __LINE__) )
+#define CV_Assert( expr ) { if(!(expr)) cv::error( cv::Exception(CV_StsAssert, #expr, __func__, __FILE__, __LINE__) ); }
+#else
+#define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, "", __FILE__, __LINE__) )
+#define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, "", __FILE__, __LINE__) )
+#define CV_Assert( expr ) { if(!(expr)) cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) ); }
+#endif
 
-    void attach( IplImage* img, bool use_refcount=true )
-    {
-        if( refcount && --*refcount == 0 )
-        {
-            cvReleaseImage( &image );
-            delete refcount;
-        }
-        image = img;
-        refcount = use_refcount && image ? new int(1) : 0;
-    }
+CV_EXPORTS void setNumThreads(int);
+CV_EXPORTS int getNumThreads();
+CV_EXPORTS int getThreadNum();
 
-    void detach()
-    {
-        if( refcount && --*refcount == 0 )
-        {
-            cvReleaseImage( &image );
-            delete refcount;
-        }
-        image = 0;
-        refcount = 0;
-    }
+CV_EXPORTS int64 getTickCount();
+CV_EXPORTS double getTickFrequency();
+
+CV_EXPORTS void* fastMalloc(size_t);
+CV_EXPORTS void fastFree(void* ptr);
+
+template<typename T> static inline T* fastMalloc_(size_t n)
+{
+    T* ptr = (T*)fastMalloc(n*sizeof(ptr[0]));
+    ::new(ptr) T[n];
+    return ptr;
+}
 
-    bool load( const char* filename, const char* imgname=0, int color=-1 );
-    bool read( CvFileStorage* fs, const char* mapname, const char* imgname );
-    bool read( CvFileStorage* fs, const char* seqname, int idx );
-    void save( const char* filename, const char* imgname );
-    void write( CvFileStorage* fs, const char* imgname );
+template<typename T> static inline void fastFree_(T* ptr, size_t n)
+{
+    for( size_t i = 0; i < n; i++ ) (ptr+i)->~T();
+    fastFree(ptr);
+}
 
-    void show( const char* window_name );
-    bool is_valid() { return image != 0; }
+template<typename T> static inline T* alignPtr(T* ptr, int n=(int)sizeof(T))
+{
+    return (T*)(((size_t)ptr + n-1) & -n);
+}
 
-    int width() const { return image ? image->width : 0; }
-    int height() const { return image ? image->height : 0; }
+static inline size_t alignSize(size_t sz, int n)
+{
+    return (sz + n-1) & -n;
+}
 
-    CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
+CV_EXPORTS void setUseOptimized(bool);
+CV_EXPORTS bool useOptimized();
 
-    CvSize roi_size() const
-    {
-        return !image ? cvSize(0,0) :
-            !image->roi ? cvSize(image->width,image->height) :
-            cvSize(image->roi->width, image->roi->height);
-    }
+template<typename T> class CV_EXPORTS Allocator
+{
+public: 
+    typedef T value_type;
+    typedef value_type* pointer;
+    typedef const value_type* const_pointer;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    template<typename U> struct rebind { typedef Allocator<U> other; };
+
+public : 
+    explicit Allocator() {}
+    ~Allocator() {}
+    explicit Allocator(Allocator const&) {}
+    template<typename U>
+    explicit Allocator(Allocator<U> const&) {}
+
+    // address
+    pointer address(reference r) { return &r; }
+    const_pointer address(const_reference r) { return &r; }
+
+    pointer allocate(size_type count, const void* =0)
+    { return reinterpret_cast<pointer>(fastMalloc(count * sizeof (T))); }
+
+    void deallocate(pointer p, size_type) {fastFree(p); }
+
+    size_type max_size() const
+    { return max(static_cast<T>(-1)/sizeof(T), 1); }
+
+    void construct(pointer p, const T& v) { new(static_cast<void*>(p)) T(v); }
+    void destroy(pointer p) { p->~T(); }
+};
 
-    CvRect roi() const
-    {
-        return !image ? cvRect(0,0,0,0) :
-            !image->roi ? cvRect(0,0,image->width,image->height) :
-            cvRect(image->roi->xOffset,image->roi->yOffset,
-                   image->roi->width,image->roi->height);
-    }
+/////////////////////// Vec_ (used as element of multi-channel images ///////////////////// 
 
-    int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
+template<typename T> struct CV_EXPORTS DataDepth { enum { value = -1, fmt=(int)'\0' }; };
 
-    void set_roi(CvRect roi) { cvSetImageROI(image,roi); }
-    void reset_roi() { cvResetImageROI(image); }
-    void set_coi(int coi) { cvSetImageCOI(image,coi); }
-    int depth() const { return image ? image->depth : 0; }
-    int channels() const { return image ? image->nChannels : 0; }
-    int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
+template<> struct DataDepth<uchar> { enum { value = CV_8U, fmt=(int)'u' }; };
+template<> struct DataDepth<schar> { enum { value = CV_8S, fmt=(int)'c' }; };
+template<> struct DataDepth<ushort> { enum { value = CV_16U, fmt=(int)'w' }; };
+template<> struct DataDepth<short> { enum { value = CV_16S, fmt=(int)'s' }; };
+template<> struct DataDepth<int> { enum { value = CV_32S, fmt=(int)'i' }; };
+template<> struct DataDepth<float> { enum { value = CV_32F, fmt=(int)'f' }; };
+template<> struct DataDepth<double> { enum { value = CV_64F, fmt=(int)'d' }; };
+template<typename T> struct DataDepth<T*> { enum { value = CV_USRTYPE1, fmt=(int)'r' }; };
 
-    uchar* data() { return image ? (uchar*)image->imageData : 0; }
-    const uchar* data() const { return image ? (const uchar*)image->imageData : 0; }
-    int step() const { return image ? image->widthStep : 0; }
-    int origin() const { return image ? image->origin : 0; }
+template<typename T, int cn> struct CV_EXPORTS Vec_
+{
+    typedef T value_type;
+    enum { depth = DataDepth<T>::value, channels = cn, type = CV_MAKETYPE(depth, channels) };
+    
+    Vec_();
+    Vec_(T v0);
+    Vec_(T v0, T v1);
+    Vec_(T v0, T v1, T v2);
+    Vec_(T v0, T v1, T v2, T v3);
+    Vec_(const Vec_<T, cn>& v);
+    static Vec_ all(T alpha);
+    T dot(const Vec_& v) const;
+    double ddot(const Vec_& v) const;
+    Vec_ cross(const Vec_& v) const;
+    template<typename T2> operator Vec_<T2, cn>() const;
+    operator CvScalar() const;
+    T operator [](int i) const;
+    T& operator[](int i);
+
+    T val[cn];
+};
 
-    uchar* roi_row(int y)
-    {
-        assert(0<=y);
-        assert(!image ?
-                1 : image->roi ?
-                y<image->roi->height : y<image->height);
-        
-        return !image ? 0 :
-            !image->roi ?
-                (uchar*)(image->imageData + y*image->widthStep) :
-                (uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
-                image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
-    }
+typedef Vec_<uchar, 2> Vec2b;
+typedef Vec_<uchar, 3> Vec3b;
+typedef Vec_<uchar, 4> Vec4b;
 
-    const uchar* roi_row(int y) const
-    {
-        assert(0<=y);
-        assert(!image ?
-                1 : image->roi ?
-                y<image->roi->height : y<image->height); 
-
-        return !image ? 0 :
-            !image->roi ?
-                (const uchar*)(image->imageData + y*image->widthStep) :
-                (const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
-                image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
-    }
+typedef Vec_<short, 2> Vec2s;
+typedef Vec_<short, 3> Vec3s;
+typedef Vec_<short, 4> Vec4s;
 
-    operator const IplImage* () const { return image; }
-    operator IplImage* () { return image; }
+typedef Vec_<int, 2> Vec2i;
+typedef Vec_<int, 3> Vec3i;
+typedef Vec_<int, 4> Vec4i;
 
-    CvImage& operator = (const CvImage& img)
-    {
-        if( img.refcount )
-            ++*img.refcount;
-        if( refcount && !(--*refcount) )
-            cvReleaseImage( &image );
-        image=img.image;
-        refcount=img.refcount;
-        return *this;
-    }
+typedef Vec_<float, 2> Vec2f;
+typedef Vec_<float, 3> Vec3f;
+typedef Vec_<float, 4> Vec4f;
 
-protected:
-    IplImage* image;
-    int* refcount;
+typedef Vec_<double, 2> Vec2d;
+typedef Vec_<double, 3> Vec3d;
+typedef Vec_<double, 4> Vec4d;
+
+//////////////////////////////// Complex //////////////////////////////
+
+template<typename T> struct CV_EXPORTS Complex
+{
+    Complex();
+    Complex( T _re, T _im=0 );
+    template<typename T2> operator Complex<T2>() const;
+    Complex conj() const;
+
+    T re, im;
 };
 
+typedef Complex<float> Complexf;
+typedef Complex<double> Complexd;
+
+//////////////////////////////// Point_ ////////////////////////////////
 
-class CV_EXPORTS CvMatrix
+template<typename T> struct CV_EXPORTS Point_
 {
-public:
-    CvMatrix() : matrix(0) {}
-    CvMatrix( int rows, int cols, int type )
-    { matrix = cvCreateMat( rows, cols, type ); }
+    typedef T value_type;
+    
+    Point_();
+    Point_(T _x, T _y);
+    Point_(const Point_& pt);
+    Point_(const CvPoint& pt);
+    Point_(const CvPoint2D32f& pt);
+    Point_(const Size_<T>& sz);
+    Point_& operator = (const Point_& pt);
+    operator Point_<int>() const;
+    operator Point_<float>() const;
+    operator Point_<double>() const;
+    operator CvPoint() const;
+    operator CvPoint2D32f() const;
+
+    T dot(const Point_& pt) const;
+    double ddot(const Point_& pt) const;
+    bool inside(const Rect_<T>& r) const;
+    
+    T x, y;
+};
 
-    CvMatrix( int rows, int cols, int type, CvMat* hdr,
-              void* data=0, int step=CV_AUTOSTEP )
-    { matrix = cvInitMatHeader( hdr, rows, cols, type, data, step ); }
+template<typename T> struct CV_EXPORTS Point3_
+{
+    typedef T value_type;
+    
+    Point3_();
+    Point3_(T _x, T _y, T _z);
+    Point3_(const Point3_& pt);
+    Point3_(const CvPoint3D32f& pt);
+    Point3_(const Vec_<T, 3>& t);
+    Point3_& operator = (const Point3_& pt);
+    Point3_& operator += (const Point3_& pt);
+    Point3_& operator -= (const Point3_& pt);
+    operator Point3_<int>() const;
+    operator Point3_<float>() const;
+    operator Point3_<double>() const;
+    operator CvPoint3D32f() const;
+
+    T dot(const Point3_& pt) const;
+    double ddot(const Point3_& pt) const;
+    
+    T x, y, z;
+};
 
-    CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
+//////////////////////////////// Size_ ////////////////////////////////
 
-    CvMatrix( int rows, int cols, int type, void* data, int step=CV_AUTOSTEP )
-    { matrix = cvCreateMatHeader( rows, cols, type );
-      cvSetData( matrix, data, step ); }
+template<typename T> struct CV_EXPORTS Size_
+{
+    typedef T value_type;
+    
+    Size_();
+    Size_(T _width, T _height);
+    Size_(const Size_& sz);
+    Size_(const CvSize& sz);
+    Size_(const Point_<T>& pt);
+    Size_& operator = (const Size_& sz);
+    T area() const;
+
+    operator Size_<int>() const;
+    operator Size_<float>() const;
+    operator Size_<double>() const;
+    operator CvSize() const;
+
+    T width, height;
+};
 
-    CvMatrix( CvMat* m )
-    { matrix = m; }
+//////////////////////////////// Rect_ ////////////////////////////////
 
-    CvMatrix( const CvMatrix& m )
-    {
-        matrix = m.matrix;
-        addref();
-    }
+template<typename T> struct CV_EXPORTS Rect_
+{
+    typedef T value_type;
+    
+    Rect_();
+    Rect_(T _x, T _y, T _width, T _height);
+    Rect_(const Rect_& r);
+    Rect_(const CvRect& r);
+    Rect_(const Point_<T>& org, const Size_<T>& sz);
+    Rect_(const Point_<T>& pt1, const Point_<T>& pt2);
+    Rect_& operator = ( const Rect_& r );
+    Point_<T> tl() const;
+    Point_<T> br() const;
+    
+    Size_<T> size() const;
+    T area() const;
+
+    operator Rect_<int>() const;
+    operator Rect_<float>() const;
+    operator Rect_<double>() const;
+    operator CvRect() const;
+
+    bool contains(const Point_<T>& pt) const;
+
+    T x, y, width, height;
+};
 
-    CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
-    {  load( filename, matname, color ); }
+typedef Point_<int> Point2i;
+typedef Point2i Point;
+typedef Size_<int> Size2i;
+typedef Size2i Size;
+typedef Rect_<int> Rect;
+typedef Point_<float> Point2f;
+typedef Point_<double> Point2d;
+typedef Size_<float> Size2f;
+typedef Point3_<int> Point3i;
+typedef Point3_<float> Point3f;
+typedef Point3_<double> Point3d;
+
+struct CV_EXPORTS RotatedRect
+{
+    RotatedRect();
+    RotatedRect(const Point2f& _center, const Size2f& _size, float _angle);
+    Point2f center;
+    Size2f size;
+    float angle;
+};
 
-    CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
-    {  read( fs, mapname, matname ); }
+//////////////////////////////// Scalar_ ///////////////////////////////
 
-    CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
-    {  read( fs, seqname, idx ); }
+template<typename T> struct CV_EXPORTS Scalar_ : Vec_<T, 4>
+{
+    Scalar_();
+    Scalar_(T v0, T v1, T v2=0, T v3=0);
+    Scalar_(const CvScalar& s);
+    Scalar_(T v0);
+    static Scalar_<T> all(T v0);
+    operator CvScalar() const;
 
-    ~CvMatrix()
-    {
-        release();
-    }
+    template<typename T2> operator Scalar_<T2>() const;
 
-    CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
+    Scalar_<T> mul(const Scalar_<T>& t, double scale=1 ) const;
+    template<typename T2> void convertTo(T2* buf, int channels, int unroll_to=0) const;
+};
 
-    void set( CvMat* m, bool add_ref )
-    {
-        release();
-        matrix = m;
-        if( add_ref )
-            addref();
-    }
+typedef Scalar_<double> Scalar;
 
-    void create( int rows, int cols, int type )
-    {
-        if( !matrix || !matrix->refcount ||
-            matrix->rows != rows || matrix->cols != cols ||
-            CV_MAT_TYPE(matrix->type) != type )
-            set( cvCreateMat( rows, cols, type ), false );
-    }
+//////////////////////////////// Range /////////////////////////////////
 
-    void addref() const
-    {
-        if( matrix )
-        {
-            if( matrix->hdr_refcount )
-                ++matrix->hdr_refcount;
-            else if( matrix->refcount )
-                ++*matrix->refcount;
-        }
-    }
+struct CV_EXPORTS Range
+{
+    Range();
+    Range(int _start, int _end);
+    int size() const;
+    bool empty() const;
+    static Range all();
 
-    void release()
-    {
-        if( matrix )
-        {
-            if( matrix->hdr_refcount )
-            {
-                if( --matrix->hdr_refcount == 0 )
-                    cvReleaseMat( &matrix );
-            }
-            else if( matrix->refcount )
-            {
-                if( --*matrix->refcount == 0 )
-                    cvFree( &matrix->refcount );
-            }
-            matrix = 0;
-        }
-    }
+    int start, end;
+};
 
-    void clear()
-    {
-        release();
-    }
+/////////////////////////////// DataType ////////////////////////////////
 
-    bool load( const char* filename, const char* matname=0, int color=-1 );
-    bool read( CvFileStorage* fs, const char* mapname, const char* matname );
-    bool read( CvFileStorage* fs, const char* seqname, int idx );
-    void save( const char* filename, const char* matname );
-    void write( CvFileStorage* fs, const char* matname );
+template<typename T> struct DataType
+{
+    typedef T value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    void show( const char* window_name );
+template<> struct DataType<uchar>
+{
+    typedef uchar value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    bool is_valid() { return matrix != 0; }
+template<> struct DataType<schar>
+{
+    typedef schar value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    int rows() const { return matrix ? matrix->rows : 0; }
-    int cols() const { return matrix ? matrix->cols : 0; }
+template<> struct DataType<ushort>
+{
+    typedef ushort value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    CvSize size() const
-    {
-        return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
-    }
+template<> struct DataType<short>
+{
+    typedef short value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; }
-    int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; }
-    int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; }
-    int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; }
+template<> struct DataType<int>
+{
+    typedef int value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    uchar* data() { return matrix ? matrix->data.ptr : 0; }
-    const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
-    int step() const { return matrix ? matrix->step : 0; }
+template<> struct DataType<float>
+{
+    typedef float value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    void set_data( void* data, int step=CV_AUTOSTEP )
-    { cvSetData( matrix, data, step ); }
+template<> struct DataType<double>
+{
+    typedef double value_type;
+    typedef value_type channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 1,
+           fmt=DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
-    const uchar* row(int i) const
-    { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
+template<typename T, int cn> struct DataType<Vec_<T, cn> >
+{
+    typedef Vec_<T, cn> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = cn,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    operator const CvMat* () const { return matrix; }
-    operator CvMat* () { return matrix; }
+template<typename T> struct DataType<std::complex<T> >
+{
+    typedef std::complex<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 2,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
 
-    CvMatrix& operator = (const CvMatrix& _m)
+template<typename T> struct DataType<Complex<T> >
+{
+    typedef Complex<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 2,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+template<typename T> struct DataType<Point_<T> >
+{
+    typedef Point_<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 2,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+template<typename T> struct DataType<Point3_<T> >
+{
+    typedef Point3_<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 3,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+template<typename T> struct DataType<Size_<T> >
+{
+    typedef Size_<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 2,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+template<typename T> struct DataType<Rect_<T> >
+{
+    typedef Rect_<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 4,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+template<typename T> struct DataType<Scalar_<T> >
+{
+    typedef Scalar_<T> value_type;
+    typedef T channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 4,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+template<> struct DataType<Range>
+{
+    typedef Range value_type;
+    typedef int channel_type;
+    enum { depth = DataDepth<channel_type>::value, channels = 2,
+           fmt = ((channels-1)<<8) + DataDepth<channel_type>::fmt,
+           type = CV_MAKETYPE(depth, channels) };
+};
+
+
+//////////////////////////////// Vector ////////////////////////////////
+
+// template vector class. It is similar to STL's vector,
+// with a few important differences:
+//   1) it can be created on top of user-allocated data w/o copying it
+//   2) Vector b = a means copying the header,
+//      not the underlying data (use clone() to make a deep copy)
+template <typename T> class CV_EXPORTS Vector
+{
+public:
+    typedef T value_type;
+    typedef T* iterator;
+    typedef const T* const_iterator;
+
+    struct CV_EXPORTS Hdr
     {
-        _m.addref();
-        release();
-        matrix = _m.matrix;
-        return *this;
-    }
+        Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {};
+        T* data;
+        T* datastart;
+        volatile int* refcount;
+        size_t size;
+        size_t capacity;
+    };
+
+    Vector();
+    Vector(size_t _size);
+    Vector(size_t _size, const T& val);
+    Vector(T* _data, size_t _size, bool _copyData=false);
+    Vector(const std::vector<T>& vec, bool _copyData=false);
+    Vector(const Vector& d);
+    Vector(const Vector& d, const Range& r);
+
+    Vector& operator = (const Vector& d);
+
+    ~Vector();
+    Vector clone() const;
+
+    operator T* ();
+    operator const T* () const;
+    T& operator [] (size_t i);
+    T operator [] (size_t i) const;
+    T& operator [] (int i);
+    T operator [] (int i) const;
+    Vector operator() (const Range& r) const;
+    T& back();
+    T back() const;
+    T& front();
+    T front() const;
+
+    T* begin();
+    T* end();
+    const T* begin() const;
+    const T* end() const;
+
+    void release();
+    void set(T* _data, size_t _size, bool _copyData=false);
+
+    void reserve(size_t newCapacity);
+    void resize(size_t newSize);
+    Vector<T>& push_back(const T& elem);
+    Vector<T>& pop_back();
+    size_t size() const;
+    size_t capacity() const;
+    bool empty() const;
+    void clear();
 
 protected:
-    CvMat* matrix;
+    Hdr hdr;
+};
+
+//////////////////// Generic ref-cointing pointer class for C/C++ objects ////////////////////////
+
+template<typename T> struct CV_EXPORTS ObjPtr
+{
+    ObjPtr();
+    ObjPtr(T* _obj);
+    ~ObjPtr();
+    ObjPtr(const ObjPtr& ptr);
+    ObjPtr& operator = (const ObjPtr& ptr);
+    void addref();
+    void release();
+    void delete_obj();
+
+    T* operator -> ();
+    const T* operator -> () const;
+
+    operator T* ();
+    operator const T*() const;
+
+    T* obj;
+    int* refcount;
+};
+
+//////////////////////////////// Mat ////////////////////////////////
+
+struct MatExpr_Base;
+template<typename E, typename M> struct MatExpr_;
+template<typename A1, typename M, typename Op> struct MatExpr_Op1_;
+template<typename A1, typename A2, typename M, typename Op> struct MatExpr_Op2_;
+template<typename A1, typename A2, typename A3, typename M, typename Op> struct MatExpr_Op3_;
+template<typename A1, typename A2, typename A3, typename A4,
+        typename M, typename Op> struct MatExpr_Op4_;
+template<typename A1, typename A2, typename A3, typename A4,
+        typename A5, typename M, typename Op> struct MatExpr_Op5_;
+template<typename M> struct CV_EXPORTS MatOp_DivRS_;
+template<typename M> struct CV_EXPORTS MatOp_Inv_;
+template<typename M> struct CV_EXPORTS MatOp_MulDiv_;
+template<typename M> struct CV_EXPORTS MatOp_Repeat_;
+template<typename M> struct CV_EXPORTS MatOp_Set_;
+template<typename M> struct CV_EXPORTS MatOp_Scale_;
+template<typename M> struct CV_EXPORTS MatOp_T_;
+
+struct Mat;
+
+typedef MatExpr_<MatExpr_Op4_<Size, int, Scalar,
+    int, Mat, MatOp_Set_<Mat> >, Mat> MatExpr_Initializer;
+
+template<typename T> struct MatIterator_;
+template<typename T> struct MatConstIterator_;
+
+enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 };
+
+static inline int getElemSize(int type) { return CV_ELEM_SIZE(type); }
+
+// matrix decomposition types
+enum { DECOMP_LU=0, DECOMP_SVD=1, DECOMP_EIG=2, DECOMP_CHOLESKY=3, DECOMP_QR=4, DECOMP_NORMAL=16 };
+enum { NORM_INF=1, NORM_L1=2, NORM_L2=4, NORM_RELATIVE=8};
+enum { CMP_EQ=0, CMP_GT=1, CMP_GE=2, CMP_LT=3, CMP_LE=4, CMP_NE=5 };
+enum { GEMM_1_T=1, GEMM_2_T=2, GEMM_3_T=4 };
+enum { DFT_INVERSE=1, DFT_SCALE=2, DFT_ROWS=4, DFT_COMPLEX_OUTPUT=16, DFT_REAL_OUTPUT=32,
+    DCT_INVERSE = DFT_INVERSE, DCT_ROWS=DFT_ROWS };
+
+struct CV_EXPORTS Mat
+{
+    Mat();
+    Mat(int _rows, int _cols, int _type);
+    Mat(int _rows, int _cols, int _type, const Scalar& _s);
+    Mat(Size _size, int _type);
+    Mat(const Mat& m);
+    Mat(int _rows, int _cols, int _type, void* _data, int _step=AUTO_STEP);
+    Mat(Size _size, int _type, void* _data, int _step=AUTO_STEP);
+    Mat(const Mat& m, const Range& rowRange, const Range& colRange);
+    Mat(const Mat& m, const Rect& roi);
+    Mat(const CvMat* m, bool copyData=false);
+    Mat(const IplImage* img, bool copyData=false);
+    Mat( const MatExpr_Base& expr );
+    ~Mat();
+    Mat& operator = (const Mat& m);
+    Mat& operator = (const MatExpr_Base& expr);
+
+    operator MatExpr_<Mat, Mat>() const;
+
+    Mat row(int y) const;
+    Mat col(int x) const;
+    Mat rowRange(int startrow, int endrow) const;
+    Mat rowRange(const Range& r) const;
+    Mat colRange(int startcol, int endcol) const;
+    Mat colRange(const Range& r) const;
+    Mat diag(int d=0) const;
+    static Mat diag(const Mat& d);
+
+    Mat clone() const;
+    void copyTo( Mat& m ) const;
+    void copyTo( Mat& m, const Mat& mask ) const;
+    void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
+
+    void assignTo( Mat& m, int type=-1 ) const;
+    Mat& operator = (const Scalar& s);
+    Mat& setTo(const Scalar& s, const Mat& mask=Mat());
+    Mat reshape(int _cn, int _rows=0) const;
+
+    MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> >, Mat>
+    t() const;
+    MatExpr_<MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> >, Mat>
+        inv(int method=DECOMP_LU) const;
+    MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
+    mul(const Mat& m, double scale=1) const;
+    MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
+    mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>& m, double scale=1) const;
+    MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>    
+    mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat>& m, double scale=1) const;
+
+    Mat cross(const Mat& m) const;
+    double dot(const Mat& m) const;
+
+    static MatExpr_Initializer zeros(int rows, int cols, int type);
+    static MatExpr_Initializer zeros(Size size, int type);
+    static MatExpr_Initializer ones(int rows, int cols, int type);
+    static MatExpr_Initializer ones(Size size, int type);
+    static MatExpr_Initializer eye(int rows, int cols, int type);
+    static MatExpr_Initializer eye(Size size, int type);
+
+    void create(int _rows, int _cols, int _type);
+    void create(Size _size, int _type);
+    void release();
+
+    void locateROI( int& drow, int& allrows, int& dcol, int& allcols );
+    Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+    Mat operator()( Range rowRange, Range colRange ) const;
+    Mat operator()( const Rect& roi ) const;
+
+    operator CvMat() const;
+    bool isContinuous() const;
+    int elemSize() const;
+    int elemSize1() const;
+    int type() const;
+    int depth() const;
+    int channels() const;
+    int step1() const;
+    Size size() const;
+
+    uchar* ptr(int y=0);
+    const uchar* ptr(int y=0) const;
+
+    enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=-1, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG };
+
+    int flags;
+    int rows, cols;
+    int step;
+    uchar* data;
+    volatile int* refcount;
+
+    uchar* datastart;
+    uchar* dataend;
+};
+
+
+// Multiply-with-Carry RNG
+struct CV_EXPORTS RNG
+{
+    enum { A=4164903690U, UNIFORM=0, NORMAL=1 };
+
+    RNG();
+    RNG(unsigned seed);
+    RNG(uint64 _state);
+    unsigned next();
+
+    operator uchar();
+    operator schar();
+    operator ushort();
+    operator short();
+    operator unsigned();
+    operator int();
+    operator float();
+    operator double();
+    void fill( Mat& mat, int distType, const Scalar& a, const Scalar& b );
+
+    uint64 state;
+};
+
+struct CV_EXPORTS TermCriteria
+{
+    enum { COUNT=1, EPS=2 };
+
+    TermCriteria();
+    TermCriteria(int _type, int _maxCount, double _epsilon);
+    
+    int type;
+    int maxCount;
+    double epsilon;
+};
+
+CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false, bool allowND=true);
+CV_EXPORTS Mat extractImageCOI(const CvArr* arr);
+
+CV_EXPORTS void add(const Mat& a, const Mat& b, Mat& c, const Mat& mask);
+CV_EXPORTS void subtract(const Mat& a, const Mat& b, Mat& c, const Mat& mask);
+CV_EXPORTS void add(const Mat& a, const Mat& b, Mat& c);
+CV_EXPORTS void subtract(const Mat& a, const Mat& b, Mat& c);
+CV_EXPORTS void add(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void subtract(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
+
+CV_EXPORTS void multiply(const Mat& a, const Mat& b, Mat& c, double scale=1);
+CV_EXPORTS void divide(const Mat& a, const Mat& b, Mat& c, double scale=1);
+CV_EXPORTS void divide(double scale, const Mat& b, Mat& c);
+
+CV_EXPORTS void subtract(const Scalar& s, const Mat& a, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void scaleAdd(const Mat& a, double alpha, const Mat& b, Mat& c);
+CV_EXPORTS void addWeighted(const Mat& a, double alpha, const Mat& b,
+                            double beta, double gamma, Mat& c);
+CV_EXPORTS void convertScaleAbs(const Mat& a, Mat& c, double alpha=1, double beta=0);
+CV_EXPORTS void LUT(const Mat& a, const Mat& lut, Mat& b);
+
+CV_EXPORTS Scalar sum(const Mat& m);
+
+CV_EXPORTS Scalar mean(const Mat& m);
+CV_EXPORTS Scalar mean(const Mat& m, const Mat& mask);
+CV_EXPORTS void meanStdDev(const Mat& m, Scalar& mean, Scalar& stddev, const Mat& mask=Mat());
+CV_EXPORTS double norm(const Mat& a, int normType=NORM_L2);
+CV_EXPORTS double norm(const Mat& a, const Mat& b, int normType=NORM_L2);
+CV_EXPORTS double norm(const Mat& a, int normType, const Mat& mask);
+CV_EXPORTS double norm(const Mat& a, const Mat& b,
+                       int normType, const Mat& mask);
+CV_EXPORTS void normalize( const Mat& a, Mat& b, double alpha=1, double beta=0,
+                          int norm_type=NORM_L2, int rtype=-1, const Mat& mask=Mat());
+
+CV_EXPORTS void minMaxLoc(const Mat& a, double* minVal,
+                          double* maxVal=0, Point* minLoc=0,
+                          Point* maxLoc=0, const Mat& mask=Mat());
+CV_EXPORTS void reduce(const Mat& m, Mat& dst, int dim, int rtype, int dtype=-1);
+CV_EXPORTS void merge(const Vector<Mat>& mv, Mat& dst);
+CV_EXPORTS void split(const Mat& m, Vector<Mat>& mv);
+CV_EXPORTS void mixChannels(const Vector<Mat>& src, Vector<Mat>& dst,
+                            const Vector<int>& fromTo);
+CV_EXPORTS void flip(const Mat& a, Mat& b, int flipCode);
+
+CV_EXPORTS void repeat(const Mat& a, int ny, int nx, Mat& b);
+static inline Mat repeat(const Mat& src, int ny, int nx)
+{
+    if( nx == 1 && ny == 1 ) return src;
+    Mat dst; repeat(src, ny, nx, dst); return dst;
+}
+
+CV_EXPORTS void bitwise_and(const Mat& a, const Mat& b, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void bitwise_or(const Mat& a, const Mat& b, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void bitwise_xor(const Mat& a, const Mat& b, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void bitwise_and(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void bitwise_or(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void bitwise_xor(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
+CV_EXPORTS void bitwise_not(const Mat& a, Mat& c);
+CV_EXPORTS void absdiff(const Mat& a, const Mat& b, Mat& c);
+CV_EXPORTS void absdiff(const Mat& a, const Scalar& s, Mat& c);
+CV_EXPORTS void inRange(const Mat& src, const Mat& lowerb,
+                        const Mat& upperb, Mat& dst);
+CV_EXPORTS void inRange(const Mat& src, const Scalar& lowerb,
+                        const Scalar& upperb, Mat& dst);
+CV_EXPORTS void compare(const Mat& a, const Mat& b, Mat& c, int cmpop);
+CV_EXPORTS void compare(const Mat& a, double s, Mat& c, int cmpop);
+CV_EXPORTS void min(const Mat& a, const Mat& b, Mat& c);
+CV_EXPORTS void min(const Mat& a, double alpha, Mat& c);
+CV_EXPORTS void max(const Mat& a, const Mat& b, Mat& c);
+CV_EXPORTS void max(const Mat& a, double alpha, Mat& c);
+
+CV_EXPORTS void sqrt(const Mat& a, Mat& b);
+CV_EXPORTS void pow(const Mat& a, double power, Mat& b);
+CV_EXPORTS void exp(const Mat& a, Mat& b);
+CV_EXPORTS void log(const Mat& a, Mat& b);
+CV_EXPORTS float cubeRoot(float val);
+CV_EXPORTS float fastAtan2(float y, float x);
+CV_EXPORTS void polarToCart(const Mat& magnitude, const Mat& angle,
+                            Mat& x, Mat& y, bool angleInDegrees=false);
+CV_EXPORTS void cartToPolar(const Mat& x, const Mat& y,
+                            const Mat& magnitude, const Mat& angle,
+                            bool angleInDegrees=false);
+CV_EXPORTS bool checkRange(const Mat& a, bool quiet=true, Point* pt=0,
+                           double minVal=-DBL_MAX, double maxVal=DBL_MAX);
+
+CV_EXPORTS void gemm(const Mat& a, const Mat& b, double alpha,
+                     const Mat& c, double gamma, Mat& d, int flags=0);
+CV_EXPORTS void mulTransposed( const Mat& a, Mat& c, bool aTa,
+                               const Mat& delta=Mat(),
+                               double scale=1, int rtype=-1 );
+CV_EXPORTS void transpose(const Mat& a, Mat& b);
+CV_EXPORTS void transform(const Mat& src, Mat& dst, const Mat& m );
+CV_EXPORTS void perspectiveTransform(const Mat& src, Mat& dst, const Mat& m );
+
+CV_EXPORTS void completeSymm(Mat& a, bool lowerToUpper=false);
+CV_EXPORTS void setIdentity(Mat& c, const Scalar& s=Scalar(1));
+CV_EXPORTS double determinant(const Mat& m);
+CV_EXPORTS Scalar trace(const Mat& m);
+CV_EXPORTS double invert(const Mat& a, Mat& c, int flags=DECOMP_LU);
+CV_EXPORTS bool solve(const Mat& a, const Mat& b, Mat& x, int flags=DECOMP_LU);
+CV_EXPORTS void sort(const Mat& a, Mat& b, int flags);
+CV_EXPORTS void sortIdx(const Mat& a, Mat& b, int flags);
+CV_EXPORTS void solveCubic(const Mat& coeffs, Mat& roots);
+CV_EXPORTS void solvePoly(const Mat& coeffs, Mat& roots, int maxIters=20, int fig=100);
+CV_EXPORTS bool eigen(const Mat& a, Mat& eigenvalues);
+CV_EXPORTS bool eigen(const Mat& a, Mat& eigenvalues, Mat& eigenvectors);
+
+CV_EXPORTS void calcCovariation( const Vector<Mat>& data, Mat& covar, Mat& mean,
+                                 int flags, int ctype=CV_64F);
+CV_EXPORTS void calcCovariation( const Mat& data, Mat& covar, Mat& mean,
+                                 int flags, int ctype=CV_64F);
+
+struct CV_EXPORTS PCA
+{
+    PCA();
+    PCA(const Mat& data, const Mat& mean, int flags, int maxComponents=0);
+    PCA& operator()(const Mat& data, const Mat& mean, int flags, int maxComponents=0);
+    Mat project(const Mat& vec) const;
+    Mat backProject(const Mat& vec) const;
+
+    Mat eigenvectors;
+    Mat eigenvalues;
+    Mat mean;
 };
 
+struct CV_EXPORTS SVD
+{
+    enum { MODIFY_A=1, NO_UV=2, FULL_UV=4 };
+    SVD();
+    SVD( const Mat& m, int flags=0 );
+    SVD& operator ()( const Mat& m, int flags=0 );
+
+    static void solveZ( const Mat& m, Mat& dst );
+    void backSubst( const Mat& rhs, Mat& dst ) const;
+
+    Mat u, w, vt;
+};
 
-// classes for automatic module/RTTI data registration/unregistration
-struct CV_EXPORTS CvModule
+CV_EXPORTS double mahalanobis(const Mat& v1, const Mat& v2, const Mat& icovar);
+static inline double mahalonobis(const Mat& v1, const Mat& v2, const Mat& icovar)
+{ return mahalanobis(v1, v2, icovar); }
+
+CV_EXPORTS void dft(const Mat& src, Mat& dst, int flags=0, int nonzeroRows=0);
+CV_EXPORTS void idft(const Mat& src, Mat& dst, int flags=0, int nonzeroRows=0);
+CV_EXPORTS void dct(const Mat& src, Mat& dst, int flags=0);
+CV_EXPORTS void idct(const Mat& src, Mat& dst, int flags=0);
+CV_EXPORTS void mulSpectrums(const Mat& a, const Mat& b, Mat& c,
+                             int flags, bool conjB=false);
+CV_EXPORTS int getOptimalDFTSize(int vecsize);
+
+CV_EXPORTS int kmeans( const Mat& samples, int K,
+                       Mat& labels, Mat& centers,
+                       TermCriteria crit, int attempts=1,
+                       int flags=0, double* compactness=0);
+
+CV_EXPORTS void seqToVector( const CvSeq* ptseq, Vector<Point>& pts );
+
+CV_EXPORTS RNG& theRNG();
+static inline int randi() { return (int)theRNG(); }
+static inline unsigned randu() { return (unsigned)theRNG(); }
+static inline float randf() { return (float)theRNG(); }
+static inline double randd() { return (double)theRNG(); }
+static inline void randu(Mat& dst, const Scalar& low, const Scalar& high)
+{ theRNG().fill(dst, RNG::UNIFORM, low, high); }
+static inline void randn(Mat& dst, const Scalar& mean, const Scalar& stddev)
+{ theRNG().fill(dst, RNG::NORMAL, mean, stddev); }
+CV_EXPORTS void randShuffle(Mat& dst, RNG& rng, double iterFactor=1.);
+static inline void randShuffle(Mat& dst, double iterFactor=1.)
+{ randShuffle(dst, theRNG(), iterFactor); }
+
+CV_EXPORTS void line(Mat& img, Point pt1, Point pt2, const Scalar& color,
+                     int thickness=1, int lineType=8, int shift=0);
+
+CV_EXPORTS void rectangle(Mat& img, Point pt1, Point pt2,
+                          const Scalar& color, int thickness=1,
+                          int lineType=8, int shift=0);
+
+CV_EXPORTS void circle(Mat& img, Point center, int radius,
+                       const Scalar& color, int thickness=1,
+                       int lineType=8, int shift=0);
+
+CV_EXPORTS void ellipse(Mat& img, Point center, Size axes,
+                        double angle, double startAngle, double endAngle,
+                        const Scalar& color, int thickness=1,
+                        int lineType=8, int shift=0);
+
+CV_EXPORTS void ellipse(Mat& img, const RotatedRect& box, const Scalar& color,
+                        int thickness=1, int lineType=8, int shift=0 );
+
+CV_EXPORTS void fillConvexPoly(Mat& img, const Vector<Point>& pts,
+                               const Scalar& color, int lineType=8,
+                               int shift=0);
+
+CV_EXPORTS void fillPoly(Mat& img, const Vector<Vector<Point> >& pts,
+                         const Scalar& color, int lineType=8, int shift=0,
+                         Point offset=Point() );
+
+CV_EXPORTS void polylines(Mat& img, const Vector<Vector<Point> >& pts, bool isClosed,
+                          const Scalar& color, int thickness=1, int lineType=8, int shift=0 );
+
+CV_EXPORTS bool clipLine(Size imgSize, Point& pt1, Point& pt2);
+
+struct CV_EXPORTS LineIterator
 {
-    CvModule( CvModuleInfo* _info );
-    ~CvModule();
-    CvModuleInfo* info;
+    LineIterator(const Mat& img, Point pt1, Point pt2,
+                 int connectivity=8, bool leftToRight=false);
+    uchar* operator *();
+    LineIterator& operator ++();
+    LineIterator operator ++(int);
+
+    uchar* ptr;
+    int err, count;
+    int minusDelta, plusDelta;
+    int minusStep, plusStep;
+};
+
+CV_EXPORTS void ellipse2Poly( Point center, Size axes, int angle,
+                              int arcStart, int arcEnd, int delta, Vector<Point>& pts );
 
-    static CvModuleInfo* first;
-    static CvModuleInfo* last;
+enum
+{
+    FONT_HERSHEY_SIMPLEX = 0,
+    FONT_HERSHEY_PLAIN = 1,
+    FONT_HERSHEY_DUPLEX = 2,
+    FONT_HERSHEY_COMPLEX = 3,
+    FONT_HERSHEY_TRIPLEX = 4,
+    FONT_HERSHEY_COMPLEX_SMALL = 5,
+    FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
+    FONT_HERSHEY_SCRIPT_COMPLEX = 7,
+    FONT_ITALIC = 16
 };
 
-struct CV_EXPORTS CvType
+CV_EXPORTS void putText( Mat& img, const String& text, Point org,
+                         int fontFace, double fontScale, Scalar color,
+                         int thickness=1, int linetype=8,
+                         bool bottomLeftOrigin=false );
+
+CV_EXPORTS Size getTextSize(const String& text, int fontFace,
+                            double fontScale, int thickness,
+                            int* baseLine);
+
+///////////////////////////////// Mat_<T> ////////////////////////////////////
+
+template<typename T> struct CV_EXPORTS Mat_ : public Mat
 {
-    CvType( const char* type_name,
-            CvIsInstanceFunc is_instance, CvReleaseFunc release=0,
-            CvReadFunc read=0, CvWriteFunc write=0, CvCloneFunc clone=0 );
-    ~CvType();
-    CvTypeInfo* info;
+    typedef T value_type;
+    typedef typename DataType<T>::channel_type channel_type;
+    typedef MatIterator_<T> iterator;
+    typedef MatConstIterator_<T> const_iterator;
+    
+    Mat_();
+    Mat_(int _rows, int _cols);
+    Mat_(int _rows, int _cols, const T& value);
+    Mat_(const Mat& m);
+    Mat_(const Mat_& m);
+    Mat_(int _rows, int _cols, T* _data, int _step=AUTO_STEP);
+    Mat_(const Mat_& m, const Range& rowRange, const Range& colRange);
+    Mat_(const Mat_& m, const Rect& roi);
+    Mat_(const MatExpr_Base& expr);
+    ~Mat_();
+
+    Mat_& operator = (const Mat& m);
+    Mat_& operator = (const Mat_& m);
+    Mat_& operator = (const T& s);
+
+    iterator begin();
+    iterator end();
+    const_iterator begin() const;
+    const_iterator end() const;
+
+    Mat_& create(int _rows, int _cols);
+    Mat_& create(Size _size);
+    Mat_ cross(const Mat_& m) const;
+    Mat_& operator = (const MatExpr_Base& expr);
+    template<typename T2> operator Mat_<T2>() const;
+    Mat_ row(int y) const;
+    Mat_ col(int x) const;
+    Mat_ diag(int d=0) const;
+    Mat_ clone() const;
+
+    MatExpr_<MatExpr_Op2_<Mat_, double, Mat_, MatOp_T_<Mat> >, Mat_> t() const;
+    MatExpr_<MatExpr_Op2_<Mat_, int, Mat_, MatOp_Inv_<Mat> >, Mat_> inv(int method=DECOMP_LU) const;
+
+    MatExpr_<MatExpr_Op4_<Mat_, Mat_, double, char, Mat_, MatOp_MulDiv_<Mat> >, Mat_>
+    mul(const Mat_& m, double scale=1) const;
+    MatExpr_<MatExpr_Op4_<Mat_, Mat_, double, char, Mat_, MatOp_MulDiv_<Mat> >, Mat_>
+    mul(const MatExpr_<MatExpr_Op2_<Mat_, double, Mat_,
+        MatOp_Scale_<Mat> >, Mat_>& m, double scale=1) const;
+    MatExpr_<MatExpr_Op4_<Mat_, Mat_, double, char, Mat_, MatOp_MulDiv_<Mat> >, Mat_>    
+    mul(const MatExpr_<MatExpr_Op2_<Mat_, double, Mat_,
+        MatOp_DivRS_<Mat> >, Mat_>& m, double scale=1) const;
+
+    int elemSize() const;
+    int elemSize1() const;
+    int type() const;
+    int depth() const;
+    int channels() const;
+    int stepT() const;
+    int step1() const;
+
+    static MatExpr_Initializer zeros(int rows, int cols);
+    static MatExpr_Initializer zeros(Size size);
+    static MatExpr_Initializer ones(int rows, int cols);
+    static MatExpr_Initializer ones(Size size);
+    static MatExpr_Initializer eye(int rows, int cols);
+    static MatExpr_Initializer eye(Size size);
+
+    Mat_ reshape(int _rows) const;
+    Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
+    Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
+    Mat_ operator()( const Rect& roi ) const;
+
+    T* operator [](int y);
+    const T* operator [](int y) const;
+
+    T& operator ()(int row, int col);
+    T operator ()(int row, int col) const;
+
+    operator MatExpr_<Mat_, Mat_>() const;
+};
+
+//////////// Iterators & Comma initializers //////////////////
+
+template<typename T>
+struct CV_EXPORTS MatConstIterator_
+{
+    typedef T value_type;
+    typedef int difference_type;
+
+    MatConstIterator_();
+    MatConstIterator_(const Mat_<T>* _m);
+    MatConstIterator_(const Mat_<T>* _m, int _row, int _col=0);
+    MatConstIterator_(const Mat_<T>* _m, Point _pt);
+    MatConstIterator_(const MatConstIterator_& it);
+
+    MatConstIterator_& operator = (const MatConstIterator_& it );
+    T operator *() const;
+    T operator [](int i) const;
+    
+    MatConstIterator_& operator += (int ofs);
+    MatConstIterator_& operator -= (int ofs);
+    MatConstIterator_& operator --();
+    MatConstIterator_ operator --(int);
+    MatConstIterator_& operator ++();
+    MatConstIterator_ operator ++(int);
+    Point pos() const;
+
+    const Mat_<T>* m;
+    T* ptr;
+    T* sliceEnd;
+};
+
 
-    static CvTypeInfo* first;
-    static CvTypeInfo* last;
+template<typename T>
+struct CV_EXPORTS MatIterator_ : MatConstIterator_<T>
+{
+    typedef T* pointer;
+    typedef T& reference;
+    typedef std::random_access_iterator_tag iterator_category;
+
+    MatIterator_();
+    MatIterator_(Mat_<T>* _m);
+    MatIterator_(Mat_<T>* _m, int _row, int _col=0);
+    MatIterator_(const Mat_<T>* _m, Point _pt);
+    MatIterator_(const MatIterator_& it);
+    MatIterator_& operator = (const MatIterator_<T>& it );
+
+    T& operator *() const;
+    T& operator [](int i) const;
+
+    MatIterator_& operator += (int ofs);
+    MatIterator_& operator -= (int ofs);
+    MatIterator_& operator --();
+    MatIterator_ operator --(int);
+    MatIterator_& operator ++();
+    MatIterator_ operator ++(int);
+};
+
+template<typename T> struct CV_EXPORTS MatOp_Iter_;
+
+template<typename T> struct CV_EXPORTS MatCommaInitializer_ :
+    MatExpr_<MatExpr_Op1_<MatIterator_<T>, Mat_<T>, MatOp_Iter_<T> >, Mat_<T> >
+{
+    MatCommaInitializer_(Mat_<T>* _m);
+    template<typename T2> MatCommaInitializer_<T>& operator , (T2 v);
+    operator Mat_<T>() const;
+    Mat_<T> operator *() const;
+    void assignTo(Mat& m, int type=-1) const;
 };
 
+template<typename T> struct VectorCommaInitializer_
+{
+    VectorCommaInitializer_(Vector<T>* _vec);
+    template<typename T2> VectorCommaInitializer_<T>& operator , (T2 val);
+    operator Vector<T>() const;
+    Vector<T> operator *() const;
+
+    Vector<T>* vec;
+    int idx;
+};
+
+template<typename T, size_t fixed_size=CV_MAX_LOCAL_SIZE> struct CV_EXPORTS AutoBuffer
+{
+    typedef T value_type;
+
+    AutoBuffer();
+    AutoBuffer(size_t _size);
+    ~AutoBuffer();
+
+    void allocate(size_t _size);
+    void deallocate();
+    operator T* ();
+    operator const T* () const;
+
+    T* ptr;
+    size_t size;
+    T buf[fixed_size];
+};
+
+//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
+
+struct CV_EXPORTS FileNode;
+
+struct CV_EXPORTS FileStorage
+{
+    enum { READ=0, WRITE=1, APPEND=2 };
+    enum { UNDEFINED=0, VALUE_EXPECTED=1, NAME_EXPECTED=2, INSIDE_MAP=4 };
+    FileStorage();
+    FileStorage(const String& filename, int flags);
+    FileStorage(CvFileStorage* fs);
+    virtual ~FileStorage();
+
+    virtual bool open(const String& filename, int flags);
+    virtual bool isOpened() const;
+    virtual void release();
+
+    FileNode root(int streamidx=0) const;
+    FileNode operator[](const String& nodename) const;
+    FileNode operator[](const char* nodename) const;
+
+    CvFileStorage* operator *() { return fs.obj; }
+    const CvFileStorage* operator *() const { return fs.obj; }
+    void writeRaw( const String& fmt, const Vector<uchar>& vec );
+    void writeObj( const String& name, const void* obj );
+
+    ObjPtr<CvFileStorage> fs;
+    String elname;
+    Vector<char> structs;
+    int state;
+};
+
+struct CV_EXPORTS FileNodeIterator;
+
+struct CV_EXPORTS FileNode
+{
+    enum { NONE=0, INT=1, REAL=2, FLOAT=REAL, STR=3, STRING=STR, REF=4, SEQ=5, MAP=6, TYPE_MASK=7,
+        FLOW=8, USER=16, EMPTY=32, NAMED=64 };
+    FileNode();
+    FileNode(const CvFileStorage* fs, const CvFileNode* node);
+    FileNode(const FileNode& node);
+    FileNode operator[](const String& nodename) const;
+    FileNode operator[](const char* nodename) const;
+    FileNode operator[](int i) const;
+    int type() const;
+    int rawDataSize(const String& fmt) const;
+    bool isNone() const;
+    bool isSeq() const;
+    bool isMap() const;
+    bool isInt() const;
+    bool isReal() const;
+    bool isString() const;
+    bool isNamed() const;
+    String name() const;
+    size_t count() const;
+    operator int() const;
+    operator float() const;
+    operator double() const;
+    operator String() const;
+
+    FileNodeIterator begin() const;
+    FileNodeIterator end() const;
+
+    void readRaw( const String& fmt, Vector<uchar>& vec ) const;
+    void* readObj() const;
+
+    // do not use wrapper pointer classes for better efficiency
+    const CvFileStorage* fs;
+    const CvFileNode* node;
+};
+
+struct CV_EXPORTS FileNodeIterator
+{
+    FileNodeIterator();
+    FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
+    FileNodeIterator(const FileNodeIterator& it);
+    FileNode operator *() const;
+    FileNode operator ->() const;
+
+    FileNodeIterator& operator ++();
+    FileNodeIterator operator ++(int);
+    FileNodeIterator& operator --();
+    FileNodeIterator operator --(int);
+    FileNodeIterator& operator += (int);
+    FileNodeIterator& operator -= (int);
+
+    FileNodeIterator& readRaw( const String& fmt, Vector<uchar>& vec,
+                               size_t maxCount=(size_t)INT_MAX );
+
+    const CvFileStorage* fs;
+    const CvFileNode* container;
+    CvSeqReader reader;
+    size_t remaining;
+};
+
+}
+
+#endif // __cplusplus
+
+#include "cxoperations.hpp"
+
 #endif /*_CXCORE_HPP_*/
index de4011a956d60170c8cf9defaaf45e4dd0ed2316..c896f6d28dec04b7f42aa303eac2f7927083ba26 100644 (file)
@@ -100,6 +100,7 @@ typedef int CVStatus;
 #define CV_StsParseError             -212 /* invalid syntax/structure of the parsed file */
 #define CV_StsNotImplemented         -213 /* the requested function/feature is not implemented */
 #define CV_StsBadMemBlock            -214 /* an allocated block has been corrupted */
+#define CV_StsAssert                 -215 /* assertion failed */
 
 /********************************* Error handling Macros ********************************/
 
index bf2baf1788de9a4f7ce11827bd3ec44da9cc9469..be1f36fa1b862ae581aa83f11554be83f5ae279c 100644 (file)
-/*M///////////////////////////////////////////////////////////////////////////////////////
-//
-//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-//  By downloading, copying, installing or using the software you agree to this license.
-//  If you do not agree to this license, do not download, install,
-//  copy or use the software.
-//
-//
-//                        Intel License Agreement
-//                For Open Source Computer Vision Library
-//
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-//   * Redistribution's of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//
-//   * Redistribution's in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//
-//   * The name of Intel Corporation may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
-
-/* The header is mostly for internal use and it is likely to change.
-   It contains some macro definitions that are used in cxcore, cv, cvaux
-   and, probably, other libraries. If you need some of this functionality,
-   the safe way is to copy it into your code and rename the macros.
-*/
-#ifndef _CXCORE_MISC_H_
-#define _CXCORE_MISC_H_
-
-#ifdef HAVE_CONFIG_H
-    #include "cvconfig.h"
-#endif
-
-#include <limits.h>
-#ifdef _OPENMP
-#include "omp.h"
-#endif
-
-/****************************************************************************************\
-*                              Compile-time tuning parameters                            *
-\****************************************************************************************/
-
-/* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */
-#define  CV_MAX_INLINE_MAT_OP_SIZE  10
-
-/* maximal linear size of matrix to allocate it on stack. */
-#define  CV_MAX_LOCAL_MAT_SIZE  32
-
-/* maximal size of local memory storage */
-#define  CV_MAX_LOCAL_SIZE  \
-    (CV_MAX_LOCAL_MAT_SIZE*CV_MAX_LOCAL_MAT_SIZE*(int)sizeof(double))
-
-/* default image row align (in bytes) */
-#define  CV_DEFAULT_IMAGE_ROW_ALIGN  4
-
-/* matrices are continuous by default */
-#define  CV_DEFAULT_MAT_ROW_ALIGN  1
-
-/* maximum size of dynamic memory buffer.
-   cvAlloc reports an error if a larger block is requested. */
-#define  CV_MAX_ALLOC_SIZE    (((size_t)1 << (sizeof(size_t)*8-2)))
-
-/* the alignment of all the allocated buffers */
-#define  CV_MALLOC_ALIGN    32
-
-/* default alignment for dynamic data strucutures, resided in storages. */
-#define  CV_STRUCT_ALIGN    ((int)sizeof(double))
-
-/* default storage block size */
-#define  CV_STORAGE_BLOCK_SIZE   ((1<<16) - 128)
-
-/* default memory block for sparse array elements */
-#define  CV_SPARSE_MAT_BLOCK    (1<<12)
-
-/* initial hash table size */
-#define  CV_SPARSE_HASH_SIZE0    (1<<10)
-
-/* maximal average node_count/hash_size ratio beyond which hash table is resized */
-#define  CV_SPARSE_HASH_RATIO    3
-
-/* max length of strings */
-#define  CV_MAX_STRLEN  1024
-
-/* maximum possible number of threads in parallel implementations */
-#ifdef _OPENMP
-#define CV_MAX_THREADS 128
-#else
-#define CV_MAX_THREADS 1
-#endif
-
-#if 0 /*def  CV_CHECK_FOR_NANS*/
-    #define CV_CHECK_NANS( arr ) cvCheckArray((arr))
-#else
-    #define CV_CHECK_NANS( arr )
-#endif
-
-/****************************************************************************************\
-*                                  Common declarations                                   *
-\****************************************************************************************/
-
-/* get alloca declaration */
-#ifdef __GNUC__
-    #undef alloca
-    #define alloca __builtin_alloca
-#elif defined WIN32 || defined WIN64 || defined WINCE
-    #if defined _MSC_VER || defined __BORLANDC__
-        #include <malloc.h>
-    #endif
-#elif defined HAVE_ALLOCA_H
-    #include <alloca.h>
-#elif defined HAVE_ALLOCA
-    #include <stdlib.h>
-#else
-    #error "No alloca!"
-#endif
-
-/* ! DO NOT make it an inline function */
-#define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN )
-
-#if defined _MSC_VER || defined __BORLANDC__
-    #define CV_BIG_INT(n)   n##I64
-    #define CV_BIG_UINT(n)  n##UI64
-#else
-    #define CV_BIG_INT(n)   n##LL
-    #define CV_BIG_UINT(n)  n##ULL
-#endif
-
-#define CV_IMPL CV_EXTERN_C
-
-#define CV_DBG_BREAK() { volatile int* crashMe = 0; *crashMe = 0; }
-
-/* default step, set in case of continuous data
-   to work around checks for valid step in some ipp functions */
-#define  CV_STUB_STEP     (1 << 30)
-
-#define  CV_SIZEOF_FLOAT ((int)sizeof(float))
-#define  CV_SIZEOF_SHORT ((int)sizeof(short))
-
-#define  CV_ORIGIN_TL  0
-#define  CV_ORIGIN_BL  1
-
-/* IEEE754 constants and macros */
-#define  CV_POS_INF       0x7f800000
-#define  CV_NEG_INF       0x807fffff /* CV_TOGGLE_FLT(0xff800000) */
-#define  CV_1F            0x3f800000
-#define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))
-#define  CV_TOGGLE_DBL(x) \
-    ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))
-
-#define  CV_NOP(a)      (a)
-#define  CV_ADD(a, b)   ((a) + (b))
-#define  CV_SUB(a, b)   ((a) - (b))
-#define  CV_MUL(a, b)   ((a) * (b))
-#define  CV_AND(a, b)   ((a) & (b))
-#define  CV_OR(a, b)    ((a) | (b))
-#define  CV_XOR(a, b)   ((a) ^ (b))
-#define  CV_ANDN(a, b)  (~(a) & (b))
-#define  CV_ORN(a, b)   (~(a) | (b))
-#define  CV_SQR(a)      ((a) * (a))
-
-#define  CV_LT(a, b)    ((a) < (b))
-#define  CV_LE(a, b)    ((a) <= (b))
-#define  CV_EQ(a, b)    ((a) == (b))
-#define  CV_NE(a, b)    ((a) != (b))
-#define  CV_GT(a, b)    ((a) > (b))
-#define  CV_GE(a, b)    ((a) >= (b))
-
-#define  CV_NONZERO(a)      ((a) != 0)
-#define  CV_NONZERO_FLT(a)  (((a)+(a)) != 0)
-
-/* general-purpose saturation macros */
-#define  CV_CAST_8U(t)  (uchar)(!((t) & ~255) ? (t) : (t) > 0 ? 255 : 0)
-#define  CV_CAST_8S(t)  (schar)(!(((t)+128) & ~255) ? (t) : (t) > 0 ? 127 : -128)
-#define  CV_CAST_16U(t) (ushort)(!((t) & ~65535) ? (t) : (t) > 0 ? 65535 : 0)
-#define  CV_CAST_16S(t) (short)(!(((t)+32768) & ~65535) ? (t) : (t) > 0 ? 32767 : -32768)
-#define  CV_CAST_32S(t) (int)(t)
-#define  CV_CAST_64S(t) (int64)(t)
-#define  CV_CAST_32F(t) (float)(t)
-#define  CV_CAST_64F(t) (double)(t)
-
-#define  CV_PASTE2(a,b) a##b
-#define  CV_PASTE(a,b)  CV_PASTE2(a,b)
-
-#define  CV_EMPTY
-#define  CV_MAKE_STR(a) #a
-
-#define  CV_DEFINE_MASK         \
-    float maskTab[2]; maskTab[0] = 0.f; maskTab[1] = 1.f;
-#define  CV_ANDMASK( m, x )     ((x) & (((m) == 0) - 1))
-
-/* (x) * ((m) == 1 ? 1.f : (m) == 0 ? 0.f : <ERR> */
-#define  CV_MULMASK( m, x )       (maskTab[(m) != 0]*(x))
-
-/* (x) * ((m) == -1 ? 1.f : (m) == 0 ? 0.f : <ERR> */
-#define  CV_MULMASK1( m, x )      (maskTab[(m)+1]*(x))
-
-#define  CV_ZERO_OBJ(x)  memset((x), 0, sizeof(*(x)))
-
-#define  CV_DIM(static_array) ((int)(sizeof(static_array)/sizeof((static_array)[0])))
-
-#define  CV_UN_ENTRY_C1(worktype)           \
-    worktype s0 = scalar[0]
-
-#define  CV_UN_ENTRY_C2(worktype)           \
-    worktype s0 = scalar[0], s1 = scalar[1]
-
-#define  CV_UN_ENTRY_C3(worktype)           \
-    worktype s0 = scalar[0], s1 = scalar[1], s2 = scalar[2]
-
-#define  CV_UN_ENTRY_C4(worktype)           \
-    worktype s0 = scalar[0], s1 = scalar[1], s2 = scalar[2], s3 = scalar[3]
-
-#define  cvUnsupportedFormat "Unsupported format"
-
-CV_INLINE void* cvAlignPtr( const void* ptr, int align=32 )
-{
-    assert( (align & (align-1)) == 0 );
-    return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );
-}
-
-CV_INLINE int cvAlign( int size, int align )
-{
-    assert( (align & (align-1)) == 0 && size < INT_MAX );
-    return (size + align - 1) & -align;
-}
-
-CV_INLINE  CvSize  cvGetMatSize( const CvMat* mat )
-{
-    CvSize size = { mat->width, mat->height };
-    return size;
-}
-
-#define  CV_DESCALE(x,n)     (((x) + (1 << ((n)-1))) >> (n))
-#define  CV_FLT_TO_FIX(x,n)  cvRound((x)*(1<<(n)))
-
-#if 0
-/* This is a small engine for performing fast division of multiple numbers
-   by the same constant. Most compilers do it too if they know the divisor value
-   at compile-time. The algorithm was taken from Agner Fog's optimization guide
-   at http://www.agner.org/assem */
-typedef struct CvFastDiv
-{
-    unsigned delta, scale, divisor;
-}
-CvFastDiv;
-
-#define CV_FAST_DIV_SHIFT 32
-
-CV_INLINE CvFastDiv cvFastDiv( int divisor )
-{
-    CvFastDiv fastdiv;
-
-    assert( divisor >= 1 );
-    uint64 temp = ((uint64)1 << CV_FAST_DIV_SHIFT)/divisor;
-
-    fastdiv.divisor = divisor;
-    fastdiv.delta = (unsigned)(((temp & 1) ^ 1) + divisor - 1);
-    fastdiv.scale = (unsigned)((temp + 1) >> 1);
-
-    return fastdiv;
-}
-
-#define CV_FAST_DIV( x, fastdiv )  \
-    ((int)(((int64)((x)*2 + (int)(fastdiv).delta))*(int)(fastdiv).scale>>CV_FAST_DIV_SHIFT))
-
-#define CV_FAST_UDIV( x, fastdiv )  \
-    ((int)(((uint64)((x)*2 + (fastdiv).delta))*(fastdiv).scale>>CV_FAST_DIV_SHIFT))
-#endif
-
-#define CV_MEMCPY_CHAR( dst, src, len )                                             \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    char* _icv_memcpy_dst_ = (char*)(dst);                                          \
-    const char* _icv_memcpy_src_ = (const char*)(src);                              \
-                                                                                    \
-    for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];        \
-}
-
-
-#define CV_MEMCPY_INT( dst, src, len )                                              \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    int* _icv_memcpy_dst_ = (int*)(dst);                                            \
-    const int* _icv_memcpy_src_ = (const int*)(src);                                \
-    assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 &&                      \
-            ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                      \
-                                                                                    \
-    for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)          \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];        \
-}
-
-
-#define CV_MEMCPY_AUTO( dst, src, len )                                             \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    char* _icv_memcpy_dst_ = (char*)(dst);                                          \
-    const char* _icv_memcpy_src_ = (const char*)(src);                              \
-    if( (_icv_memcpy_len_ & (sizeof(int)-1)) == 0 )                                 \
-    {                                                                               \
-        assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 &&                  \
-                ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                  \
-        for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_;                 \
-            _icv_memcpy_i_+=sizeof(int) )                                           \
-        {                                                                           \
-            *(int*)(_icv_memcpy_dst_+_icv_memcpy_i_) =                              \
-            *(const int*)(_icv_memcpy_src_+_icv_memcpy_i_);                         \
-        }                                                                           \
-    }                                                                               \
-    else                                                                            \
-    {                                                                               \
-        for(_icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++)\
-            _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];    \
-    }                                                                               \
-}
-
-
-#define CV_ZERO_CHAR( dst, len )                                                    \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    char* _icv_memcpy_dst_ = (char*)(dst);                                          \
-                                                                                    \
-    for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = '\0';                                    \
-}
-
-
-#define CV_ZERO_INT( dst, len )                                                     \
-{                                                                                   \
-    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \
-    int* _icv_memcpy_dst_ = (int*)(dst);                                            \
-    assert( ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                      \
-                                                                                    \
-    for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)          \
-        _icv_memcpy_dst_[_icv_memcpy_i_] = 0;                                       \
-}
-
-
-/****************************************************************************************\
-
-  Generic implementation of QuickSort algorithm.
-  ----------------------------------------------
-  Using this macro user can declare customized sort function that can be much faster
-  than built-in qsort function because of lower overhead on elements
-  comparison and exchange. The macro takes less_than (or LT) argument - a macro or function
-  that takes 2 arguments returns non-zero if the first argument should be before the second
-  one in the sorted sequence and zero otherwise.
-
-  Example:
-
-    Suppose that the task is to sort points by ascending of y coordinates and if
-    y's are equal x's should ascend.
-
-    The code is:
-    ------------------------------------------------------------------------------
-           #define cmp_pts( pt1, pt2 ) \
-               ((pt1).y < (pt2).y || ((pt1).y < (pt2).y && (pt1).x < (pt2).x))
-
-           [static] CV_IMPLEMENT_QSORT( icvSortPoints, CvPoint, cmp_pts )
-    ------------------------------------------------------------------------------
-
-    After that the function "void icvSortPoints( CvPoint* array, size_t total, int aux );"
-    is available to user.
-
-  aux is an additional parameter, which can be used when comparing elements.
-  The current implementation was derived from *BSD system qsort():
-
-    * Copyright (c) 1992, 1993
-    *  The Regents of the University of California.  All rights reserved.
-    *
-    * Redistribution and use in source and binary forms, with or without
-    * modification, are permitted provided that the following conditions
-    * are met:
-    * 1. Redistributions of source code must retain the above copyright
-    *    notice, this list of conditions and the following disclaimer.
-    * 2. Redistributions in binary form must reproduce the above copyright
-    *    notice, this list of conditions and the following disclaimer in the
-    *    documentation and/or other materials provided with the distribution.
-    * 3. All advertising materials mentioning features or use of this software
-    *    must display the following acknowledgement:
-    *  This product includes software developed by the University of
-    *  California, Berkeley and its contributors.
-    * 4. Neither the name of the University nor the names of its contributors
-    *    may be used to endorse or promote products derived from this software
-    *    without specific prior written permission.
-    *
-    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    * SUCH DAMAGE.
-
-\****************************************************************************************/
-
-#define CV_IMPLEMENT_QSORT_EX( func_name, T, LT, user_data_type )                   \
-void func_name( T *array, size_t total, user_data_type aux )                        \
-{                                                                                   \
-    int isort_thresh = 7;                                                           \
-    T t;                                                                            \
-    int sp = 0;                                                                     \
-                                                                                    \
-    struct                                                                          \
-    {                                                                               \
-        T *lb;                                                                      \
-        T *ub;                                                                      \
-    }                                                                               \
-    stack[48];                                                                      \
-                                                                                    \
-    aux = aux;                                                                      \
-                                                                                    \
-    if( total <= 1 )                                                                \
-        return;                                                                     \
-                                                                                    \
-    stack[0].lb = array;                                                            \
-    stack[0].ub = array + (total - 1);                                              \
-                                                                                    \
-    while( sp >= 0 )                                                                \
-    {                                                                               \
-        T* left = stack[sp].lb;                                                     \
-        T* right = stack[sp--].ub;                                                  \
-                                                                                    \
-        for(;;)                                                                     \
-        {                                                                           \
-            int i, n = (int)(right - left) + 1, m;                                  \
-            T* ptr;                                                                 \
-            T* ptr2;                                                                \
-                                                                                    \
-            if( n <= isort_thresh )                                                 \
-            {                                                                       \
-            insert_sort:                                                            \
-                for( ptr = left + 1; ptr <= right; ptr++ )                          \
-                {                                                                   \
-                    for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)   \
-                        CV_SWAP( ptr2[0], ptr2[-1], t );                            \
-                }                                                                   \
-                break;                                                              \
-            }                                                                       \
-            else                                                                    \
-            {                                                                       \
-                T* left0;                                                           \
-                T* left1;                                                           \
-                T* right0;                                                          \
-                T* right1;                                                          \
-                T* pivot;                                                           \
-                T* a;                                                               \
-                T* b;                                                               \
-                T* c;                                                               \
-                int swap_cnt = 0;                                                   \
-                                                                                    \
-                left0 = left;                                                       \
-                right0 = right;                                                     \
-                pivot = left + (n/2);                                               \
-                                                                                    \
-                if( n > 40 )                                                        \
-                {                                                                   \
-                    int d = n / 8;                                                  \
-                    a = left, b = left + d, c = left + 2*d;                         \
-                    left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))     \
-                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \
-                                                                                    \
-                    a = pivot - d, b = pivot, c = pivot + d;                        \
-                    pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))    \
-                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \
-                                                                                    \
-                    a = right - 2*d, b = right - d, c = right;                      \
-                    right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))    \
-                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \
-                }                                                                   \
-                                                                                    \
-                a = left, b = pivot, c = right;                                     \
-                pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))        \
-                                   : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));       \
-                if( pivot != left0 )                                                \
-                {                                                                   \
-                    CV_SWAP( *pivot, *left0, t );                                   \
-                    pivot = left0;                                                  \
-                }                                                                   \
-                left = left1 = left0 + 1;                                           \
-                right = right1 = right0;                                            \
-                                                                                    \
-                for(;;)                                                             \
-                {                                                                   \
-                    while( left <= right && !LT(*pivot, *left) )                    \
-                    {                                                               \
-                        if( !LT(*left, *pivot) )                                    \
-                        {                                                           \
-                            if( left > left1 )                                      \
-                                CV_SWAP( *left1, *left, t );                        \
-                            swap_cnt = 1;                                           \
-                            left1++;                                                \
-                        }                                                           \
-                        left++;                                                     \
-                    }                                                               \
-                                                                                    \
-                    while( left <= right && !LT(*right, *pivot) )                   \
-                    {                                                               \
-                        if( !LT(*pivot, *right) )                                   \
-                        {                                                           \
-                            if( right < right1 )                                    \
-                                CV_SWAP( *right1, *right, t );                      \
-                            swap_cnt = 1;                                           \
-                            right1--;                                               \
-                        }                                                           \
-                        right--;                                                    \
-                    }                                                               \
-                                                                                    \
-                    if( left > right )                                              \
-                        break;                                                      \
-                    CV_SWAP( *left, *right, t );                                    \
-                    swap_cnt = 1;                                                   \
-                    left++;                                                         \
-                    right--;                                                        \
-                }                                                                   \
-                                                                                    \
-                if( swap_cnt == 0 )                                                 \
-                {                                                                   \
-                    left = left0, right = right0;                                   \
-                    goto insert_sort;                                               \
-                }                                                                   \
-                                                                                    \
-                n = MIN( (int)(left1 - left0), (int)(left - left1) );               \
-                for( i = 0; i < n; i++ )                                            \
-                    CV_SWAP( left0[i], left[i-n], t );                              \
-                                                                                    \
-                n = MIN( (int)(right0 - right1), (int)(right1 - right) );           \
-                for( i = 0; i < n; i++ )                                            \
-                    CV_SWAP( left[i], right0[i-n+1], t );                           \
-                n = (int)(left - left1);                                            \
-                m = (int)(right1 - right);                                          \
-                if( n > 1 )                                                         \
-                {                                                                   \
-                    if( m > 1 )                                                     \
-                    {                                                               \
-                        if( n > m )                                                 \
-                        {                                                           \
-                            stack[++sp].lb = left0;                                 \
-                            stack[sp].ub = left0 + n - 1;                           \
-                            left = right0 - m + 1, right = right0;                  \
-                        }                                                           \
-                        else                                                        \
-                        {                                                           \
-                            stack[++sp].lb = right0 - m + 1;                        \
-                            stack[sp].ub = right0;                                  \
-                            left = left0, right = left0 + n - 1;                    \
-                        }                                                           \
-                    }                                                               \
-                    else                                                            \
-                        left = left0, right = left0 + n - 1;                        \
-                }                                                                   \
-                else if( m > 1 )                                                    \
-                    left = right0 - m + 1, right = right0;                          \
-                else                                                                \
-                    break;                                                          \
-            }                                                                       \
-        }                                                                           \
-    }                                                                               \
-}
-
-#define CV_IMPLEMENT_QSORT( func_name, T, cmp )  \
-    CV_IMPLEMENT_QSORT_EX( func_name, T, cmp, int )
-
-/****************************************************************************************\
-*                     Structures and macros for integration with IPP                     *
-\****************************************************************************************/
-
-/* IPP-compatible return codes */
-typedef enum CvStatus
-{
-    CV_BADMEMBLOCK_ERR          = -113,
-    CV_INPLACE_NOT_SUPPORTED_ERR= -112,
-    CV_UNMATCHED_ROI_ERR        = -111,
-    CV_NOTFOUND_ERR             = -110,
-    CV_BADCONVERGENCE_ERR       = -109,
-
-    CV_BADDEPTH_ERR             = -107,
-    CV_BADROI_ERR               = -106,
-    CV_BADHEADER_ERR            = -105,
-    CV_UNMATCHED_FORMATS_ERR    = -104,
-    CV_UNSUPPORTED_COI_ERR      = -103,
-    CV_UNSUPPORTED_CHANNELS_ERR = -102,
-    CV_UNSUPPORTED_DEPTH_ERR    = -101,
-    CV_UNSUPPORTED_FORMAT_ERR   = -100,
-
-    CV_BADARG_ERR      = -49,  //ipp comp
-    CV_NOTDEFINED_ERR  = -48,  //ipp comp
-
-    CV_BADCHANNELS_ERR = -47,  //ipp comp
-    CV_BADRANGE_ERR    = -44,  //ipp comp
-    CV_BADSTEP_ERR     = -29,  //ipp comp
-
-    CV_BADFLAG_ERR     =  -12,
-    CV_DIV_BY_ZERO_ERR =  -11, //ipp comp
-    CV_BADCOEF_ERR     =  -10,
-
-    CV_BADFACTOR_ERR   =  -7,
-    CV_BADPOINT_ERR    =  -6,
-    CV_BADSCALE_ERR    =  -4,
-    CV_OUTOFMEM_ERR    =  -3,
-    CV_NULLPTR_ERR     =  -2,
-    CV_BADSIZE_ERR     =  -1,
-    CV_NO_ERR          =   0,
-    CV_OK              =   CV_NO_ERR
-}
-CvStatus;
-
-#define CV_ERROR_FROM_STATUS( result )                \
-    CV_ERROR( cvErrorFromIppStatus( result ), "OpenCV function failed" )
-
-#define IPPI_CALL( Func )                                              \
-{                                                                      \
-      CvStatus  ippi_call_result;                                      \
-      ippi_call_result = Func;                                         \
-                                                                       \
-      if( ippi_call_result < 0 )                                       \
-            CV_ERROR_FROM_STATUS( (ippi_call_result));                 \
-}
-
-#define CV_PLUGIN_NONE      0
-#define CV_PLUGIN_OPTCV     1 /* custom "emerged" ippopencv library */
-#define CV_PLUGIN_IPPCV     2 /* IPP: computer vision */
-#define CV_PLUGIN_IPPI      3 /* IPP: image processing */
-#define CV_PLUGIN_IPPS      4 /* IPP: signal processing */
-#define CV_PLUGIN_IPPVM     5 /* IPP: vector math functions */
-#define CV_PLUGIN_IPPCC     6 /* IPP: color space conversion */
-#define CV_PLUGIN_MKL       8 /* Intel Math Kernel Library */
-
-#define CV_PLUGIN_MAX      16
-
-#define CV_PLUGINS1(lib1) ((lib1)&15)
-#define CV_PLUGINS2(lib1,lib2) (((lib1)&15)|(((lib2)&15)<<4))
-#define CV_PLUGINS3(lib1,lib2,lib3) (((lib1)&15)|(((lib2)&15)<<4)|(((lib2)&15)<<8))
-
-#define CV_NOTHROW throw()
-
-#ifndef IPCVAPI
-#define IPCVAPI(type,declspec,name,args)                        \
-    /* function pointer */                                      \
-    typedef type (declspec* name##_t) args;                     \
-    extern name##_t name##_p;                                   \
-    type declspec name args;
-#endif
-
-#define IPCVAPI_EX(type,name,ipp_name,ipp_search_modules,args)  \
-    IPCVAPI(type,CV_STDCALL,name,args)
-
-#define IPCVAPI_C_EX(type,name,ipp_name,ipp_search_modules,args)\
-    IPCVAPI(type,CV_CDECL,name,args)
-
-#ifndef IPCVAPI_IMPL
-#define IPCVAPI_IMPL(type,name,args,arg_names)                  \
-    static type CV_STDCALL name##_f args;                       \
-    name##_t name##_p = name##_f;                               \
-    type CV_STDCALL name args { return name##_p arg_names; }    \
-    static type CV_STDCALL name##_f args
-#endif
-
-/* IPP types' enumeration */
-typedef enum CvDataType {
-    cv1u,
-    cv8u, cv8s,
-    cv16u, cv16s, cv16sc,
-    cv32u, cv32s, cv32sc,
-    cv32f, cv32fc,
-    cv64u, cv64s, cv64sc,
-    cv64f, cv64fc
-} CvDataType;
-
-typedef enum CvHintAlgorithm {
-    cvAlgHintNone,
-    cvAlgHintFast,
-    cvAlgHintAccurate
-} CvHintAlgorithm;
-
-typedef enum CvCmpOp {
-    cvCmpLess,
-    cvCmpLessEq,
-    cvCmpEq,
-    cvCmpGreaterEq,
-    cvCmpGreater
-} CvCmpOp;
-
-typedef struct CvFuncTable
-{
-    void*   fn_2d[CV_DEPTH_MAX];
-}
-CvFuncTable;
-
-typedef struct CvBigFuncTable
-{
-    void*   fn_2d[CV_DEPTH_MAX*CV_CN_MAX];
-}
-CvBigFuncTable;
-
-
-typedef struct CvBtFuncTable
-{
-    void*   fn_2d[33];
-}
-CvBtFuncTable;
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_1A)(void* arr, int step, CvSize size);
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_1A1P)(void* arr, int step, CvSize size, void* param);
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_1A1P1I)(void* arr, int step, CvSize size,
-                                               void* param, int flag);
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_1A1P)( void* arr, int step, CvSize size,
-                                                int cn, int coi, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_1A1P)( void* arr, int step, CvSize size,
-                                                int cn, int coi, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_1A2P)( void* arr, int step, CvSize size,
-                                              void* param1, void* param2 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_1A2P)( void* arr, int step,
-                                                CvSize size, int cn, int coi,
-                                                void* param1, void* param2 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_1A4P)( void* arr, int step, CvSize size,
-                                              void* param1, void* param2,
-                                              void* param3, void* param4 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_1A4P)( void* arr, int step,
-                                                CvSize size, int cn, int coi,
-                                                void* param1, void* param2,
-                                                void* param3, void* param4 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_2A)( void* arr0, int step0,
-                                            void* arr1, int step1, CvSize size );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_2A1P)( void* arr0, int step0,
-                                              void* arr1, int step1,
-                                              CvSize size, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_2A1P)( void* arr0, int step0,
-                                                void* arr1, int step1,
-                                                CvSize size, int cn,
-                                                int coi, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_2A1P)( void* arr0, int step0,
-                                                void* arr1, int step1,
-                                                CvSize size, int cn,
-                                                int coi, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_2A2P)( void* arr0, int step0,
-                                              void* arr1, int step1, CvSize size,
-                                              void* param1, void* param2 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_2A2P)( void* arr0, int step0,
-                                                void* arr1, int step1,
-                                                CvSize size, int cn, int coi,
-                                                void* param1, void* param2 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_2A1P1I)( void* arr0, int step0,
-                                                void* arr1, int step1, CvSize size,
-                                                void* param, int flag );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_2A4P)( void* arr0, int step0,
-                                              void* arr1, int step1, CvSize size,
-                                              void* param1, void* param2,
-                                              void* param3, void* param4 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_2A4P)( void* arr0, int step0,
-                                                void* arr1, int step1, CvSize size,
-                                                int cn, int coi,
-                                                void* param1, void* param2,
-                                                void* param3, void* param4 );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_3A)( void* arr0, int step0,
-                                            void* arr1, int step1,
-                                            void* arr2, int step2, CvSize size );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_3A1P)( void* arr0, int step0,
-                                              void* arr1, int step1,
-                                              void* arr2, int step2,
-                                              CvSize size, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_3A1I)( void* arr0, int step0,
-                                              void* arr1, int step1,
-                                              void* arr2, int step2,
-                                              CvSize size, int flag );
-
-typedef CvStatus (CV_STDCALL *CvFunc2DnC_3A1P)( void* arr0, int step0,
-                                                void* arr1, int step1,
-                                                void* arr2, int step2,
-                                                CvSize size, int cn,
-                                                int coi, void* param );
-
-typedef CvStatus (CV_STDCALL *CvFunc2D_4A)( void* arr0, int step0,
-                                            void* arr1, int step1,
-                                            void* arr2, int step2,
-                                            void* arr3, int step3,
-                                            CvSize size );
-
-typedef CvStatus (CV_STDCALL *CvFunc0D)( const void* src, void* dst, int param );
-
-#define CV_DEF_INIT_FUNC_TAB_2D( FUNCNAME, FLAG )                   \
-static void  icvInit##FUNCNAME##FLAG##Table( CvFuncTable* tab )     \
-{                                                                   \
-    assert( tab );                                                  \
-                                                                    \
-    tab->fn_2d[CV_8U]  = (void*)icv##FUNCNAME##_8u_##FLAG;          \
-    tab->fn_2d[CV_8S]  = (void*)icv##FUNCNAME##_8s_##FLAG;          \
-    tab->fn_2d[CV_16U] = (void*)icv##FUNCNAME##_16u_##FLAG;         \
-    tab->fn_2d[CV_16S] = (void*)icv##FUNCNAME##_16s_##FLAG;         \
-    tab->fn_2d[CV_32S] = (void*)icv##FUNCNAME##_32s_##FLAG;         \
-    tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_##FLAG;         \
-    tab->fn_2d[CV_64F] = (void*)icv##FUNCNAME##_64f_##FLAG;         \
-}
-
-
-#define CV_DEF_INIT_BIG_FUNC_TAB_2D( FUNCNAME, FLAG )               \
-static void  icvInit##FUNCNAME##FLAG##Table( CvBigFuncTable* tab )  \
-{                                                                   \
-    assert( tab );                                                  \
-                                                                    \
-    tab->fn_2d[CV_8UC1]  = (void*)icv##FUNCNAME##_8u_C1##FLAG;      \
-    tab->fn_2d[CV_8UC2]  = (void*)icv##FUNCNAME##_8u_C2##FLAG;      \
-    tab->fn_2d[CV_8UC3]  = (void*)icv##FUNCNAME##_8u_C3##FLAG;      \
-    tab->fn_2d[CV_8UC4]  = (void*)icv##FUNCNAME##_8u_C4##FLAG;      \
-                                                                    \
-    tab->fn_2d[CV_8SC1]  = (void*)icv##FUNCNAME##_8s_C1##FLAG;      \
-    tab->fn_2d[CV_8SC2]  = (void*)icv##FUNCNAME##_8s_C2##FLAG;      \
-    tab->fn_2d[CV_8SC3]  = (void*)icv##FUNCNAME##_8s_C3##FLAG;      \
-    tab->fn_2d[CV_8SC4]  = (void*)icv##FUNCNAME##_8s_C4##FLAG;      \
-                                                                    \
-    tab->fn_2d[CV_16UC1] = (void*)icv##FUNCNAME##_16u_C1##FLAG;     \
-    tab->fn_2d[CV_16UC2] = (void*)icv##FUNCNAME##_16u_C2##FLAG;     \
-    tab->fn_2d[CV_16UC3] = (void*)icv##FUNCNAME##_16u_C3##FLAG;     \
-    tab->fn_2d[CV_16UC4] = (void*)icv##FUNCNAME##_16u_C4##FLAG;     \
-                                                                    \
-    tab->fn_2d[CV_16SC1] = (void*)icv##FUNCNAME##_16s_C1##FLAG;     \
-    tab->fn_2d[CV_16SC2] = (void*)icv##FUNCNAME##_16s_C2##FLAG;     \
-    tab->fn_2d[CV_16SC3] = (void*)icv##FUNCNAME##_16s_C3##FLAG;     \
-    tab->fn_2d[CV_16SC4] = (void*)icv##FUNCNAME##_16s_C4##FLAG;     \
-                                                                    \
-    tab->fn_2d[CV_32SC1] = (void*)icv##FUNCNAME##_32s_C1##FLAG;     \
-    tab->fn_2d[CV_32SC2] = (void*)icv##FUNCNAME##_32s_C2##FLAG;     \
-    tab->fn_2d[CV_32SC3] = (void*)icv##FUNCNAME##_32s_C3##FLAG;     \
-    tab->fn_2d[CV_32SC4] = (void*)icv##FUNCNAME##_32s_C4##FLAG;     \
-                                                                    \
-    tab->fn_2d[CV_32FC1] = (void*)icv##FUNCNAME##_32f_C1##FLAG;     \
-    tab->fn_2d[CV_32FC2] = (void*)icv##FUNCNAME##_32f_C2##FLAG;     \
-    tab->fn_2d[CV_32FC3] = (void*)icv##FUNCNAME##_32f_C3##FLAG;     \
-    tab->fn_2d[CV_32FC4] = (void*)icv##FUNCNAME##_32f_C4##FLAG;     \
-                                                                    \
-    tab->fn_2d[CV_64FC1] = (void*)icv##FUNCNAME##_64f_C1##FLAG;     \
-    tab->fn_2d[CV_64FC2] = (void*)icv##FUNCNAME##_64f_C2##FLAG;     \
-    tab->fn_2d[CV_64FC3] = (void*)icv##FUNCNAME##_64f_C3##FLAG;     \
-    tab->fn_2d[CV_64FC4] = (void*)icv##FUNCNAME##_64f_C4##FLAG;     \
-}
-
-#define CV_DEF_INIT_FUNC_TAB_0D( FUNCNAME )                         \
-static void  icvInit##FUNCNAME##Table( CvFuncTable* tab )           \
-{                                                                   \
-    tab->fn_2d[CV_8U]  = (void*)icv##FUNCNAME##_8u;                 \
-    tab->fn_2d[CV_8S]  = (void*)icv##FUNCNAME##_8s;                 \
-    tab->fn_2d[CV_16U] = (void*)icv##FUNCNAME##_16u;                \
-    tab->fn_2d[CV_16S] = (void*)icv##FUNCNAME##_16s;                \
-    tab->fn_2d[CV_32S] = (void*)icv##FUNCNAME##_32s;                \
-    tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f;                \
-    tab->fn_2d[CV_64F] = (void*)icv##FUNCNAME##_64f;                \
-}
-
-#define CV_DEF_INIT_FUNC_TAB_1D  CV_DEF_INIT_FUNC_TAB_0D
-
-
-#define CV_DEF_INIT_PIXSIZE_TAB_2D( FUNCNAME, FLAG )                \
-static void icvInit##FUNCNAME##FLAG##Table( CvBtFuncTable* table )  \
-{                                                                   \
-    table->fn_2d[1]  = (void*)icv##FUNCNAME##_8u_C1##FLAG;          \
-    table->fn_2d[2]  = (void*)icv##FUNCNAME##_8u_C2##FLAG;          \
-    table->fn_2d[3]  = (void*)icv##FUNCNAME##_8u_C3##FLAG;          \
-    table->fn_2d[4]  = (void*)icv##FUNCNAME##_16u_C2##FLAG;         \
-    table->fn_2d[6]  = (void*)icv##FUNCNAME##_16u_C3##FLAG;         \
-    table->fn_2d[8]  = (void*)icv##FUNCNAME##_32s_C2##FLAG;         \
-    table->fn_2d[12] = (void*)icv##FUNCNAME##_32s_C3##FLAG;         \
-    table->fn_2d[16] = (void*)icv##FUNCNAME##_64s_C2##FLAG;         \
-    table->fn_2d[24] = (void*)icv##FUNCNAME##_64s_C3##FLAG;         \
-    table->fn_2d[32] = (void*)icv##FUNCNAME##_64s_C4##FLAG;         \
-}
-
-#define  CV_GET_FUNC_PTR( func, table_entry )  \
-    func = (table_entry);                      \
-                                               \
-    if( !func )                                \
-        CV_ERROR( CV_StsUnsupportedFormat, "" )
-
-
-#endif /*_CXCORE_MISC_H_*/
+/*M///////////////////////////////////////////////////////////////////////////////////////\r
+//\r
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
+//\r
+//  By downloading, copying, installing or using the software you agree to this license.\r
+//  If you do not agree to this license, do not download, install,\r
+//  copy or use the software.\r
+//\r
+//\r
+//                           License Agreement\r
+//                For Open Source Computer Vision Library\r
+//\r
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.\r
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.\r
+// Third party copyrights are property of their respective owners.\r
+//\r
+// Redistribution and use in source and binary forms, with or without modification,\r
+// are permitted provided that the following conditions are met:\r
+//\r
+//   * Redistribution's of source code must retain the above copyright notice,\r
+//     this list of conditions and the following disclaimer.\r
+//\r
+//   * Redistribution's in binary form must reproduce the above copyright notice,\r
+//     this list of conditions and the following disclaimer in the documentation\r
+//     and/or other materials provided with the distribution.\r
+//\r
+//   * The name of the copyright holders may not be used to endorse or promote products\r
+//     derived from this software without specific prior written permission.\r
+//\r
+// This software is provided by the copyright holders and contributors "as is" and\r
+// any express or implied warranties, including, but not limited to, the implied\r
+// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
+// In no event shall the Intel Corporation or contributors be liable for any direct,\r
+// indirect, incidental, special, exemplary, or consequential damages\r
+// (including, but not limited to, procurement of substitute goods or services;\r
+// loss of use, data, or profits; or business interruption) however caused\r
+// and on any theory of liability, whether in contract, strict liability,\r
+// or tort (including negligence or otherwise) arising in any way out of\r
+// the use of this software, even if advised of the possibility of such damage.\r
+//\r
+//M*/\r
+\r
+/* The header is mostly for internal use and it is likely to change.\r
+   It contains some macro definitions that are used in cxcore, cv, cvaux\r
+   and, probably, other libraries. If you need some of this functionality,\r
+   the safe way is to copy it into your code and rename the macros.\r
+*/\r
+#ifndef _CXCORE_MISC_H_\r
+#define _CXCORE_MISC_H_\r
+\r
+#ifdef HAVE_CONFIG_H\r
+    #include "cvconfig.h"\r
+#endif\r
+\r
+#include <limits.h>\r
+#ifdef _OPENMP\r
+#include "omp.h"\r
+#endif\r
+\r
+/****************************************************************************************\\r
+*                              Compile-time tuning parameters                            *\r
+\****************************************************************************************/\r
+\r
+/* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */\r
+#define  CV_MAX_INLINE_MAT_OP_SIZE  10\r
+\r
+/* maximal linear size of matrix to allocate it on stack. */\r
+#define  CV_MAX_LOCAL_MAT_SIZE  32\r
+\r
+/* maximal size of local memory storage */\r
+#define  CV_MAX_LOCAL_SIZE  \\r
+    (CV_MAX_LOCAL_MAT_SIZE*CV_MAX_LOCAL_MAT_SIZE*(int)sizeof(double))\r
+\r
+/* default image row align (in bytes) */\r
+#define  CV_DEFAULT_IMAGE_ROW_ALIGN  4\r
+\r
+/* matrices are continuous by default */\r
+#define  CV_DEFAULT_MAT_ROW_ALIGN  1\r
+\r
+/* maximum size of dynamic memory buffer.\r
+   cvAlloc reports an error if a larger block is requested. */\r
+#define  CV_MAX_ALLOC_SIZE    (((size_t)1 << (sizeof(size_t)*8-2)))\r
+\r
+/* the alignment of all the allocated buffers */\r
+#define  CV_MALLOC_ALIGN    32\r
+\r
+/* default alignment for dynamic data strucutures, resided in storages. */\r
+#define  CV_STRUCT_ALIGN    ((int)sizeof(double))\r
+\r
+/* default storage block size */\r
+#define  CV_STORAGE_BLOCK_SIZE   ((1<<16) - 128)\r
+\r
+/* default memory block for sparse array elements */\r
+#define  CV_SPARSE_MAT_BLOCK    (1<<12)\r
+\r
+/* initial hash table size */\r
+#define  CV_SPARSE_HASH_SIZE0    (1<<10)\r
+\r
+/* maximal average node_count/hash_size ratio beyond which hash table is resized */\r
+#define  CV_SPARSE_HASH_RATIO    3\r
+\r
+/* max length of strings */\r
+#define  CV_MAX_STRLEN  1024\r
+\r
+/* maximum possible number of threads in parallel implementations */\r
+#ifdef _OPENMP\r
+#define CV_MAX_THREADS 128\r
+#else\r
+#define CV_MAX_THREADS 1\r
+#endif\r
+\r
+#if 0 /*def  CV_CHECK_FOR_NANS*/\r
+    #define CV_CHECK_NANS( arr ) cvCheckArray((arr))\r
+#else\r
+    #define CV_CHECK_NANS( arr )\r
+#endif\r
+\r
+/****************************************************************************************\\r
+*                                  Common declarations                                   *\r
+\****************************************************************************************/\r
+\r
+/* get alloca declaration */\r
+#ifdef __GNUC__\r
+    #undef alloca\r
+    #define alloca __builtin_alloca\r
+#elif defined WIN32 || defined WIN64 || defined WINCE\r
+    #if defined _MSC_VER || defined __BORLANDC__\r
+        #include <malloc.h>\r
+    #endif\r
+#elif defined HAVE_ALLOCA_H\r
+    #include <alloca.h>\r
+#elif defined HAVE_ALLOCA\r
+    #include <stdlib.h>\r
+#else\r
+    #error "No alloca!"\r
+#endif\r
+\r
+/* ! DO NOT make it an inline function */\r
+#define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN )\r
+\r
+#if defined _MSC_VER || defined __BORLANDC__\r
+    #define CV_BIG_INT(n)   n##I64\r
+    #define CV_BIG_UINT(n)  n##UI64\r
+#else\r
+    #define CV_BIG_INT(n)   n##LL\r
+    #define CV_BIG_UINT(n)  n##ULL\r
+#endif\r
+\r
+#define CV_IMPL CV_EXTERN_C\r
+\r
+#define CV_DBG_BREAK() { volatile int* crashMe = 0; *crashMe = 0; }\r
+\r
+/* default step, set in case of continuous data\r
+   to work around checks for valid step in some ipp functions */\r
+#define  CV_STUB_STEP     (1 << 30)\r
+\r
+#define  CV_SIZEOF_FLOAT ((int)sizeof(float))\r
+#define  CV_SIZEOF_SHORT ((int)sizeof(short))\r
+\r
+#define  CV_ORIGIN_TL  0\r
+#define  CV_ORIGIN_BL  1\r
+\r
+/* IEEE754 constants and macros */\r
+#define  CV_POS_INF       0x7f800000\r
+#define  CV_NEG_INF       0x807fffff /* CV_TOGGLE_FLT(0xff800000) */\r
+#define  CV_1F            0x3f800000\r
+#define  CV_TOGGLE_FLT(x) ((x)^((int)(x) < 0 ? 0x7fffffff : 0))\r
+#define  CV_TOGGLE_DBL(x) \\r
+    ((x)^((int64)(x) < 0 ? CV_BIG_INT(0x7fffffffffffffff) : 0))\r
+\r
+#define  CV_NOP(a)      (a)\r
+#define  CV_ADD(a, b)   ((a) + (b))\r
+#define  CV_SUB(a, b)   ((a) - (b))\r
+#define  CV_MUL(a, b)   ((a) * (b))\r
+#define  CV_AND(a, b)   ((a) & (b))\r
+#define  CV_OR(a, b)    ((a) | (b))\r
+#define  CV_XOR(a, b)   ((a) ^ (b))\r
+#define  CV_ANDN(a, b)  (~(a) & (b))\r
+#define  CV_ORN(a, b)   (~(a) | (b))\r
+#define  CV_SQR(a)      ((a) * (a))\r
+\r
+#define  CV_LT(a, b)    ((a) < (b))\r
+#define  CV_LE(a, b)    ((a) <= (b))\r
+#define  CV_EQ(a, b)    ((a) == (b))\r
+#define  CV_NE(a, b)    ((a) != (b))\r
+#define  CV_GT(a, b)    ((a) > (b))\r
+#define  CV_GE(a, b)    ((a) >= (b))\r
+\r
+#define  CV_NONZERO(a)      ((a) != 0)\r
+#define  CV_NONZERO_FLT(a)  (((a)+(a)) != 0)\r
+\r
+/* general-purpose saturation macros */\r
+#define  CV_CAST_8U(t)  (uchar)(!((t) & ~255) ? (t) : (t) > 0 ? 255 : 0)\r
+#define  CV_CAST_8S(t)  (schar)(!(((t)+128) & ~255) ? (t) : (t) > 0 ? 127 : -128)\r
+#define  CV_CAST_16U(t) (ushort)(!((t) & ~65535) ? (t) : (t) > 0 ? 65535 : 0)\r
+#define  CV_CAST_16S(t) (short)(!(((t)+32768) & ~65535) ? (t) : (t) > 0 ? 32767 : -32768)\r
+#define  CV_CAST_32S(t) (int)(t)\r
+#define  CV_CAST_64S(t) (int64)(t)\r
+#define  CV_CAST_32F(t) (float)(t)\r
+#define  CV_CAST_64F(t) (double)(t)\r
+\r
+#define  CV_PASTE2(a,b) a##b\r
+#define  CV_PASTE(a,b)  CV_PASTE2(a,b)\r
+\r
+#define  CV_EMPTY\r
+#define  CV_MAKE_STR(a) #a\r
+\r
+#define  CV_DEFINE_MASK         \\r
+    float maskTab[2]; maskTab[0] = 0.f; maskTab[1] = 1.f;\r
+#define  CV_ANDMASK( m, x )     ((x) & (((m) == 0) - 1))\r
+\r
+/* (x) * ((m) == 1 ? 1.f : (m) == 0 ? 0.f : <ERR> */\r
+#define  CV_MULMASK( m, x )       (maskTab[(m) != 0]*(x))\r
+\r
+/* (x) * ((m) == -1 ? 1.f : (m) == 0 ? 0.f : <ERR> */\r
+#define  CV_MULMASK1( m, x )      (maskTab[(m)+1]*(x))\r
+\r
+#define  CV_ZERO_OBJ(x)  memset((x), 0, sizeof(*(x)))\r
+\r
+#define  CV_DIM(static_array) ((int)(sizeof(static_array)/sizeof((static_array)[0])))\r
+\r
+#define  CV_UN_ENTRY_C1(worktype)           \\r
+    worktype s0 = scalar[0]\r
+\r
+#define  CV_UN_ENTRY_C2(worktype)           \\r
+    worktype s0 = scalar[0], s1 = scalar[1]\r
+\r
+#define  CV_UN_ENTRY_C3(worktype)           \\r
+    worktype s0 = scalar[0], s1 = scalar[1], s2 = scalar[2]\r
+\r
+#define  CV_UN_ENTRY_C4(worktype)           \\r
+    worktype s0 = scalar[0], s1 = scalar[1], s2 = scalar[2], s3 = scalar[3]\r
+\r
+#define  cvUnsupportedFormat "Unsupported format"\r
+\r
+CV_INLINE void* cvAlignPtr( const void* ptr, int align CV_DEFAULT(32) )\r
+{\r
+    assert( (align & (align-1)) == 0 );\r
+    return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) );\r
+}\r
+\r
+CV_INLINE int cvAlign( int size, int align )\r
+{\r
+    assert( (align & (align-1)) == 0 && size < INT_MAX );\r
+    return (size + align - 1) & -align;\r
+}\r
+\r
+CV_INLINE  CvSize  cvGetMatSize( const CvMat* mat )\r
+{\r
+    CvSize size;\r
+    size.width = mat->cols;\r
+    size.height = mat->rows;\r
+    return size;\r
+}\r
+\r
+#define  CV_DESCALE(x,n)     (((x) + (1 << ((n)-1))) >> (n))\r
+#define  CV_FLT_TO_FIX(x,n)  cvRound((x)*(1<<(n)))\r
+\r
+#if 0\r
+/* This is a small engine for performing fast division of multiple numbers\r
+   by the same constant. Most compilers do it too if they know the divisor value\r
+   at compile-time. The algorithm was taken from Agner Fog's optimization guide\r
+   at http://www.agner.org/assem */\r
+typedef struct CvFastDiv\r
+{\r
+    unsigned delta, scale, divisor;\r
+}\r
+CvFastDiv;\r
+\r
+#define CV_FAST_DIV_SHIFT 32\r
+\r
+CV_INLINE CvFastDiv cvFastDiv( int divisor )\r
+{\r
+    CvFastDiv fastdiv;\r
+\r
+    assert( divisor >= 1 );\r
+    uint64 temp = ((uint64)1 << CV_FAST_DIV_SHIFT)/divisor;\r
+\r
+    fastdiv.divisor = divisor;\r
+    fastdiv.delta = (unsigned)(((temp & 1) ^ 1) + divisor - 1);\r
+    fastdiv.scale = (unsigned)((temp + 1) >> 1);\r
+\r
+    return fastdiv;\r
+}\r
+\r
+#define CV_FAST_DIV( x, fastdiv )  \\r
+    ((int)(((int64)((x)*2 + (int)(fastdiv).delta))*(int)(fastdiv).scale>>CV_FAST_DIV_SHIFT))\r
+\r
+#define CV_FAST_UDIV( x, fastdiv )  \\r
+    ((int)(((uint64)((x)*2 + (fastdiv).delta))*(fastdiv).scale>>CV_FAST_DIV_SHIFT))\r
+#endif\r
+\r
+#define CV_MEMCPY_CHAR( dst, src, len )                                             \\r
+{                                                                                   \\r
+    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \\r
+    char* _icv_memcpy_dst_ = (char*)(dst);                                          \\r
+    const char* _icv_memcpy_src_ = (const char*)(src);                              \\r
+                                                                                    \\r
+    for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \\r
+        _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];        \\r
+}\r
+\r
+\r
+#define CV_MEMCPY_INT( dst, src, len )                                              \\r
+{                                                                                   \\r
+    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \\r
+    int* _icv_memcpy_dst_ = (int*)(dst);                                            \\r
+    const int* _icv_memcpy_src_ = (const int*)(src);                                \\r
+    assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 &&                      \\r
+            ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                      \\r
+                                                                                    \\r
+    for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)          \\r
+        _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];        \\r
+}\r
+\r
+\r
+#define CV_MEMCPY_AUTO( dst, src, len )                                             \\r
+{                                                                                   \\r
+    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \\r
+    char* _icv_memcpy_dst_ = (char*)(dst);                                          \\r
+    const char* _icv_memcpy_src_ = (const char*)(src);                              \\r
+    if( (_icv_memcpy_len_ & (sizeof(int)-1)) == 0 )                                 \\r
+    {                                                                               \\r
+        assert( ((size_t)_icv_memcpy_src_&(sizeof(int)-1)) == 0 &&                  \\r
+                ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                  \\r
+        for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_;                 \\r
+            _icv_memcpy_i_+=sizeof(int) )                                           \\r
+        {                                                                           \\r
+            *(int*)(_icv_memcpy_dst_+_icv_memcpy_i_) =                              \\r
+            *(const int*)(_icv_memcpy_src_+_icv_memcpy_i_);                         \\r
+        }                                                                           \\r
+    }                                                                               \\r
+    else                                                                            \\r
+    {                                                                               \\r
+        for(_icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++)\\r
+            _icv_memcpy_dst_[_icv_memcpy_i_] = _icv_memcpy_src_[_icv_memcpy_i_];    \\r
+    }                                                                               \\r
+}\r
+\r
+\r
+#define CV_ZERO_CHAR( dst, len )                                                    \\r
+{                                                                                   \\r
+    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \\r
+    char* _icv_memcpy_dst_ = (char*)(dst);                                          \\r
+                                                                                    \\r
+    for( _icv_memcpy_i_ = 0; _icv_memcpy_i_ < _icv_memcpy_len_; _icv_memcpy_i_++ )  \\r
+        _icv_memcpy_dst_[_icv_memcpy_i_] = '\0';                                    \\r
+}\r
+\r
+\r
+#define CV_ZERO_INT( dst, len )                                                     \\r
+{                                                                                   \\r
+    size_t _icv_memcpy_i_, _icv_memcpy_len_ = (len);                                \\r
+    int* _icv_memcpy_dst_ = (int*)(dst);                                            \\r
+    assert( ((size_t)_icv_memcpy_dst_&(sizeof(int)-1)) == 0 );                      \\r
+                                                                                    \\r
+    for(_icv_memcpy_i_=0;_icv_memcpy_i_<_icv_memcpy_len_;_icv_memcpy_i_++)          \\r
+        _icv_memcpy_dst_[_icv_memcpy_i_] = 0;                                       \\r
+}\r
+\r
+\r
+/****************************************************************************************\\r
+\r
+  Generic implementation of QuickSort algorithm.\r
+  ----------------------------------------------\r
+  Using this macro user can declare customized sort function that can be much faster\r
+  than built-in qsort function because of lower overhead on elements\r
+  comparison and exchange. The macro takes less_than (or LT) argument - a macro or function\r
+  that takes 2 arguments returns non-zero if the first argument should be before the second\r
+  one in the sorted sequence and zero otherwise.\r
+\r
+  Example:\r
+\r
+    Suppose that the task is to sort points by ascending of y coordinates and if\r
+    y's are equal x's should ascend.\r
+\r
+    The code is:\r
+    ------------------------------------------------------------------------------\r
+           #define cmp_pts( pt1, pt2 ) \\r
+               ((pt1).y < (pt2).y || ((pt1).y < (pt2).y && (pt1).x < (pt2).x))\r
+\r
+           [static] CV_IMPLEMENT_QSORT( icvSortPoints, CvPoint, cmp_pts )\r
+    ------------------------------------------------------------------------------\r
+\r
+    After that the function "void icvSortPoints( CvPoint* array, size_t total, int aux );"\r
+    is available to user.\r
+\r
+  aux is an additional parameter, which can be used when comparing elements.\r
+  The current implementation was derived from *BSD system qsort():\r
+\r
+    * Copyright (c) 1992, 1993\r
+    *  The Regents of the University of California.  All rights reserved.\r
+    *\r
+    * Redistribution and use in source and binary forms, with or without\r
+    * modification, are permitted provided that the following conditions\r
+    * are met:\r
+    * 1. Redistributions of source code must retain the above copyright\r
+    *    notice, this list of conditions and the following disclaimer.\r
+    * 2. Redistributions in binary form must reproduce the above copyright\r
+    *    notice, this list of conditions and the following disclaimer in the\r
+    *    documentation and/or other materials provided with the distribution.\r
+    * 3. All advertising materials mentioning features or use of this software\r
+    *    must display the following acknowledgement:\r
+    *  This product includes software developed by the University of\r
+    *  California, Berkeley and its contributors.\r
+    * 4. Neither the name of the University nor the names of its contributors\r
+    *    may be used to endorse or promote products derived from this software\r
+    *    without specific prior written permission.\r
+    *\r
+    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+    * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+    * SUCH DAMAGE.\r
+\r
+\****************************************************************************************/\r
+\r
+#define CV_IMPLEMENT_QSORT_EX( func_name, T, LT, user_data_type )                   \\r
+void func_name( T *array, size_t total, user_data_type aux )                        \\r
+{                                                                                   \\r
+    int isort_thresh = 7;                                                           \\r
+    T t;                                                                            \\r
+    int sp = 0;                                                                     \\r
+                                                                                    \\r
+    struct                                                                          \\r
+    {                                                                               \\r
+        T *lb;                                                                      \\r
+        T *ub;                                                                      \\r
+    }                                                                               \\r
+    stack[48];                                                                      \\r
+                                                                                    \\r
+    aux = aux;                                                                      \\r
+                                                                                    \\r
+    if( total <= 1 )                                                                \\r
+        return;                                                                     \\r
+                                                                                    \\r
+    stack[0].lb = array;                                                            \\r
+    stack[0].ub = array + (total - 1);                                              \\r
+                                                                                    \\r
+    while( sp >= 0 )                                                                \\r
+    {                                                                               \\r
+        T* left = stack[sp].lb;                                                     \\r
+        T* right = stack[sp--].ub;                                                  \\r
+                                                                                    \\r
+        for(;;)                                                                     \\r
+        {                                                                           \\r
+            int i, n = (int)(right - left) + 1, m;                                  \\r
+            T* ptr;                                                                 \\r
+            T* ptr2;                                                                \\r
+                                                                                    \\r
+            if( n <= isort_thresh )                                                 \\r
+            {                                                                       \\r
+            insert_sort:                                                            \\r
+                for( ptr = left + 1; ptr <= right; ptr++ )                          \\r
+                {                                                                   \\r
+                    for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)   \\r
+                        CV_SWAP( ptr2[0], ptr2[-1], t );                            \\r
+                }                                                                   \\r
+                break;                                                              \\r
+            }                                                                       \\r
+            else                                                                    \\r
+            {                                                                       \\r
+                T* left0;                                                           \\r
+                T* left1;                                                           \\r
+                T* right0;                                                          \\r
+                T* right1;                                                          \\r
+                T* pivot;                                                           \\r
+                T* a;                                                               \\r
+                T* b;                                                               \\r
+                T* c;                                                               \\r
+                int swap_cnt = 0;                                                   \\r
+                                                                                    \\r
+                left0 = left;                                                       \\r
+                right0 = right;                                                     \\r
+                pivot = left + (n/2);                                               \\r
+                                                                                    \\r
+                if( n > 40 )                                                        \\r
+                {                                                                   \\r
+                    int d = n / 8;                                                  \\r
+                    a = left, b = left + d, c = left + 2*d;                         \\r
+                    left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))     \\r
+                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \\r
+                                                                                    \\r
+                    a = pivot - d, b = pivot, c = pivot + d;                        \\r
+                    pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))    \\r
+                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \\r
+                                                                                    \\r
+                    a = right - 2*d, b = right - d, c = right;                      \\r
+                    right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))    \\r
+                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));    \\r
+                }                                                                   \\r
+                                                                                    \\r
+                a = left, b = pivot, c = right;                                     \\r
+                pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))        \\r
+                                   : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));       \\r
+                if( pivot != left0 )                                                \\r
+                {                                                                   \\r
+                    CV_SWAP( *pivot, *left0, t );                                   \\r
+                    pivot = left0;                                                  \\r
+                }                                                                   \\r
+                left = left1 = left0 + 1;                                           \\r
+                right = right1 = right0;                                            \\r
+                                                                                    \\r
+                for(;;)                                                             \\r
+                {                                                                   \\r
+                    while( left <= right && !LT(*pivot, *left) )                    \\r
+                    {                                                               \\r
+                        if( !LT(*left, *pivot) )                                    \\r
+                        {                                                           \\r
+                            if( left > left1 )                                      \\r
+                                CV_SWAP( *left1, *left, t );                        \\r
+                            swap_cnt = 1;                                           \\r
+                            left1++;                                                \\r
+                        }                                                           \\r
+                        left++;                                                     \\r
+                    }                                                               \\r
+                                                                                    \\r
+                    while( left <= right && !LT(*right, *pivot) )                   \\r
+                    {                                                               \\r
+                        if( !LT(*pivot, *right) )                                   \\r
+                        {                                                           \\r
+                            if( right < right1 )                                    \\r
+                                CV_SWAP( *right1, *right, t );                      \\r
+                            swap_cnt = 1;                                           \\r
+                            right1--;                                               \\r
+                        }                                                           \\r
+                        right--;                                                    \\r
+                    }                                                               \\r
+                                                                                    \\r
+                    if( left > right )                                              \\r
+                        break;                                                      \\r
+                    CV_SWAP( *left, *right, t );                                    \\r
+                    swap_cnt = 1;                                                   \\r
+                    left++;                                                         \\r
+                    right--;                                                        \\r
+                }                                                                   \\r
+                                                                                    \\r
+                if( swap_cnt == 0 )                                                 \\r
+                {                                                                   \\r
+                    left = left0, right = right0;                                   \\r
+                    goto insert_sort;                                               \\r
+                }                                                                   \\r
+                                                                                    \\r
+                n = MIN( (int)(left1 - left0), (int)(left - left1) );               \\r
+                for( i = 0; i < n; i++ )                                            \\r
+                    CV_SWAP( left0[i], left[i-n], t );                              \\r
+                                                                                    \\r
+                n = MIN( (int)(right0 - right1), (int)(right1 - right) );           \\r
+                for( i = 0; i < n; i++ )                                            \\r
+                    CV_SWAP( left[i], right0[i-n+1], t );                           \\r
+                n = (int)(left - left1);                                            \\r
+                m = (int)(right1 - right);                                          \\r
+                if( n > 1 )                                                         \\r
+                {                                                                   \\r
+                    if( m > 1 )                                                     \\r
+                    {                                                               \\r
+                        if( n > m )                                                 \\r
+                        {                                                           \\r
+                            stack[++sp].lb = left0;                                 \\r
+                            stack[sp].ub = left0 + n - 1;                           \\r
+                            left = right0 - m + 1, right = right0;                  \\r
+                        }                                                           \\r
+                        else                                                        \\r
+                        {                                                           \\r
+                            stack[++sp].lb = right0 - m + 1;                        \\r
+                            stack[sp].ub = right0;                                  \\r
+                            left = left0, right = left0 + n - 1;                    \\r
+                        }                                                           \\r
+                    }                                                               \\r
+                    else                                                            \\r
+                        left = left0, right = left0 + n - 1;                        \\r
+                }                                                                   \\r
+                else if( m > 1 )                                                    \\r
+                    left = right0 - m + 1, right = right0;                          \\r
+                else                                                                \\r
+                    break;                                                          \\r
+            }                                                                       \\r
+        }                                                                           \\r
+    }                                                                               \\r
+}\r
+\r
+#define CV_IMPLEMENT_QSORT( func_name, T, cmp )  \\r
+    CV_IMPLEMENT_QSORT_EX( func_name, T, cmp, int )\r
+\r
+/****************************************************************************************\\r
+*                     Structures and macros for integration with IPP                     *\r
+\****************************************************************************************/\r
+\r
+/* IPP-compatible return codes */\r
+typedef enum CvStatus\r
+{\r
+    CV_BADMEMBLOCK_ERR          = -113,\r
+    CV_INPLACE_NOT_SUPPORTED_ERR= -112,\r
+    CV_UNMATCHED_ROI_ERR        = -111,\r
+    CV_NOTFOUND_ERR             = -110,\r
+    CV_BADCONVERGENCE_ERR       = -109,\r
+\r
+    CV_BADDEPTH_ERR             = -107,\r
+    CV_BADROI_ERR               = -106,\r
+    CV_BADHEADER_ERR            = -105,\r
+    CV_UNMATCHED_FORMATS_ERR    = -104,\r
+    CV_UNSUPPORTED_COI_ERR      = -103,\r
+    CV_UNSUPPORTED_CHANNELS_ERR = -102,\r
+    CV_UNSUPPORTED_DEPTH_ERR    = -101,\r
+    CV_UNSUPPORTED_FORMAT_ERR   = -100,\r
+\r
+    CV_BADARG_ERR      = -49,  //ipp comp\r
+    CV_NOTDEFINED_ERR  = -48,  //ipp comp\r
+\r
+    CV_BADCHANNELS_ERR = -47,  //ipp comp\r
+    CV_BADRANGE_ERR    = -44,  //ipp comp\r
+    CV_BADSTEP_ERR     = -29,  //ipp comp\r
+\r
+    CV_BADFLAG_ERR     =  -12,\r
+    CV_DIV_BY_ZERO_ERR =  -11, //ipp comp\r
+    CV_BADCOEF_ERR     =  -10,\r
+\r
+    CV_BADFACTOR_ERR   =  -7,\r
+    CV_BADPOINT_ERR    =  -6,\r
+    CV_BADSCALE_ERR    =  -4,\r
+    CV_OUTOFMEM_ERR    =  -3,\r
+    CV_NULLPTR_ERR     =  -2,\r
+    CV_BADSIZE_ERR     =  -1,\r
+    CV_NO_ERR          =   0,\r
+    CV_OK              =   CV_NO_ERR\r
+}\r
+CvStatus;\r
+\r
+#define IPPI_CALL(stmt) CV_Assert((stmt) >= 0)\r
+\r
+#define CV_NOTHROW throw()\r
+\r
+typedef struct CvFuncTable\r
+{\r
+    void*   fn_2d[CV_DEPTH_MAX];\r
+}\r
+CvFuncTable;\r
+\r
+typedef struct CvBigFuncTable\r
+{\r
+    void*   fn_2d[CV_DEPTH_MAX*CV_CN_MAX];\r
+}\r
+CvBigFuncTable;\r
+\r
+\r
+typedef struct CvBtFuncTable\r
+{\r
+    void*   fn_2d[33];\r
+}\r
+CvBtFuncTable;\r
+\r
+#define CV_INIT_FUNC_TAB( tab, FUNCNAME, FLAG )         \\r
+    (tab).fn_2d[CV_8U] = (void*)FUNCNAME##_8u##FLAG;    \\r
+    (tab).fn_2d[CV_8S] = 0;                             \\r
+    (tab).fn_2d[CV_16U] = (void*)FUNCNAME##_16u##FLAG;  \\r
+    (tab).fn_2d[CV_16S] = (void*)FUNCNAME##_16s##FLAG;  \\r
+    (tab).fn_2d[CV_32S] = (void*)FUNCNAME##_32s##FLAG;  \\r
+    (tab).fn_2d[CV_32F] = (void*)FUNCNAME##_32f##FLAG;  \\r
+    (tab).fn_2d[CV_64F] = (void*)FUNCNAME##_64f##FLAG\r
+\r
+#define CV_INIT_BIG_FUNC_TAB( tab, FUNCNAME, FLAG )             \\r
+    (tab).fn_2d[CV_8UC1]  = (void*)FUNCNAME##_8u_C1##FLAG;      \\r
+    (tab).fn_2d[CV_8UC2]  = (void*)FUNCNAME##_8u_C2##FLAG;      \\r
+    (tab).fn_2d[CV_8UC3]  = (void*)FUNCNAME##_8u_C3##FLAG;      \\r
+    (tab).fn_2d[CV_8UC4]  = (void*)FUNCNAME##_8u_C4##FLAG;      \\r
+                                                                \\r
+    (tab).fn_2d[CV_8SC1]  = 0;                                  \\r
+    (tab).fn_2d[CV_8SC2]  = 0;                                  \\r
+    (tab).fn_2d[CV_8SC3]  = 0;                                  \\r
+    (tab).fn_2d[CV_8SC4]  = 0;                                  \\r
+                                                                \\r
+    (tab).fn_2d[CV_16UC1] = (void*)FUNCNAME##_16u_C1##FLAG;     \\r
+    (tab).fn_2d[CV_16UC2] = (void*)FUNCNAME##_16u_C2##FLAG;     \\r
+    (tab).fn_2d[CV_16UC3] = (void*)FUNCNAME##_16u_C3##FLAG;     \\r
+    (tab).fn_2d[CV_16UC4] = (void*)FUNCNAME##_16u_C4##FLAG;     \\r
+                                                                \\r
+    (tab).fn_2d[CV_16SC1] = (void*)FUNCNAME##_16s_C1##FLAG;     \\r
+    (tab).fn_2d[CV_16SC2] = (void*)FUNCNAME##_16s_C2##FLAG;     \\r
+    (tab).fn_2d[CV_16SC3] = (void*)FUNCNAME##_16s_C3##FLAG;     \\r
+    (tab).fn_2d[CV_16SC4] = (void*)FUNCNAME##_16s_C4##FLAG;     \\r
+                                                                \\r
+    (tab).fn_2d[CV_32SC1] = (void*)FUNCNAME##_32s_C1##FLAG;     \\r
+    (tab).fn_2d[CV_32SC2] = (void*)FUNCNAME##_32s_C2##FLAG;     \\r
+    (tab).fn_2d[CV_32SC3] = (void*)FUNCNAME##_32s_C3##FLAG;     \\r
+    (tab).fn_2d[CV_32SC4] = (void*)FUNCNAME##_32s_C4##FLAG;     \\r
+                                                                \\r
+    (tab).fn_2d[CV_32FC1] = (void*)FUNCNAME##_32f_C1##FLAG;     \\r
+    (tab).fn_2d[CV_32FC2] = (void*)FUNCNAME##_32f_C2##FLAG;     \\r
+    (tab).fn_2d[CV_32FC3] = (void*)FUNCNAME##_32f_C3##FLAG;     \\r
+    (tab).fn_2d[CV_32FC4] = (void*)FUNCNAME##_32f_C4##FLAG;     \\r
+                                                                \\r
+    (tab).fn_2d[CV_64FC1] = (void*)FUNCNAME##_64f_C1##FLAG;     \\r
+    (tab).fn_2d[CV_64FC2] = (void*)FUNCNAME##_64f_C2##FLAG;     \\r
+    (tab).fn_2d[CV_64FC3] = (void*)FUNCNAME##_64f_C3##FLAG;     \\r
+    (tab).fn_2d[CV_64FC4] = (void*)FUNCNAME##_64f_C4##FLAG\r
+\r
+#define CV_INIT_PIXSIZE_TAB( tab, FUNCNAME, FLAG )      \\r
+    (tab).fn_2d[1]  = (void*)FUNCNAME##_8u_C1##FLAG;    \\r
+    (tab).fn_2d[2]  = (void*)FUNCNAME##_8u_C2##FLAG;    \\r
+    (tab).fn_2d[3]  = (void*)FUNCNAME##_8u_C3##FLAG;    \\r
+    (tab).fn_2d[4]  = (void*)FUNCNAME##_16u_C2##FLAG;   \\r
+    (tab).fn_2d[6]  = (void*)FUNCNAME##_16u_C3##FLAG;   \\r
+    (tab).fn_2d[8]  = (void*)FUNCNAME##_32s_C2##FLAG;   \\r
+    (tab).fn_2d[12] = (void*)FUNCNAME##_32s_C3##FLAG;   \\r
+    (tab).fn_2d[16] = (void*)FUNCNAME##_64s_C2##FLAG;   \\r
+    (tab).fn_2d[24] = (void*)FUNCNAME##_64s_C3##FLAG;   \\r
+    (tab).fn_2d[32] = (void*)FUNCNAME##_64s_C4##FLAG\r
+\r
+\r
+#endif /*_CXCORE_MISC_H_*/\r
diff --git a/opencv/include/opencv/cxoperations.hpp b/opencv/include/opencv/cxoperations.hpp
new file mode 100644 (file)
index 0000000..677b652
--- /dev/null
@@ -0,0 +1,5029 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of the copyright holders may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef _CXCORE_OPERATIONS_H_
+#define _CXCORE_OPERATIONS_H_
+
+#include <limits.h>
+
+#ifndef CV_NO_BACKWARD_COMPATIBILITY
+#include "cxcompat.h"
+#endif
+
+#ifdef __cplusplus
+
+namespace cv
+{
+
+/////////////// saturate_cast (used in image & signal processing) ///////////////////
+
+template<typename T> static inline T saturate_cast(uchar v) { return T(v); }
+template<typename T> static inline T saturate_cast(schar v) { return T(v); }
+template<typename T> static inline T saturate_cast(ushort v) { return T(v); }
+template<typename T> static inline T saturate_cast(short v) { return T(v); }
+template<typename T> static inline T saturate_cast(unsigned v) { return T(v); }
+template<typename T> static inline T saturate_cast(int v) { return T(v); }
+template<typename T> static inline T saturate_cast(float v) { return T(v); }
+template<typename T> static inline T saturate_cast(double v) { return T(v); }
+
+template<> static inline uchar saturate_cast<uchar>(schar v)
+{ return (uchar)std::max((int)v, 0); }
+template<> static inline uchar saturate_cast<uchar>(ushort v)
+{ return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
+template<> static inline uchar saturate_cast<uchar>(int v)
+{ return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
+template<> static inline uchar saturate_cast<uchar>(short v)
+{ return saturate_cast<uchar>((int)v); }
+template<> static inline uchar saturate_cast<uchar>(unsigned v)
+{ return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
+template<> static inline uchar saturate_cast<uchar>(float v)
+{ int iv = cvRound(v); return saturate_cast<uchar>(iv); }
+template<> static inline uchar saturate_cast<uchar>(double v)
+{ int iv = cvRound(v); return saturate_cast<uchar>(iv); }
+
+template<> static inline schar saturate_cast<schar>(uchar v)
+{ return (schar)std::min((int)v, SCHAR_MAX); }
+template<> static inline schar saturate_cast<schar>(ushort v)
+{ return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
+template<> static inline schar saturate_cast<schar>(int v)
+{
+    return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ?
+                v : v > 0 ? SCHAR_MAX : SCHAR_MIN);
+}
+template<> static inline schar saturate_cast<schar>(short v)
+{ return saturate_cast<schar>((int)v); }
+template<> static inline schar saturate_cast<schar>(unsigned v)
+{ return (schar)std::min(v, (unsigned)SCHAR_MAX); }
+
+template<> static inline schar saturate_cast<schar>(float v)
+{ int iv = cvRound(v); return saturate_cast<schar>(iv); }
+template<> static inline schar saturate_cast<schar>(double v)
+{ int iv = cvRound(v); return saturate_cast<schar>(iv); }
+
+template<> static inline ushort saturate_cast<ushort>(schar v)
+{ return (ushort)std::max((int)v, 0); }
+template<> static inline ushort saturate_cast<ushort>(short v)
+{ return (ushort)std::max((int)v, 0); }
+template<> static inline ushort saturate_cast<ushort>(int v)
+{ return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
+template<> static inline ushort saturate_cast<ushort>(unsigned v)
+{ return (ushort)std::min(v, (unsigned)USHRT_MAX); }
+template<> static inline ushort saturate_cast<ushort>(float v)
+{ int iv = cvRound(v); return saturate_cast<ushort>(iv); }
+template<> static inline ushort saturate_cast<ushort>(double v)
+{ int iv = cvRound(v); return saturate_cast<ushort>(iv); }
+
+template<> static inline short saturate_cast<short>(ushort v)
+{ return (short)std::min((int)v, SHRT_MAX); }
+template<> static inline short saturate_cast<short>(int v)
+{
+    return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ?
+            v : v > 0 ? SHRT_MAX : SHRT_MIN);
+}
+template<> static inline short saturate_cast<short>(unsigned v)
+{ return (short)std::min(v, (unsigned)SHRT_MAX); }
+template<> static inline short saturate_cast<short>(float v)
+{ int iv = cvRound(v); return saturate_cast<short>(iv); }
+template<> static inline short saturate_cast<short>(double v)
+{ int iv = cvRound(v); return saturate_cast<short>(iv); }
+
+template<> static inline int saturate_cast<int>(float v) { return cvRound(v); }
+template<> static inline int saturate_cast<int>(double v) { return cvRound(v); }
+
+// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
+template<> static inline unsigned saturate_cast<unsigned>(float v){ return cvRound(v); }
+template<> static inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
+
+
+/////////////////////////// short vector (Vec_) /////////////////////////////
+
+template<typename T, int cn> inline Vec_<T, cn>::Vec_() {}
+template<typename T, int cn> inline Vec_<T, cn>::Vec_(T v0)
+{
+    val[0] = v0;
+    for(int i = 1; i < cn; i++) val[i] = T();
+}
+
+template<typename T, int cn> inline Vec_<T, cn>::Vec_(T v0, T v1)
+{
+    val[0] = v0; val[1] = v1;
+    for(int i = 2; i < cn; i++) val[i] = T(0);
+}
+
+template<typename T, int cn> inline Vec_<T, cn>::Vec_(T v0, T v1, T v2)
+{
+    val[0] = v0; val[1] = v1; val[2] = v2;
+    for(int i = 3; i < cn; i++) val[i] = T(0);
+}
+
+template<typename T, int cn> inline Vec_<T, cn>::Vec_(T v0, T v1, T v2, T v3)
+{
+    val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
+    for(int i = 4; i < cn; i++) val[i] = T(0);
+}
+
+template<typename T, int cn> inline Vec_<T, cn>::Vec_(const Vec_<T, cn>& v)
+{
+    for( int i = 0; i < cn; i++ ) val[i] = v.val[i];
+}
+
+template<typename T, int cn> inline Vec_<T, cn> Vec_<T, cn>::all(T alpha)
+{
+    Vec_ v;
+    for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
+    return v;
+}
+
+template<typename T, int cn> inline T Vec_<T, cn>::dot(const Vec_<T, cn>& v) const
+{
+    T s = 0;
+    for( int i = 0; i < cn; i++ ) s += val[i]*v.val[i];
+    return s;
+}
+
+template<typename T, int cn> inline double Vec_<T, cn>::ddot(const Vec_<T, cn>& v) const
+{
+    double s = 0;
+    for( int i = 0; i < cn; i++ ) s += (double)val[i]*v.val[i];
+    return s;
+}
+
+template<typename T, int cn> inline Vec_<T, cn> Vec_<T, cn>::cross(const Vec_<T, cn>& v) const
+{
+    return Vec_<T, cn>(); // for arbitrary-size vector there is no cross-product defined
+}
+
+template<typename T, int cn> template<typename T2>
+inline Vec_<T, cn>::operator Vec_<T2, cn>() const
+{
+    Vec_<T2, cn> v;
+    for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(val[i]);
+    return v;
+}
+
+template<typename T, int cn> inline Vec_<T, cn>::operator CvScalar() const
+{
+    CvScalar s = {{0,0,0,0}};
+    int i;
+    for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = val[i];
+    for( ; i < 4; i++ ) s.val[i] = 0;
+    return s;
+}
+
+template<typename T, int cn> inline T Vec_<T, cn>::operator [](int i) const { return val[i]; }
+template<typename T, int cn> inline T& Vec_<T, cn>::operator[](int i) { return val[i]; }
+
+template<typename T, int cn> static inline Vec_<T, cn>
+operator + (const Vec_<T, cn>& a, const Vec_<T, cn>& b)
+{
+    Vec_<T, cn> c = a;
+    return c += b;
+}
+
+template<typename T, int cn> static inline Vec_<T, cn>
+operator - (const Vec_<T, cn>& a, const Vec_<T, cn>& b)
+{
+    Vec_<T, cn> c = a;
+    return c -= b;
+}
+
+template<typename T, int cn> static inline Vec_<T, cn>
+operator * (const Vec_<T, cn>& a, T alpha)
+{
+    Vec_<T, cn> c = a;
+    return c *= alpha;
+}
+
+template<typename T, int cn> static inline Vec_<T, cn>
+operator * (T alpha, const Vec_<T, cn>& a)
+{
+    return a * alpha;
+}
+
+template<typename T, int cn> static inline Vec_<T, cn>
+operator - (const Vec_<T, cn>& a)
+{
+    Vec_<T,cn> t;
+    for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<T>(-a.val[i]);
+    return t;
+}
+
+template<> inline Vec_<float, 3> Vec_<float, 3>::cross(const Vec_<float, 3>& v) const
+{
+    return Vec_<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
+                     val[2]*v.val[0] - val[0]*v.val[2],
+                     val[0]*v.val[1] - val[1]*v.val[0]);
+}
+
+template<> inline Vec_<double, 3> Vec_<double, 3>::cross(const Vec_<double, 3>& v) const
+{
+    return Vec_<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
+                     val[2]*v.val[0] - val[0]*v.val[2],
+                     val[0]*v.val[1] - val[1]*v.val[0]);
+}
+
+template<typename T1, typename T2> static inline
+Vec_<T1, 2>& operator += (Vec_<T1, 2>& a, const Vec_<T2, 2>& b)
+{
+    a[0] = saturate_cast<T1>(a[0] + b[0]);
+    a[1] = saturate_cast<T1>(a[1] + b[1]);
+    return a;
+}
+
+template<typename T1, typename T2> static inline
+Vec_<T1, 3>& operator += (Vec_<T1, 3>& a, const Vec_<T2, 3>& b)
+{
+    a[0] = saturate_cast<T1>(a[0] + b[0]);
+    a[1] = saturate_cast<T1>(a[1] + b[1]);
+    a[2] = saturate_cast<T1>(a[2] + b[2]);
+    return a;
+}
+
+template<typename T1, typename T2> static inline
+Vec_<T1, 4>& operator += (Vec_<T1, 4>& a, const Vec_<T2, 4>& b)
+{
+    a[0] = saturate_cast<T1>(a[0] + b[0]);
+    a[1] = saturate_cast<T1>(a[1] + b[1]);
+    a[2] = saturate_cast<T1>(a[2] + b[2]);
+    a[3] = saturate_cast<T1>(a[3] + b[3]);
+    return a;
+}
+
+//////////////////////////////// Complex //////////////////////////////
+
+template<typename T> inline Complex<T>::Complex() : re(0), im(0) {}
+template<typename T> inline Complex<T>::Complex( T _re, T _im ) : re(_re), im(_im) {}
+template<typename T> template<typename T2> inline Complex<T>::operator Complex<T2>() const
+{ return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im)); }
+template<typename T> inline Complex<T> Complex<T>::conj() const
+{ return Complex<T>(re, -im); }
+
+template<typename T> static inline
+Complex<T> operator + (const Complex<T>& a, const Complex<T>& b)
+{ return Complex<T>( a.re + b.re, a.im + b.im ); }
+
+template<typename T> static inline
+Complex<T>& operator += (Complex<T>& a, const Complex<T>& b)
+{ a.re += b.re; a.im += b.im; return a; }
+
+template<typename T> static inline
+Complex<T> operator - (const Complex<T>& a, const Complex<T>& b)
+{ return Complex<T>( a.re - b.re, a.im - b.im ); }
+
+template<typename T> static inline
+Complex<T>& operator -= (Complex<T>& a, const Complex<T>& b)
+{ a.re -= b.re; a.im -= b.im; return a; }
+
+template<typename T> static inline
+Complex<T> operator - (const Complex<T>& a)
+{ return Complex<T>(-a.re, -a.im); }
+
+template<typename T> static inline
+Complex<T> operator * (const Complex<T>& a, const Complex<T>& b)
+{ return Complex<T>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); }
+
+template<typename T> static inline
+Complex<T> operator * (const Complex<T>& a, T b)
+{ return Complex<T>( a.re*b, a.im*b ); }
+
+template<typename T> static inline
+Complex<T> operator * (T b, const Complex<T>& a)
+{ return Complex<T>( a.re*b, a.im*b ); }
+
+template<typename T> static inline
+Complex<T> operator + (const Complex<T>& a, T b)
+{ return Complex<T>( a.re + b, a.im ); }
+
+template<typename T> static inline
+Complex<T> operator - (const Complex<T>& a, T b)
+{ return Complex<T>( a.re - b, a.im ); }
+
+template<typename T> static inline
+Complex<T> operator + (T b, const Complex<T>& a)
+{ return Complex<T>( a.re + b, a.im ); }
+
+template<typename T> static inline
+Complex<T> operator - (T b, const Complex<T>& a)
+{ return Complex<T>( b - a.re, -a.im ); }
+
+template<typename T> static inline
+Complex<T>& operator += (Complex<T>& a, T b)
+{ a.re += b; return a; }
+
+template<typename T> static inline
+Complex<T>& operator -= (Complex<T>& a, T b)
+{ a.re -= b; return a; }
+
+template<typename T> static inline
+Complex<T>& operator *= (Complex<T>& a, T b)
+{ a.re *= b; a.im *= b; return a; }
+
+template<typename T> static inline
+double abs(const Complex<T>& a)
+{ return std::sqrt( (double)a.re.a.re + (double)a.im*a.im); }
+
+template<typename T> static inline
+Complex<T> operator / (const Complex<T>& a, const Complex<T>& b)
+{
+    double t = 1./((double)b.re*b.re + (double)b.im*b.im);
+    return Complex<T>( (T)((a.re*b.re + a.im*b.im)*t),
+                        (T)((-a.re*b.im + a.im*b.re)*t) );
+}
+
+template<typename T> static inline
+Complex<T>& operator /= (Complex<T>& a, const Complex<T>& b)
+{
+    return (a = a / b);
+}
+
+template<typename T> static inline
+Complex<T> operator / (const Complex<T>& a, T b)
+{
+    T t = (T)1/b;
+    return Complex<T>( a.re*t, a.im*t );
+}
+
+template<typename T> static inline
+Complex<T> operator / (T b, const Complex<T>& a)
+{
+    return Complex<T>(b)/a;
+}
+
+template<typename T> static inline
+Complex<T> operator /= (const Complex<T>& a, T b)
+{
+    T t = (T)1/b;
+    a.re *= t; a.im *= t; return a;
+}
+
+//////////////////////////////// 2D Point ////////////////////////////////
+
+template<typename T> inline Point_<T>::Point_() : x(0), y(0) {}
+template<typename T> inline Point_<T>::Point_(T _x, T _y) : x(_x), y(_y) {}
+template<typename T> inline Point_<T>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {}
+template<typename T> inline Point_<T>::Point_(const CvPoint& pt) : x((T)pt.x), y((T)pt.y) {}
+template<typename T> inline Point_<T>::Point_(const CvPoint2D32f& pt) : x((T)pt.x), y((T)pt.y) {}
+template<typename T> inline Point_<T>::Point_(const Size_<T>& sz) : x(sz.width), y(sz.height) {}
+template<typename T> inline Point_<T>& Point_<T>::operator = (const Point_& pt)
+{ x = pt.x; y = pt.y; return *this; }
+
+template<typename T> inline Point_<T>::operator Point_<int>() const
+{ return Point_<int>(cvRound(x), cvRound(y)); }
+template<typename T> inline Point_<T>::operator Point_<float>() const
+{ return Point_<float>(float(x), float(y)); }
+template<typename T> inline Point_<T>::operator Point_<double>() const
+{ return Point_<double>(x, y); }
+template<typename T> inline Point_<T>::operator CvPoint() const
+{ return cvPoint(cvRound(x), cvRound(y)); }
+template<typename T> inline Point_<T>::operator CvPoint2D32f() const
+{ return cvPoint2D32f((float)x, (float)y); }
+
+template<typename T> inline T Point_<T>::dot(const Point_& pt) const
+{ return x*pt.x + y*pt.y; }
+template<typename T> inline double Point_<T>::ddot(const Point_& pt) const
+{ return (double)x*pt.x + (double)y*pt.y; }
+
+template<typename T> static inline Point_<T>&
+operator += (Point_<T>& a, const Point_<T>& b) { a.x += b.x; a.y += b.y; return a; }
+
+template<typename T> static inline Point_<T>&
+operator -= (Point_<T>& a, const Point_<T>& b) { a.x -= b.x; a.y -= b.y; return a; }
+
+template<typename T> static inline double norm(const Point_<T>& pt)
+{ return sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); }
+
+template<typename T> static inline bool operator == (const Point_<T>& a, const Point_<T>& b)
+{ return a.x == b.x && a.y == b.y; }
+
+template<typename T> static inline bool operator != (const Point_<T>& a, const Point_<T>& b)
+{ return !(a == b); }
+
+template<typename T> static inline Point_<T> operator + (const Point_<T>& a, const Point_<T>& b)
+{ return Point_<T>( a.x + b.x, a.y + b.y ); }
+
+template<typename T> static inline Point_<T> operator - (const Point_<T>& a, const Point_<T>& b)
+{ return Point_<T>( a.x - b.x, a.y - b.y ); }
+
+template<typename T> static inline Point_<T> operator - (const Point_<T>& a)
+{ return Point_<T>( -a.x, -a.y ); }
+
+template<typename T> static inline Point_<T> operator * (const Point_<T>& a, T b)
+{ return Point_<T>( a.x*b, a.y*b ); }
+
+template<typename T> static inline Point_<T> operator * (T a, const Point_<T>& b)
+{ return Point_<T>( a*b.x, a*b.y ); }
+
+template<> inline Point_<int>::Point_(const CvPoint2D32f& pt) : x(cvRound(pt.x)), y(cvRound(pt.y)) {}
+template<> inline Point_<int>::operator CvPoint() const { return cvPoint(x,y); }
+
+//////////////////////////////// 3D Point ////////////////////////////////
+
+template<typename T> inline Point3_<T>::Point3_() : x(0), y(0), z(0) {}
+template<typename T> inline Point3_<T>::Point3_(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
+template<typename T> inline Point3_<T>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {}
+template<typename T> inline Point3_<T>::Point3_(const CvPoint3D32f& pt) :
+x((T)pt.x), y((T)pt.y), z((T)pt.z) {}
+template<typename T> inline Point3_<T>::Point3_(const Vec_<T, 3>& t) : x(t[0]), y(t[1]), z(t[2]) {}
+
+template<typename T> inline Point3_<T>::operator Point3_<int>() const
+{ return Point3_<int>(cvRound(x), cvRound(y), cvRound(z)); }
+template<typename T> inline Point3_<T>::operator Point3_<float>() const
+{ return Point3_<float>(float(x), float(y), float(z)); }
+template<typename T> inline Point3_<T>::operator Point3_<double>() const
+{ return Point3_<double>(x, y, z); }
+template<typename T> inline Point3_<T>::operator CvPoint3D32f() const
+{ return cvPoint3D32f((float)x, (float)y, (float)z); }
+
+template<typename T> inline Point3_<T>& Point3_<T>::operator = (const Point3_& pt)
+{ x = pt.x; y = pt.y; z = pt.z; return *this; }
+
+template<typename T> inline T Point3_<T>::dot(const Point3_& pt) const
+{ return x*pt.x + y*pt.y + z*pt.z; }
+template<typename T> inline double Point3_<T>::ddot(const Point3_& pt) const
+{ return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; }
+
+template<typename T> static inline Point3_<T>&
+operator += (Point3_<T>& a, const Point3_<T>& b) { a += b.x; a += b.y; a += b.z; return a; }
+template<typename T> static inline Point3_<T>&
+operator -= (Point3_<T>& a, const Point3_<T>& b) { a -= b.x; a -= b.y; a -= b.z; return a; }
+
+template<typename T> static inline double norm(const Point3_<T>& pt)
+{ return sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); }
+
+template<typename T> static inline bool operator == (const Point3_<T>& a, const Point3_<T>& b)
+{ return a.x == b.x && a.y == b.y && a.z == b.z; }
+
+template<typename T> static inline Point3_<T> operator + (const Point3_<T>& a, const Point3_<T>& b)
+{ return Point3_<T>( a.x + b.x, a.y + b.y, a.z + b.z ); }
+
+template<typename T> static inline Point3_<T> operator - (const Point3_<T>& a, const Point3_<T>& b)
+{ return Point3_<T>( a.x - b.x, a.y - b.y, a.z - b.z ); }
+
+template<typename T> static inline Point3_<T> operator - (const Point3_<T>& a)
+{ return Point3_<T>( -a.x, -a.y, -a.z ); }
+
+template<typename T> static inline Point3_<T> operator * (const Point3_<T>& a, T b)
+{ return Point3_<T>( a.x*b, a.y*b, a.z*b ); }
+
+template<typename T> static inline Point3_<T> operator * (T a, const Point3_<T>& b)
+{ return Point3_<T>( a*b.x, a*b.y, a*b.z ); }
+
+template<> inline Point3_<int>::Point3_(const CvPoint3D32f& pt)
+    : x(cvRound(pt.x)), y(cvRound(pt.y)), z(cvRound(pt.z)) {}
+
+//////////////////////////////// Size ////////////////////////////////
+
+template<typename T> inline Size_<T>::Size_()
+    : width(0), height(0) {}
+template<typename T> inline Size_<T>::Size_(T _width, T _height)
+    : width(_width), height(_height) {}
+template<typename T> inline Size_<T>::Size_(const Size_& sz)
+    : width(sz.width), height(sz.height) {}
+template<typename T> inline Size_<T>::Size_(const CvSize& sz)
+    : width((T)sz.width), height((T)sz.height) {}
+template<typename T> inline Size_<T>::Size_(const Point_<T>& pt) : width(pt.x), height(pt.y) {}
+
+template<typename T> inline Size_<T>::operator Size_<int>() const
+{ return Size_<int>(cvRound(width), cvRound(height)); }
+template<typename T> inline Size_<T>::operator Size_<float>() const
+{ return Size_<float>(float(width), float(height)); }
+template<typename T> inline Size_<T>::operator Size_<double>() const
+{ return Size_<double>(width, height); }
+template<typename T> inline Size_<T>::operator CvSize() const
+{ return cvSize(cvRound(width), cvRound(height)); }
+
+template<typename T> inline Size_<T>& Size_<T>::operator = (const Size_<T>& sz)
+{ width = sz.width; height = sz.height; return *this; }
+template<typename T> inline T Size_<T>::area() const { return width*height; }
+
+template<typename T> static inline Size_<T>& operator += (Size_<T>& a, const Size_<T>& b)
+{ a.width += b.width; a.height += b.height; return a; }
+template<typename T> static inline Size_<T>& operator -= (Size_<T>& a, const Size_<T>& b)
+{ a.width -= b.width; a.height -= b.height; return a; }
+
+template<typename T> static inline bool operator == (const Size_<T>& a, const Size_<T>& b)
+{ return a.width == b.width && a.height == b.height; }
+
+template<> inline Size_<int>::operator CvSize() const { return cvSize(width,height); }
+
+//////////////////////////////// Rect ////////////////////////////////
+
+
+template<typename T> inline Rect_<T>::Rect_() : x(0), y(0), width(0), height(0) {}
+template<typename T> inline Rect_<T>::Rect_(T _x, T _y, T _width, T _height) : x(_x), y(_y), width(_width), height(_height) {}
+template<typename T> inline Rect_<T>::Rect_(const Rect_<T>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {}
+template<typename T> inline Rect_<T>::Rect_(const CvRect& r) : x((T)r.x), y((T)r.y), width((T)r.width), height((T)r.height) {}
+template<typename T> inline Rect_<T>::Rect_(const Point_<T>& org, const Size_<T>& sz) :
+    x(org.x), y(org.y), width(sz.width), height(sz.height) {}
+template<typename T> inline Rect_<T>::Rect_(const Point_<T>& pt1, const Point_<T>& pt2)
+{
+    x = min(pt1.x, pt2.x); y = min(pt1.y, pt2.y);
+    width = max(pt1.x, pt2.x) - x; height = max(pt1.y, pt2.y) - y;
+}
+template<typename T> inline Rect_<T>& Rect_<T>::operator = ( const Rect_<T>& r )
+{ x = r.x; y = r.y; width = r.width; height = r.height; return *this; }
+
+template<typename T> inline Point_<T> Rect_<T>::tl() const { return Point_<T>(x,y); }
+template<typename T> inline Point_<T> Rect_<T>::br() const { return Point_<T>(x+width, y+height); }
+
+template<typename T> static inline Rect_<T>& operator += ( Rect_<T>& a, const Point_<T>& b )
+{ a.x += b.x; a.y += b.y; return a; }
+template<typename T> static inline Rect_<T>& operator -= ( Rect_<T>& a, const Point_<T>& b )
+{ a.x -= b.x; a.y -= b.y; return a; }
+
+template<typename T> static inline Rect_<T>& operator += ( Rect_<T>& a, const Size_<T>& b )
+{ a.width += b.width; a.height += b.height; return a; }
+
+template<typename T> static inline Rect_<T>& operator -= ( Rect_<T>& a, const Size_<T>& b )
+{ a.width -= b.width; a.height -= b.height; return a; }
+
+template<typename T> static inline Rect_<T>& operator &= ( Rect_<T>& a, const Rect_<T>& b )
+{
+    T x1 = max(a.x, b.x), y1 = max(a.y, b.y);
+    a.width = min(a.x + a.width, b.x + b.width) - x1;
+    a.height = min(a.y + a.height, b.y + b.height) - y1;
+    a.x = x1; a.y = y1;
+    if( a.width <= 0 || a.height <= 0 )
+        a = Rect();
+    return a;
+}
+
+template<typename T> static inline Rect_<T>& operator |= ( Rect_<T>& a, const Rect_<T>& b )
+{
+    T x1 = min(a.x, b.x), y1 = min(a.y, b.y);
+    a.width = max(a.x + a.width, b.x + b.width) - x1;
+    a.height = max(a.y + a.height, b.y + b.height) - y1;
+    a.x = x1; a.y = y1;
+    return a;
+}
+
+template<typename T> inline Size_<T> Rect_<T>::size() const { return Size_<T>(width, height); }
+template<typename T> inline T Rect_<T>::area() const { return width*height; }
+
+template<typename T> inline Rect_<T>::operator Rect_<int>() const { return Rect_<int>(cvRound(x), cvRound(y), cvRound(width), cvRound(height)); }
+template<typename T> inline Rect_<T>::operator Rect_<float>() const { return Rect_<float>(float(x), float(y), float(width), float(height)); }
+template<typename T> inline Rect_<T>::operator Rect_<double>() const { return Rect_<double>(x, y, width, height); }
+template<typename T> inline Rect_<T>::operator CvRect() const { return cvRect(cvRound(x), cvRound(y), cvRound(width), cvRound(height)); }
+
+template<typename T> inline bool Rect_<T>::contains(const Point_<T>& pt) const
+{ return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; }
+
+template<typename T> static inline bool operator == (const Rect_<T>& a, const Rect_<T>& b)
+{
+    return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
+}
+
+template<typename T> static inline Rect_<T> operator + (const Rect_<T>& a, const Point_<T>& b)
+{
+    return Rect_<T>( a.x + b.x, a.y + b.y, a.width, a.height );
+}
+
+template<typename T> static inline Rect_<T> operator - (const Rect_<T>& a, const Point_<T>& b)
+{
+    return Rect_<T>( a.x - b.x, a.y - b.y, a.width, a.height );
+}
+
+template<typename T> static inline Rect_<T> operator + (const Rect_<T>& a, const Size_<T>& b)
+{
+    return Rect_<T>( a.x, a.y, a.width + b.width, a.height + b.height );
+}
+
+template<typename T> static inline Rect_<T> operator & (const Rect_<T>& a, const Rect_<T>& b)
+{
+    Rect_<T> c = a;
+    return c &= b;
+}
+
+template<typename T> static inline Rect_<T> operator | (const Rect_<T>& a, const Rect_<T>& b)
+{
+    Rect_<T> c = a;
+    return c |= b;
+}
+
+template<typename T> inline bool Point_<T>::inside( const Rect_<T>& r ) const
+{
+    return r.contains(*this);
+}
+
+template<> inline Rect_<int>::operator CvRect() const { return cvRect(x, y, width, height); }
+
+inline RotatedRect::RotatedRect() { angle = 0; }
+inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
+    : center(_center), size(_size), angle(_angle) {}
+
+//////////////////////////////// Scalar_ ///////////////////////////////
+
+template<typename T> inline Scalar_<T>::Scalar_()
+{ this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; }
+
+template<typename T> inline Scalar_<T>::Scalar_(T v0, T v1, T v2, T v3)
+{ this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; }
+
+template<typename T> inline Scalar_<T>::Scalar_(const CvScalar& s)
+{
+    this->val[0] = saturate_cast<T>(s.val[0]);
+    this->val[1] = saturate_cast<T>(s.val[1]);
+    this->val[2] = saturate_cast<T>(s.val[2]);
+    this->val[3] = saturate_cast<T>(s.val[3]);
+}
+
+template<typename T> inline Scalar_<T>::Scalar_(T v0)
+{ this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; }
+
+template<typename T> inline Scalar_<T> Scalar_<T>::all(T v0)
+{ return Scalar_<T>(v0, v0, v0, v0); }
+template<typename T> inline Scalar_<T>::operator CvScalar() const
+{ return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); }
+
+template<typename T> template<typename T2> inline Scalar_<T>::operator Scalar_<T2>() const
+{
+    return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
+                  saturate_cast<T2>(this->val[1]),
+                  saturate_cast<T2>(this->val[2]),
+                  saturate_cast<T2>(this->val[3]));
+}
+
+template<typename T> static inline Scalar_<T>& operator += (Scalar_<T>& a, const Scalar_<T>& b)
+{
+    a.val[0] = saturate_cast<T>(a.val[0] + b.val[0]);
+    a.val[1] = saturate_cast<T>(a.val[1] + b.val[1]);
+    a.val[2] = saturate_cast<T>(a.val[2] + b.val[2]);
+    a.val[3] = saturate_cast<T>(a.val[3] + b.val[3]);
+    return a;
+}
+
+template<typename T> static inline Scalar_<T>& operator -= (Scalar_<T>& a, const Scalar_<T>& b)
+{
+    a.val[0] = saturate_cast<T>(a.val[0] - b.val[0]);
+    a.val[1] = saturate_cast<T>(a.val[1] - b.val[1]);
+    a.val[2] = saturate_cast<T>(a.val[2] - b.val[2]);
+    a.val[3] = saturate_cast<T>(a.val[3] - b.val[3]);
+    return a;
+}
+
+template<typename T> static inline Scalar_<T>& operator *= ( Scalar_<T>& a, T v )
+{
+    a.val[0] = saturate_cast<T>(a.val[0] * v);
+    a.val[1] = saturate_cast<T>(a.val[1] * v);
+    a.val[2] = saturate_cast<T>(a.val[2] * v);
+    a.val[3] = saturate_cast<T>(a.val[3] * v);
+    return a;
+}
+
+template<typename T> inline Scalar_<T> Scalar_<T>::mul(const Scalar_<T>& t, double scale ) const
+{
+    return Scalar_<T>( saturate_cast<T>(this->val[0]*t.val[0]*scale),
+                       saturate_cast<T>(this->val[1]*t.val[1]*scale),
+                       saturate_cast<T>(this->val[2]*t.val[2]*scale),
+                       saturate_cast<T>(this->val[3]*t.val[3]*scale));
+}
+
+template<typename T> template<typename T2> inline void Scalar_<T>::convertTo(T2* buf, int cn, int unroll_to) const
+{
+    int i;
+    CV_Assert(cn <= 4);
+    for( i = 0; i < cn; i++ )
+        buf[i] = saturate_cast<T2>(this->val[i]);
+    for( ; i < unroll_to; i++ )
+        buf[i] = buf[i-cn];
+}    
+
+static inline void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0)
+{
+    int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
+    switch(depth)
+    {
+    case CV_8U:
+        s.convertTo((uchar*)buf, cn, unroll_to);
+        break;
+    case CV_8S:
+        s.convertTo((schar*)buf, cn, unroll_to);
+        break;
+    case CV_16U:
+        s.convertTo((ushort*)buf, cn, unroll_to);
+        break;
+    case CV_16S:
+        s.convertTo((short*)buf, cn, unroll_to);
+        break;
+    case CV_32S:
+        s.convertTo((int*)buf, cn, unroll_to);
+        break;
+    case CV_32F:
+        s.convertTo((float*)buf, cn, unroll_to);
+        break;
+    case CV_64F:
+        s.convertTo((double*)buf, cn, unroll_to);
+        break;
+    default:
+        CV_Error(CV_StsUnsupportedFormat,"");
+    }
+}
+    
+
+template<typename T> static inline Scalar_<T> operator + (const Scalar_<T>& a, const Scalar_<T>& b)
+{
+    return Scalar_<T>(saturate_cast<T>(a.val[0] + b.val[0]),
+                      saturate_cast<T>(a.val[1] + b.val[1]),
+                      saturate_cast<T>(a.val[2] + b.val[2]),
+                      saturate_cast<T>(a.val[3] + b.val[3]));
+}
+
+template<typename T> static inline Scalar_<T> operator - (const Scalar_<T>& a, const Scalar_<T>& b)
+{
+    return Scalar_<T>(saturate_cast<T>(a.val[0] - b.val[0]),
+                      saturate_cast<T>(a.val[1] - b.val[1]),
+                      saturate_cast<T>(a.val[2] - b.val[2]),
+                      saturate_cast<T>(a.val[3] - b.val[3]));
+}
+
+template<typename T> static inline Scalar_<T> operator * (const Scalar_<T>& a, T alpha)
+{
+    return Scalar_<T>(saturate_cast<T>(a.val[0] * alpha),
+                      saturate_cast<T>(a.val[1] * alpha),
+                      saturate_cast<T>(a.val[2] * alpha),
+                      saturate_cast<T>(a.val[3] * alpha));
+}
+
+template<typename T> static inline Scalar_<T> operator * (T alpha, const Scalar_<T>& a)
+{
+    return a*alpha;
+}
+
+template<typename T> static inline Scalar_<T> operator - (const Scalar_<T>& a)
+{
+    return Scalar_<T>(saturate_cast<T>(-a.val[0]), saturate_cast<T>(-a.val[1]),
+                      saturate_cast<T>(-a.val[2]), saturate_cast<T>(-a.val[3]));
+}
+
+//////////////////////////////// Range /////////////////////////////////
+
+inline Range::Range() : start(0), end(0) {}
+inline Range::Range(int _start, int _end) : start(_start), end(_end) {}
+inline int Range::size() const { return end - start; }
+inline bool Range::empty() const { return start == end; }
+inline Range Range::all() { return Range(INT_MIN, INT_MAX); }
+
+static inline bool operator == (const Range& r1, const Range& r2)
+{ return r1.start == r2.start && r1.end == r2.end; }
+
+static inline bool operator != (const Range& r1, const Range& r2)
+{ return !(r1 == r2); }
+
+static inline bool operator !(const Range& r)
+{ return r.start == r.end; }
+
+static inline Range operator & (const Range& r1, const Range& r2)
+{
+    Range r(std::max(r1.start, r2.start), std::min(r2.start, r2.end));
+    r.end = std::max(r.end, r.start);
+    return r;
+}
+
+static inline Range& operator &= (Range& r1, const Range& r2)
+{
+    r1 = r1 & r2;
+    return r1;
+}
+
+static inline Range operator + (const Range& r1, int delta)
+{
+    return Range(r1.start + delta, r1.end + delta);
+}
+
+static inline Range operator + (int delta, const Range& r1)
+{
+    return Range(r1.start + delta, r1.end + delta);
+}
+
+static inline Range operator - (const Range& r1, int delta)
+{
+    return r1 + (-delta);
+}
+
+
+template <typename T> inline Vector<T>::Vector() {};
+template <typename T> inline Vector<T>::Vector(size_t _size) { resize(_size); }
+template <typename T> inline Vector<T>::Vector(size_t _size, const T& val)
+{
+    resize(_size);
+    for(size_t i = 0; i < _size; i++)
+        hdr.data[i] = val;
+}
+template <typename T> inline Vector<T>::Vector(T* _data, size_t _size, bool _copyData)
+{ set(_data, _size, _copyData); }
+template <typename T> inline Vector<T>::Vector(const std::vector<T>& vec, bool _copyData)
+{ set(vec[0], vec.size(), _copyData); }
+template <typename T> inline Vector<T>::Vector(const Vector& d)
+{ *this = d; }
+template <typename T> inline Vector<T>::Vector(const Vector& d, const Range& r)
+{
+    if( r == Range::all() )
+        r = Range(0, d.size());
+    if( r.size() > 0 && r.start >= 0 && r.end <= d.size() )
+    {
+        if( d.hdr.refcount )
+            ++*d.hdr.refcount;
+        hdr.refcount = d.hdr.refcount;
+        hdr.datastart = d.hdr.datastart;
+        hdr.data = d.hdr.data + r.start;
+        hdr.capacity = hdr.size = r.size();
+    }
+}
+
+template <typename T> inline Vector<T>& Vector<T>::operator = (const Vector& d)
+{
+    if( this == &d )
+        return *this;
+    if( d.hdr.refcount )
+        ++*d.hdr.refcount;
+    release();
+    hdr = d.hdr;
+    return *this;
+}
+
+template <typename T> inline Vector<T>::~Vector() { release(); }
+template <typename T> inline Vector<T> Vector<T>::clone() const
+{
+    return Vector(hdr.data, hdr.size, true);
+}
+
+template <typename T> inline Vector<T>::operator T* () { return hdr.data; }
+template <typename T> inline Vector<T>::operator const T* () const { return hdr.data; }
+template <typename T> inline T& Vector<T>::operator [] (size_t i) { assert( i < size() ); return hdr.data[i]; }
+template <typename T> inline T Vector<T>::operator [] (size_t i) const { assert( i < size() ); return hdr.data[i]; }
+template <typename T> inline T& Vector<T>::operator [] (int i) { assert( (size_t)i < size() ); return hdr.data[i]; }
+template <typename T> inline T Vector<T>::operator [] (int i) const { assert( (size_t)i < size() ); return hdr.data[i]; }
+template <typename T> inline Vector<T> Vector<T>::operator() (const Range& r) const { return Vector(*this, r); }
+template <typename T> inline T& Vector<T>::back() { assert(!empty()); return hdr.data[hdr.size-1]; }
+template <typename T> inline T Vector<T>::back() const { assert(!empty()); return hdr.data[hdr.size-1]; }
+template <typename T> inline T& Vector<T>::front() { assert(!empty()); return hdr.data[0]; }
+template <typename T> inline T Vector<T>::front() const { assert(!empty()); return hdr.data[0]; }
+
+template <typename T> inline T* Vector<T>::begin() { return hdr.data; }
+template <typename T> inline T* Vector<T>::end() { return hdr.data + hdr.size; }
+template <typename T> inline const T* Vector<T>::begin() const { return hdr.data; }
+template <typename T> inline const T* Vector<T>::end() const { return hdr.data + hdr.size; }
+
+template <typename T> inline void Vector<T>::release()
+{
+    if( hdr.refcount && --*hdr.refcount == 0 )
+        fastFree_<T>(hdr.datastart, hdr.capacity);
+    hdr = Hdr();
+}
+
+template <typename T> inline void Vector<T>::set(T* _data, size_t _size, bool _copyData)
+{
+    if( !_copyData )
+    {
+        release();
+        hdr.data = hdr.datastart = _data;
+        hdr.size = hdr.capacity = _size;
+        hdr.refcount = 0;
+    }
+    else
+    {
+        reserve(_size);
+        for( size_t i = 0; i < _size; i++ )
+            hdr.data[i] = _data[i];
+        hdr.size = _size;
+    }
+}
+
+template <typename T> inline void Vector<T>::reserve(size_t newCapacity)
+{
+    T* newData;
+    int* newRefcount;
+    size_t i, oldSize = hdr.size;
+    if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity )
+        return;
+    newCapacity = std::max(newCapacity, oldSize);
+    size_t datasize = alignSize(newCapacity*sizeof(T), (size_t)sizeof(*newRefcount));
+    newData = (T*)fastMalloc(datasize + sizeof(*newRefcount));
+    for( i = 0; i < newCapacity; i++ )
+        ::new(newData + i) T();
+    newRefcount = (int*)((uchar*)newData + datasize);
+    *newRefcount = 1;
+    for( i = 0; i < oldSize; i++ )
+        newData[i] = hdr.data[i];
+    release();
+    hdr.data = hdr.datastart = newData;
+    hdr.capacity = newCapacity;
+    hdr.size = oldSize;
+    hdr.refcount = newRefcount;
+}
+
+template <typename T> inline void Vector<T>::resize(size_t newSize)
+{
+    size_t i;
+    newSize = std::max(newSize, (size_t)0);
+    if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize )
+        return;
+    reserve(newSize);
+    for( i = hdr.size; i < newSize; i++ )
+        hdr.data[i] = T();
+    hdr.size = newSize;
+}
+
+template <typename T> inline Vector<T>& Vector<T>::push_back(const T& elem)
+{
+    if( hdr.size == hdr.capacity )
+        reserve( std::max((size_t)8, hdr.capacity*3/2) );
+    hdr.data[hdr.size++] = elem;
+    return *this;
+}
+template <typename T> inline Vector<T>& Vector<T>::pop_back()
+{
+    if( hdr.size > 0 )
+        --hdr.size;
+    return *this;
+}
+
+template <typename T> inline size_t Vector<T>::size() const { return hdr.size; }
+template <typename T> inline size_t Vector<T>::capacity() const { return hdr.capacity; }
+template <typename T> inline bool Vector<T>::empty() const { return hdr.size == 0; }
+template <typename T> inline void Vector<T>::clear() { resize(0); }
+
+//////////////////////////////// Mat ////////////////////////////////
+
+inline Mat::Mat()
+    : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) {}
+    
+inline Mat::Mat(int _rows, int _cols, int _type)
+    : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
+{
+    if( _rows > 0 && _cols > 0 )
+        create( _rows, _cols, _type );
+}
+
+inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
+    : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
+    datastart(0), dataend(0)
+{
+    create(_rows, _cols, _type);
+    *this = _s;
+}
+
+inline Mat::Mat(Size _size, int _type)
+    : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
+    datastart(0), dataend(0)
+{
+    if( _size.height > 0 && _size.width > 0 )
+        create( _size.height, _size.width, _type );
+}
+
+inline Mat::Mat(const Mat& m)
+    : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data),
+    refcount(m.refcount), datastart(m.datastart), dataend(m.dataend) 
+{
+    if( refcount )
+        ++*refcount;
+}
+
+inline Mat::Mat(int _rows, int _cols, int _type, void* _data, int _step)
+    : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_rows), cols(_cols),
+    step(_step), data((uchar*)_data), refcount(0),
+    datastart((uchar*)_data), dataend((uchar*)_data)
+{
+    int minstep = cols*elemSize();
+    if( step == AUTO_STEP )
+    {
+        step = minstep;
+        flags |= CONTINUOUS_FLAG;
+    }
+    else
+    {
+        if( rows == 1 ) step = minstep;
+        assert( step >= minstep );
+        flags |= step == minstep ? CONTINUOUS_FLAG : 0;
+    }
+    dataend += (step-1)*rows + minstep;
+}
+
+inline Mat::Mat(Size _size, int _type, void* _data, int _step)
+    : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_size.height), cols(_size.width),
+    step(_step), data((uchar*)_data), refcount(0),
+    datastart((uchar*)_data), dataend((uchar*)_data)
+{
+    int minstep = cols*elemSize();
+    if( step == AUTO_STEP )
+    {
+        step = minstep;
+        flags |= CONTINUOUS_FLAG;
+    }
+    else
+    {
+        if( rows == 1 ) step = minstep;
+        assert( step >= minstep );
+        flags |= step == minstep ? CONTINUOUS_FLAG : 0;
+    }
+    dataend += (step-1)*rows + minstep;
+}
+
+inline Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
+{
+    flags = m.flags;
+    step = m.step; refcount = m.refcount;
+    data = m.data; datastart = m.datastart; dataend = m.dataend;
+
+    if( rowRange == Range::all() )
+        rows = m.rows;
+    else
+    {
+        rows = rowRange.size();
+        data += step*rowRange.start;
+    }
+
+    if( colRange == Range::all() )
+        cols = m.cols;
+    else
+    {
+        cols = colRange.size();
+        data += colRange.start*elemSize();
+        flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
+    }
+
+    if( refcount )
+        ++*refcount;
+    if( rows <= 0 || cols <= 0 )
+        rows = cols = 0;
+}
+
+inline Mat::Mat(const Mat& m, const Rect& roi)
+    : flags(m.flags), rows(roi.height), cols(roi.width),
+    step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
+    datastart(m.datastart), dataend(m.dataend)
+{
+    flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
+    data += roi.x*elemSize();
+    assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
+        0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
+    if( refcount )
+        ++*refcount;
+    if( rows <= 0 || cols <= 0 )
+        rows = cols = 0;
+}
+
+inline Mat::Mat(const CvMat* m, bool copyData)
+    : flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
+    rows(m->rows), cols(m->cols), step(m->step), data(m->data.ptr), refcount(0),
+    datastart(m->data.ptr), dataend(m->data.ptr)
+{
+    if( step == 0 )
+        step = cols*elemSize();
+    dataend += step*rows;
+    if( copyData )
+    {
+        refcount = 0;
+        data = datastart = dataend = 0;
+        Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this);
+    }
+}
+
+inline Mat::~Mat()
+{
+    release();
+}
+
+inline Mat& Mat::operator = (const Mat& m)
+{
+    if( this != &m )
+    {
+        if( m.refcount )
+            ++*m.refcount;
+        release();
+        flags = m.flags;
+        rows = m.rows; cols = m.cols;
+        step = m.step; data = m.data;
+        datastart = m.datastart; dataend = m.dataend;
+        refcount = m.refcount;
+    }
+    return *this;
+}
+
+inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
+inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
+inline Mat Mat::rowRange(int startrow, int endrow) const
+    { return Mat(*this, Range(startrow, endrow), Range::all()); }
+inline Mat Mat::rowRange(const Range& r) const
+    { return Mat(*this, r, Range::all()); }
+inline Mat Mat::colRange(int startcol, int endcol) const
+    { return Mat(*this, Range::all(), Range(startcol, endcol)); }
+inline Mat Mat::colRange(const Range& r) const
+    { return Mat(*this, Range::all(), r); }
+
+inline Mat Mat::diag(int d) const
+{
+    Mat m = *this;
+    int esz = elemSize();
+    int len;
+    
+    if( d >= 0 )
+    {
+        len = std::min(cols - d, rows);
+        m.data += esz*d;
+    }
+    else
+    {
+        len = std::min(rows + d, cols);
+        m.data -= step*d;
+    }
+    if( len <= 0 )
+    {
+        assert(0);
+        return Mat();
+    }
+    m.rows = len;
+    m.cols = 1;
+    m.step += esz;
+    if( m.rows > 1 )
+        m.flags &= ~CONTINUOUS_FLAG;
+    else
+        m.flags |= CONTINUOUS_FLAG;
+    return m;
+}
+
+inline Mat Mat::diag(const Mat& d)
+{
+    Mat m(d.rows, d.rows, d.type(), Scalar(0)), md = m.diag();
+    d.copyTo(md);
+    return m;
+}
+
+inline Mat Mat::clone() const
+{
+    Mat m;
+    copyTo(m);
+    return m;
+}
+
+inline void Mat::assignTo( Mat& m, int type ) const
+{
+    if( type < 0 )
+        m = *this;
+    else
+        convertTo(m, type);
+}
+
+inline void Mat::create(int _rows, int _cols, int _type)
+{
+    _type &= TYPE_MASK;
+    if( rows == _rows && cols == _cols && type() == _type )
+        return;
+    if( data )
+        release();
+    assert( _rows >= 0 && _cols >= 0 );
+    if( _rows > 0 && _cols > 0 )
+    {
+        flags = MAGIC_VAL + CONTINUOUS_FLAG + _type;
+        rows = _rows;
+        cols = _cols;
+        step = elemSize()*cols;
+        size_t nettosize = (size_t)step*rows;
+        size_t datasize = alignSize(nettosize, (int)sizeof(*refcount));
+        datastart = data = (uchar*)fastMalloc(datasize + sizeof(*refcount));
+        dataend = data + nettosize;
+        refcount = (int*)(data + datasize);
+        *refcount = 1;
+    }
+}
+
+inline void Mat::create(Size _size, int _type)
+{
+    create(_size.height, _size.width, _type);
+}
+
+inline void Mat::release()
+{
+    if( refcount && --*refcount == 0 )
+        fastFree(datastart);
+    data = datastart = dataend = 0;
+    step = rows = cols = 0;
+    refcount = 0;
+}
+
+inline void Mat::locateROI( int& drow, int& allrows, int& dcol, int& allcols )
+{
+    int esz = elemSize(), minstep;
+    ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
+    assert( step > 0 );
+    if( delta1 == 0 )
+        drow = dcol = 0;
+    else
+    {
+        drow = (int)(delta1/step);
+        dcol = (int)((delta1 - step*drow)/esz);
+        assert( data == datastart + drow*step + dcol );
+    }
+    minstep = (dcol + cols)*esz;
+    allrows = (int)((delta2 - minstep)/step + 1);
+    allrows = MAX(allrows, drow + rows);
+    allcols = (delta2 - step*(allrows-1))/esz;
+    allcols = MAX(allcols, dcol + cols);
+}
+
+inline Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
+{
+    int drow, allrows, dcol, allcols;
+    int esz = elemSize();
+    locateROI( drow, allrows, dcol, allcols );
+    int row1 = std::max(drow - dtop, 0), row2 = std::min(drow + rows + dbottom, allrows);
+    int col1 = std::max(dcol - dleft, 0), col2 = std::min(dcol + cols + dright, allcols);
+    data += (row1 - drow)*step + (col1 - dcol)*esz;
+    rows = row2 - row1; cols = col2 - col1;
+    if( esz*cols == step )
+        flags |= CONTINUOUS_FLAG;
+    else
+        flags &= ~CONTINUOUS_FLAG;
+    return *this;
+}
+
+inline Mat Mat::operator()( Range rowRange, Range colRange ) const
+{
+    return Mat(*this, rowRange, colRange);
+}
+
+inline Mat Mat::operator()( const Rect& roi ) const
+{ return Mat(*this, roi); }
+
+inline Mat::operator CvMat() const
+{
+    CvMat m = cvMat(rows, cols, type(), data);
+    m.step = step;
+    m.type |= flags & CONTINUOUS_FLAG;
+    return m;
+}
+
+inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
+inline int Mat::elemSize() const { return CV_ELEM_SIZE(flags); }
+inline int Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
+inline int Mat::type() const { return CV_MAT_TYPE(flags); }
+inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
+inline int Mat::channels() const { return CV_MAT_CN(flags); }
+inline int Mat::step1() const { return step/elemSize1(); }
+inline Size Mat::size() const { return Size(cols, rows); }
+
+inline uchar* Mat::ptr(int y)
+{
+    assert( (unsigned)y < (unsigned)rows );
+    return data + step*y;
+}
+
+inline const uchar* Mat::ptr(int y) const
+{
+    assert( (unsigned)y < (unsigned)rows );
+    return data + step*y;
+}
+
+static inline void swap( Mat& a, Mat& b )
+{
+    std::swap( a.flags, b.flags );
+    std::swap( a.rows, b.rows ); std::swap( a.cols, b.cols );
+    std::swap( a.step, b.step ); std::swap( a.data, b.data );
+    std::swap( a.datastart, b.datastart );
+    std::swap( a.dataend, b.dataend );
+    std::swap( a.refcount, b.refcount );
+}
+
+// Multiply-with-Carry RNG
+inline RNG::RNG() { state = 0xffffffff; }
+inline RNG::RNG(unsigned seed) { state = seed ? seed : 0xffffffff; }
+inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
+inline unsigned RNG::next()
+{
+    state = (uint64)(unsigned)state*A + (unsigned)(state >> 32);
+    return (unsigned)state;
+}
+
+inline RNG::operator uchar() { return (uchar)next(); }
+inline RNG::operator schar() { return (schar)next(); }
+inline RNG::operator ushort() { return (ushort)next(); }
+inline RNG::operator short() { return (short)next(); }
+inline RNG::operator unsigned() { return next(); }
+inline RNG::operator int() { return (int)next(); }
+// * (2^32-1)^-1
+inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
+inline RNG::operator double()
+{
+    unsigned t = next();
+    return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20;
+}
+
+inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {}
+inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
+    : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
+
+inline SVD::SVD() {}
+inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
+inline void SVD::solveZ( const Mat& m, Mat& dst )
+{
+    SVD svd(m);
+    svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
+}
+
+inline uchar* LineIterator::operator *() { return ptr; }
+inline LineIterator& LineIterator::operator ++()
+{
+    int mask = err < 0 ? -1 : 0;
+    err += minusDelta + (plusDelta & mask);
+    ptr += minusStep + (plusStep & mask);
+    return *this;
+}
+inline LineIterator LineIterator::operator ++(int)
+{
+    LineIterator it = *this;
+    ++(*this);
+    return it;
+}
+
+///////////////////////////////// Mat_<T> ////////////////////////////////////
+
+template<typename T> inline Mat_<T>::Mat_() :
+Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<T>::type; }
+template<typename T> inline Mat_<T>::Mat_(int _rows, int _cols) :
+    Mat(_rows, _cols, DataType<T>::type) {}
+
+template<typename T> inline Mat_<T>::Mat_(int _rows, int _cols, const T& value) :
+    Mat(_rows, _cols, DataType<T>::type) { *this = value; }
+
+template<typename T> inline Mat_<T>::Mat_(const Mat& m) : Mat()
+{ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<T>::type; *this = m; }
+
+template<typename T> inline Mat_<T>::Mat_(const Mat_& m) : Mat(m) {}
+
+template<typename T> inline Mat_<T>::Mat_(int _rows, int _cols, T* _data, int _step)
+    : Mat(_rows, _cols, DataType<T>::type, _data, _step) {}
+
+template<typename T> inline Mat_<T>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
+    : Mat(m, rowRange, colRange) {}
+
+template<typename T> inline Mat_<T>::Mat_(const Mat_& m, const Rect& roi)
+    : Mat(m, roi) {}
+
+template<typename T> inline Mat_<T>::~Mat_() { release(); }
+
+template<typename T> inline Mat_<T>& Mat_<T>::operator = (const Mat& m)
+{
+    if( DataType<T>::type == m.type() )
+    {
+        Mat::operator = (m);
+        return *this;
+    }
+    if( DataType<T>::depth == m.depth() )
+    {
+        return (*this = m.reshape(DataType<T>::channels));
+    }
+    assert(DataType<T>::channels == m.channels());
+    m.convertTo(*this, type());
+    return *this;
+}
+
+template<typename T> inline Mat_<T>& Mat_<T>::operator = (const Mat_& m)
+{
+    Mat::operator=(m);
+    return *this;
+}
+
+template<typename T> inline Mat_<T>& Mat_<T>::operator = (const T& s)
+{
+    Mat::operator=(Scalar(s));
+    return *this;
+}
+
+template<typename T> inline Mat_<T>& Mat_<T>::create(int _rows, int _cols)
+{
+    Mat::create(_rows, _cols, DataType<T>::type);
+    return *this;
+}
+
+template<typename T> inline Mat_<T>& Mat_<T>::create(Size _size)
+{
+    Mat::create(_size, DataType<T>::type);
+    return *this;
+}
+
+template<typename T> inline Mat_<T> Mat_<T>::cross(const Mat_& m) const
+{ return Mat_<T>(Mat::cross(m)); }
+
+template<typename T> template<typename T2> inline Mat_<T>::operator Mat_<T2>() const
+{ return Mat_<T2>(*this); }
+
+template<typename T> inline Mat_<T> Mat_<T>::row(int y) const
+{ return Mat_(*this, Range(y, y+1), Range::all()); }
+template<typename T> inline Mat_<T> Mat_<T>::col(int x) const
+{ return Mat_(*this, Range::all(), Range(x, x+1)); }
+template<typename T> inline Mat_<T> Mat_<T>::diag(int d) const
+{ return Mat_(Mat::diag(d)); }
+template<typename T> inline Mat_<T> Mat_<T>::clone() const
+{ return Mat_(Mat::clone()); }
+
+template<typename T> inline int Mat_<T>::elemSize() const
+{
+    assert( Mat::elemSize() == (int)sizeof(T) );
+    return sizeof(T);
+}
+
+template<typename T> inline int Mat_<T>::elemSize1() const
+{
+    assert( Mat::elemSize1() == (int)sizeof(T)/DataType<T>::channels );
+    return sizeof(T)/DataType<T>::channels;
+}
+template<typename T> inline int Mat_<T>::type() const
+{
+    assert( Mat::type() == DataType<T>::type );
+    return DataType<T>::type;
+}
+template<typename T> inline int Mat_<T>::depth() const
+{
+    assert( Mat::depth() == DataType<T>::depth );
+    return DataType<T>::depth;
+}
+template<typename T> inline int Mat_<T>::channels() const
+{
+    assert( Mat::channels() == DataType<T>::channels );
+    return DataType<T>::channels;
+}
+template<typename T> inline int Mat_<T>::stepT() const { return step/elemSize(); }
+template<typename T> inline int Mat_<T>::step1() const { return step/elemSize1(); }
+
+template<typename T> inline Mat_<T> Mat_<T>::reshape(int _rows) const
+{ return Mat_<T>(Mat::reshape(0,_rows)); }
+
+template<typename T> inline Mat_<T>& Mat_<T>::adjustROI( int dtop, int dbottom, int dleft, int dright )
+{ return (Mat_<T>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));  }
+
+template<typename T> inline Mat_<T> Mat_<T>::operator()( const Range& rowRange, const Range& colRange ) const
+{ return Mat_<T>(*this, rowRange, colRange); }
+
+template<typename T> inline Mat_<T> Mat_<T>::operator()( const Rect& roi ) const
+{ return Mat_<T>(roi); }
+
+template<typename T> inline T* Mat_<T>::operator [](int y)
+{ return (T*)ptr(y); }
+template<typename T> inline const T* Mat_<T>::operator [](int y) const
+{ return (const T*)ptr(y); }
+
+template<typename T> inline T& Mat_<T>::operator ()(int row, int col)
+{
+    assert( (unsigned)col < (unsigned)cols );
+    return (*this)[row][col];
+}
+
+template<typename T> inline T Mat_<T>::operator ()(int row, int col) const
+{
+    assert( (unsigned)col < (unsigned)cols );
+    return (*this)[row][col];
+}
+
+
+template<typename T1, typename T2, typename Op> inline void
+process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
+{
+    int y, x, rows = m1.rows, cols = m1.cols;
+    int c1 = m1.channels(), c2 = m2.channels();
+
+    assert( m1.size() == m2.size() );
+
+    for( y = 0; y < rows; y++ )
+    {
+        const T1* src = m1[y];
+        T2* dst = m2[y];
+
+        for( x = 0; x < cols; x++ )
+            dst[x] = op(src[x]);
+    }
+}
+
+template<typename T1, typename T2, typename T3, typename Op> inline void
+process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
+{
+    int y, x, rows = m1.rows, cols = m1.cols;
+
+    assert( m1.size() == m2.size() );
+
+    for( y = 0; y < rows; y++ )
+    {
+        const T1* src1 = m1[y];
+        const T2* src2 = m2[y];
+        T3* dst = m3[y];
+
+        for( x = 0; x < cols; x++ )
+            dst[x] = op( src1[x], src2[x] );
+    }
+}
+
+struct CV_EXPORTS MatExpr_Base
+{
+    MatExpr_Base() {}
+    virtual ~MatExpr_Base() {}
+    virtual void assignTo(Mat& m, int type=-1) const = 0;
+};
+
+template<typename E, typename M> struct CV_EXPORTS MatExpr_ : MatExpr_Base
+{
+    MatExpr_(const E& _e) : e(_e) {}
+    ~MatExpr_() {}
+    operator M() const { return (M)e; }
+    void assignTo(Mat& m, int type=-1) const { e.assignTo(m, type); }
+    
+    M row(int y) const { return ((M)e).row(y); }
+    M col(int x) const { return ((M)e).col(x); }
+    M diag(int d=0) const { return ((M)e).diag(d); }
+
+    M operator()( const Range& rowRange, const Range& colRange ) const
+    { return ((M)e)(rowRange, colRange); }
+    M operator()( const Rect& roi ) const { return ((M)e)(roi); }
+
+    M cross(const M& m) const { return ((M)e).cross(m); }
+    double dot(const M& m) const { return ((M)e).dot(m); }
+
+    MatExpr_<MatExpr_Op2_<M, double, M, MatOp_T_<Mat> >, M> t() const
+    { return ((M)e).t(); }
+    MatExpr_<MatExpr_Op2_<M, int, M, MatOp_T_<Mat> >, M> inv(int method=DECOMP_LU) const
+    { return ((M)e).inv(method); }
+
+    MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+    mul(const M& m, double scale=1) const
+    { return ((M)e).mul(m, scale); }
+    template<typename A> MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M >
+    mul(const MatExpr_<A, M>& m, double scale=1) const
+    { return ((M)e).mul(m, scale); }
+
+    E e;
+};
+
+
+inline Mat::Mat(const MatExpr_Base& expr)
+ : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
+{
+    expr.assignTo(*this);
+}
+
+inline Mat& Mat::operator = (const MatExpr_Base& expr)
+{
+    expr.assignTo(*this);
+    return *this;
+}
+
+template<typename T> inline Mat_<T>::Mat_(const MatExpr_Base& e) : Mat()
+{
+    e.assignTo(*this, DataType<T>::type);
+}
+
+template<typename T> inline Mat_<T>& Mat_<T>::operator = (const MatExpr_Base& e)
+{
+    e.assignTo(*this, DataType<T>::type);
+    return *this;
+}
+
+template<typename T> inline Mat_<T>::operator MatExpr_<Mat_<T>, Mat_<T> >() const
+{ return MatExpr_<Mat_<T>, Mat_<T> >(*this); }
+
+inline Mat::operator MatExpr_<Mat, Mat>() const
+{ return MatExpr_<Mat, Mat>(*this); }
+
+template<typename M> struct CV_EXPORTS MatOp_Sub_
+{
+    MatOp_Sub_() {}
+    
+    static void apply(const M& a, const M& b, M& c, int type=-1)
+    {
+        if( type == a.type() || type < 0 )
+        {
+            subtract( a, b, c );
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_Scale_
+{
+    MatOp_Scale_() {}
+    
+    static void apply(const M& a, double alpha, M& c, int type=-1)
+    {
+        a.convertTo(c, type, alpha, 0);
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_ScaleAddS_
+{
+    MatOp_ScaleAddS_() {}
+    
+    static void apply(const M& a, double alpha, double beta, M& c, int type=-1)
+    {
+        a.convertTo(c, type, alpha, beta);
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_AddS_
+{
+    MatOp_AddS_() {}
+    
+    static void apply(const M& a, const Scalar& s, M& c, int type=-1)
+    {
+        if( type == a.type() || type < 0 )
+        {
+            add(a, s, c);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, s, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_AddEx_
+{
+    MatOp_AddEx_() {}
+    
+    static void apply(const M& a, double alpha, const M& b,
+                      double beta, double gamma, M& c, int type=-1)
+    {
+        if( type == a.type() || type < 0 )
+        {
+            addWeighted(a, alpha, b, beta, gamma, c);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, alpha, b, beta, gamma, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_Bin_
+{
+    MatOp_Bin_() {}
+
+    static void apply(const M& a, const M& b, int _op, M& c, int type=-1)
+    {
+        char op = (char)_op;
+        if( type == a.type() || type < 0 )
+        {
+            if( op == '&' )
+                bitwise_and( a, b, c );
+            else if( op == '|' )
+                bitwise_or( a, b, c );
+            else if( op == '^' )
+                bitwise_xor( a, b, c );
+            else if( op == 'm' )
+                min( a, b, c );
+            else if( op == 'M' )
+                max( a, b, c );
+            else if( op == 'a' )
+                absdiff( a, b, c );
+            else
+                assert(0);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, op, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_BinS_
+{
+    MatOp_BinS_() {}
+
+    static void apply(const M& a, const Scalar& s, int _op, M& c, int type=-1)
+    {
+        char op = (char)_op;
+        if( type == a.type() || type < 0 )
+        {
+            if( op == '&' )
+                bitwise_and( a, s, c );
+            else if( op == '|' )
+                bitwise_or( a, s, c );
+            else if( op == '^' )
+                bitwise_xor( a, s, c );
+            else if( op == 'm' )
+                min( a, s[0], c );
+            else if( op == 'M' )
+                max( a, s[0], c );
+            else if( op == 'a' )
+                absdiff( a, s, c );
+            else if( op == '~' )
+                bitwise_not( a, c );
+            else
+                assert(0);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, s, op, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_T_
+{
+    MatOp_T_() {}
+    
+    static void apply(const M& a, double scale, M& c, int type=-1)
+    {
+        if( type == a.type() || type < 0 )
+        {
+            transpose(a, c);
+            if( fabs(scale - 1) > DBL_EPSILON )
+                c.convertTo(c, -1, scale, 0);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, scale, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+
+template<typename M> struct CV_EXPORTS MatOp_MatMul_
+{
+    MatOp_MatMul_() {}
+    
+    static void apply(const M& a, const M& b, double scale, int flags, M& c, int type=-1)
+    {
+        if( type == a.type() || type < 0 )
+        {
+            gemm(a, b, scale, Mat(), 0, c, flags);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, scale, flags, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+
+template<typename M> struct CV_EXPORTS MatOp_MatMulAdd_
+{
+    MatOp_MatMulAdd_() {}
+    
+    static void apply(const M& a, const M& b, double alpha,
+        const M& c, double beta, int flags, M& d, int type=-1)
+    {
+        if( type == a.type() || type < 0 )
+        {
+            gemm(a, b, alpha, c, beta, d, flags);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, alpha, c, beta, flags, temp);
+            temp.convertTo(d, type);
+        }
+    }
+};
+
+
+template<typename M> struct CV_EXPORTS MatOp_Cmp_
+{
+    MatOp_Cmp_() {}
+    
+    static void apply(const M& a, const M& b, int op, M& c, int type=-1)
+    {
+        if( type == CV_8UC1 || type == -1 )
+        {
+            compare(a, b, c, op);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, op, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_CmpS_
+{
+    MatOp_CmpS_() {}
+    
+    static void apply(const M& a, double alpha, int op, M& c, int type=-1)
+    {
+        if( type == CV_8UC1 || type == -1 )
+        {
+            compare(a, alpha, c, op);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, alpha, op, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_MulDiv_
+{
+    MatOp_MulDiv_() {}
+    
+    static void apply(const M& a, const M& b, double alpha, char op, M& c, int type=-1)
+    {
+        if( type == a.type() || type == -1 )
+        {
+            if( op == '*' )
+                multiply( a, b, c, alpha );
+            else
+                divide( a, b, c, alpha );
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, alpha, op, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_DivRS_
+{
+    MatOp_DivRS_() {}
+    
+    static void apply(const M& a, double alpha, M& c, int type=-1)
+    {
+        if( type == a.type() || type == -1 )
+        {
+            c.create(a.rows, a.cols, a.type());
+            divide( alpha, a, c );
+        }
+        else
+        {
+            Mat temp;
+            apply(a, alpha, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+
+template<typename M> struct CV_EXPORTS MatOp_Inv_
+{
+    MatOp_Inv_() {}
+    
+    static void apply(const M& a, int method, M& c, int type=-1)
+    {
+        if( type == a.type() || type == -1 )
+        {
+            invert(a, c, method);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, method, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+
+template<typename M> struct CV_EXPORTS MatOp_Solve_
+{
+    MatOp_Solve_() {}
+    
+    static void apply(const M& a, const M& b, int method, M& c, int type=-1)
+    {
+        if( type == a.type() || type == -1 )
+        {
+            solve(a, b, c, method);
+        }
+        else
+        {
+            Mat temp;
+            apply(a, b, method, temp);
+            temp.convertTo(c, type);
+        }
+    }
+};
+
+template<typename M> struct CV_EXPORTS MatOp_Set_
+{
+    MatOp_Set_() {}
+
+    static void apply(Size size, int type0, const Scalar& s, int mtype, M& c, int type=-1)
+    {
+        if( type < 0 )
+            type = type0;
+        c.create(size.height, size.width, type);
+        if( mtype == 0 )
+            c = Scalar(0);
+        else if( mtype == 1 )
+            c = s;
+        else if( mtype == 2 )
+            setIdentity(c, s);
+    }
+};
+
+template<typename A1, typename M, typename Op>
+struct CV_EXPORTS MatExpr_Op1_
+{
+    MatExpr_Op1_(const A1& _a1) : a1(_a1) {}
+    void assignTo(Mat& m, int type=-1) const { Op::apply(a1, (M&)m, type); }
+    operator M() const { M result; assignTo(result); return result; }
+
+    A1 a1;
+};
+
+template<typename A1, typename A2, typename M, typename Op>
+struct CV_EXPORTS MatExpr_Op2_
+{
+    MatExpr_Op2_(const A1& _a1, const A2& _a2) : a1(_a1), a2(_a2) {}
+    void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, (M&)m, type); }
+    operator M() const { M result; assignTo(result); return result; }
+
+    A1 a1; A2 a2;
+};
+
+template<typename A1, typename A2, typename A3, typename M, typename Op>
+struct CV_EXPORTS MatExpr_Op3_
+{
+    MatExpr_Op3_(const A1& _a1, const A2& _a2, const A3& _a3) : a1(_a1), a2(_a2), a3(_a3) {}
+    void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, (M&)m, type); }
+    operator M() const { M result; assignTo(result); return result; }
+
+    A1 a1; A2 a2; A3 a3;
+};
+
+template<typename A1, typename A2, typename A3, typename A4, typename M, typename Op>
+struct CV_EXPORTS MatExpr_Op4_
+{
+    MatExpr_Op4_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4)
+        : a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
+    void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, (M&)m, type); }
+    operator M() const { M result; assignTo(result); return result; }
+
+    A1 a1; A2 a2; A3 a3; A4 a4;
+};
+
+template<typename A1, typename A2, typename A3, typename A4, typename A5, typename M, typename Op>
+struct CV_EXPORTS MatExpr_Op5_
+{
+    MatExpr_Op5_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4, const A5& _a5)
+        : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5) {}
+    void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, (M&)m, type); }
+    operator M() const { M result; assignTo(result); return result; }
+
+    A1 a1; A2 a2; A3 a3; A4 a4; A5 a5;
+};
+
+template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename M, typename Op>
+struct CV_EXPORTS MatExpr_Op6_
+{
+    MatExpr_Op6_(const A1& _a1, const A2& _a2, const A3& _a3,
+                    const A4& _a4, const A5& _a5, const A6& _a6)
+        : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5), a6(_a6) {}
+    void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, a6, (M&)m, type); }
+    operator M() const { M result; assignTo(result); return result; }
+
+    A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6;
+};
+
+///////////////////////////////// Arithmetical Operations ///////////////////////////////////
+
+// A + B
+static inline MatExpr_<MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> >, Mat>
+operator + (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, 1, b, 1, 0));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op5_<Mat_<T>, double, Mat_<T>,
+double, double, Mat_<T>, MatOp_AddEx_<Mat> >, Mat_<T> >
+operator + (const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op5_<Mat_<T>, double, Mat_<T>, double, double, Mat_<T>, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, 1, b, 1, 0));
+}
+
+// E1 + E2
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
+{
+    typedef MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, (M)b, 1, 0));
+}
+
+// A - B
+static inline MatExpr_<MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> >, Mat>
+operator - (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, Mat_<T>, Mat_<T>, MatOp_Sub_<Mat> >, Mat_<T> >
+operator - (const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op2_<Mat_<T>, Mat_<T>, Mat_<T>, MatOp_Sub_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, b));
+}
+
+// E1 - E2
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> >, M>
+operator - (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
+{
+    typedef MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b));
+}
+
+// -(E1 - E2)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a2, a.e.a1));
+}
+
+// (A - B)*alpha
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a,
+            double alpha)
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, alpha, a.e.a2, -alpha, 0));
+}
+
+// alpha*(A - B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator * (double alpha,
+            const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
+{ return a*alpha; }
+
+
+// A*alpha
+static inline
+MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
+operator * (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
+}
+
+// A*alpha
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_Scale_<Mat> >, Mat_<T> >
+operator * (const Mat_<T>& a, double alpha)
+{
+    typedef MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_Scale_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, alpha));
+}
+
+// alpha*A
+static inline
+MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
+operator * (double alpha, const Mat& a)
+{ return a*alpha; }
+
+// alpha*A
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_Scale_<Mat> >, Mat_<T> >
+operator * (double alpha, const Mat_<T>& a)
+{ return a*alpha; }
+
+// A/alpha
+static inline
+MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
+operator / (const Mat& a, double alpha)
+{ return a*(1./alpha); }
+
+// A/alpha
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_Scale_<Mat> >, Mat_<T> >
+operator / (const Mat_<T>& a, double alpha)
+{ return a*(1./alpha); }
+
+// -A
+static inline
+MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
+operator - (const Mat& a)
+{ return a*(-1); }
+
+// -A
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_Scale_<Mat> >, Mat_<T> >
+operator - (const Mat_<T>& a)
+{ return a*(-1); }
+
+// E*alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
+operator * (const MatExpr_<A, M>& a, double alpha)
+{
+    typedef MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
+}
+
+// alpha*E
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
+operator * (double alpha, const MatExpr_<A, M>& a)
+{ return a*alpha; }
+
+// E/alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
+operator / (const MatExpr_<A, M>& a, double alpha)
+{ return a*(1./alpha); }
+
+// (E*alpha)*beta ~ E*(alpha*beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            double beta)
+{ return a.e.a1*(a.e.a2*beta); }
+
+// beta*(E*alpha) ~ E*(alpha*beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
+operator * (double beta,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return a.e.a1*(a.e.a2*beta); }
+
+// (E*alpha)/beta ~ E*(alpha/beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
+operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            double beta)
+{ return a.e.a1*(a.e.a2/beta); }
+
+// -E ~ E*(-1)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<MatExpr_<A, M>, double, M, MatOp_Scale_<Mat> >, M>
+operator - (const MatExpr_<A, M>& a)
+{ return a*(-1); }
+
+// -(E*alpha) ~ E*(-alpha)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return a.e.a1*(-a.e.a2); }
+
+// A + alpha
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, double, double, Mat_<T>, MatOp_ScaleAddS_<Mat> >, Mat_<T> >
+operator + (const Mat_<T>& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat_<T>, double, double, Mat_<T>,
+        MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, 1, alpha));
+}
+
+// A + alpha
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, Scalar, Mat_<T>, MatOp_AddS_<Mat> >, Mat_<T> >
+operator + (const Mat_<T>& a, const Scalar& alpha)
+{
+    typedef MatExpr_Op2_<Mat_<T>, Scalar, Mat_<T>,
+        MatOp_AddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, alpha));
+}
+
+// alpha + A
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, double, double, Mat_<T>, MatOp_ScaleAddS_<Mat> >, Mat_<T> >
+operator + (double alpha, const Mat_<T>& a)
+{ return a + alpha; }
+
+// alpha + A
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, Scalar, Mat_<T>, MatOp_AddS_<Mat> >, Mat_<T> >
+operator + (const Scalar& alpha, const Mat_<T>& a)
+{ return a + alpha; }
+
+// A - alpha
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, double, double, Mat_<T>, MatOp_ScaleAddS_<Mat> >, Mat_<T> >
+operator - (const Mat_<T>& a, double alpha)
+{ return a + (-alpha); }
+
+// A - alpha
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, Scalar, Mat_<T>, MatOp_AddS_<Mat> >, Mat_<T> >
+operator - (const Mat_<T>& a, const Scalar& alpha)
+{ return a + (-alpha); }
+
+// alpha - A
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, double, double, Mat_<T>, MatOp_ScaleAddS_<Mat> >, Mat_<T> >
+operator - (double alpha, const Mat_<T>& a)
+{
+    typedef MatExpr_Op3_<Mat_<T>, double, double, Mat_<T>,
+        MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, -1, alpha));
+}
+
+// E + alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator + (const MatExpr_<A, M>& a, double alpha)
+{
+    typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, alpha));
+}
+
+// E + alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
+operator + (const MatExpr_<A, M>& a, const Scalar& alpha)
+{
+    typedef MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
+}
+
+// alpha + E
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator + (double alpha, const MatExpr_<A, M>& a)
+{ return a + alpha; }
+
+// alpha + E
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
+operator + (const Scalar& alpha, const MatExpr_<A, M>& a)
+{ return a + alpha; }
+
+// E - alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (const MatExpr_<A, M>& a, double alpha)
+{ return a + (-alpha); }
+
+// E - alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
+operator - (const MatExpr_<A, M>& a, const Scalar& alpha)
+{ return a + (-alpha); }
+
+// alpha - E
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (double alpha, const MatExpr_<A, M>& a)
+{
+    typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, -1, alpha));
+}
+
+// E*alpha + beta
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            double beta)
+{
+    typedef MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, beta));
+}
+
+// beta + E*alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator + (double beta,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return a + beta; }
+
+// E*alpha - beta
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            double beta)
+{ return a + (-beta); }
+
+// beta - E*alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (double beta,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return (a.e.a1*(-a.e.a2)) + beta; }
+
+// (E*alpha + gamma) + beta ~ E*alpha + (gamma + beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            double beta)
+{ return a.e.a1*a.e.a2 + (a.e.a3 + beta); }
+
+// beta + (E*alpha + gamma)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator + (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return a + beta; }
+
+// (E*alpha + gamma) - beta
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            double beta)
+{ return a + (-beta); }
+
+// beta - (E*alpha + gamma)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return a.e.a1*(-a.e.a2) + (beta - a.e.a3); }
+
+// (E*alpha + gamma)*beta
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            double beta)
+{ return a.e.a1*(a.e.a2*beta) + (a.e.a3*beta); }
+
+// beta*(E*alpha + gamma)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator * (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return a*beta; }
+
+// -(E*alpha + beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return a*(-1); }
+
+// (A*u + B*v + w) + beta
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
+            double beta )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3, a.e.a4, a.e.a5 + beta));
+}
+
+// beta + (A*u + B*v + w)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (double beta,
+            const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
+{ return a + beta; }
+
+// (A*u + B*v + w) - beta
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
+            double beta)
+{ return a + (-beta); }
+
+// beta - (A*u + B*v + w)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (double beta,
+            const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, a.e.a3, -a.e.a4, -a.e.a5 + beta));
+}
+
+// (A*u + B*v + w)*beta
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
+            double beta )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1,
+        a.e.a2*beta, a.e.a3, a.e.a4*beta, a.e.a5*beta));
+}
+
+// beta*(A*u + B*v + w)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator * (double beta,
+            const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
+{ return a * beta; }
+
+// -(A*u + B*v + w)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
+{ return a*(-1); }
+
+// A*alpha + B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const M& b )
+{
+    typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, 0));
+}
+
+// B + A*alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const M& b,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return a + b; }
+
+// (A*alpha + beta) + B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const M& b )
+{
+    typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, a.e.a3));
+}
+
+// B + (A*alpha + beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const M& b,
+            const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return a + b; }
+
+
+// A*alpha + E
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const MatExpr_<B, M>& b )
+{ return a + (M)b; }
+
+// E + A*alpha
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<B, M>& b,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return a + (M)b; }
+
+// (A*alpha + beta) + E
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const MatExpr_<B, M>& b )
+{ return a + (M)b; }
+
+// E + (A*alpha + beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<B, M>& b,
+            const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return a + b; }
+
+// A*alpha + B*beta
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, 0));
+}
+
+// (A*alpha + beta) + B*gamma
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3));
+}
+
+// B*gamma + (A*alpha + beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
+            const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
+{ return a + b; }
+
+// (A*alpha + beta) + (B*gamma + theta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3 + b.e.a3));
+}
+
+// A*alpha - B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const M& b )
+{
+    typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, 0));
+}
+
+// B - A*alpha
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const M& b,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{
+    typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, 0));
+}
+
+// (A*alpha + beta) - B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const M& b )
+{
+    typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
+}
+
+// B - (A*alpha + beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const M& b,
+            const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{
+    typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
+}
+
+// A*alpha - E
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const MatExpr_<B, M>& b )
+{ return a - (M)b; }
+
+// E - A*alpha
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<B, M>& b,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return (M)b - a; }
+
+// (A*alpha + beta) - E
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const MatExpr_<B, M>& b )
+{ return a - (M)b; }
+
+// E - (A*alpha + beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<B, M>& b,
+            const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
+{ return (M)b - a; }
+
+// A*alpha - B*beta
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, 0));
+}
+
+// (A*alpha + beta) - B*gamma
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3));
+}
+
+// B*gamma - (A*alpha + beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
+            const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b.e.a1, b.e.a2, -a.e.a3));
+}
+
+// (A*alpha + beta) - (B*gamma + theta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
+operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3 - b.e.a3));
+}
+
+/////////////////////////////// Mat Multiplication ///////////////////////////////////
+
+// A^t
+inline MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> >, Mat>
+Mat::t() const
+{
+    typedef MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, 1));
+}
+
+template<typename T> inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_T_<Mat> >, Mat_<T> >
+Mat_<T>::t() const
+{
+    typedef MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_T_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(*this, 1));
+}
+
+// A*B
+static inline
+MatExpr_<MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> >, Mat>
+operator * ( const Mat& a, const Mat& b )
+{
+    typedef MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, 0));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op4_<Mat_<T>, Mat_<T>, double, int, Mat_<T>,
+MatOp_MatMul_<Mat> >, Mat_<T> >
+operator * ( const Mat_<T>& a, const Mat_<T>& b )
+{
+    typedef MatExpr_Op4_<Mat_<T>, Mat_<T>, double, int, Mat_<T>,
+        MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, b, 1, 0));
+}
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b, 1, 0));
+}
+
+// (A*alpha)*B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a, const M& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, 0));
+}
+
+// A*(B*alpha)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const M& b, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(b, (M)a.e.a1, a.e.a2, 0));
+}
+
+// A^t*B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a, const M& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, GEMM_1_T));
+}
+
+// A*B^t
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, GEMM_2_T));
+}
+
+// (A*alpha)*(B*beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, 0));
+}
+
+// A^t*(B*alpha)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T));
+}
+
+// (A*alpha)*B^t
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_2_T));
+}
+
+// A^t*B^t
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1,
+        (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T+GEMM_2_T));
+}
+
+// (A*B)*alpha
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             double alpha )
+{
+    typedef MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
+}
+
+// alpha*(A*B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator * ( double alpha,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{
+    return a*alpha;
+}
+
+// -(A*B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{
+    return a*(-1);
+}
+
+// (A*alpha + beta)*B
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a, const M& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, b, a.e.a3, 0));
+}
+
+// A*(B*alpha + beta)
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0));
+}
+
+// (A*alpha + beta)*(B*gamma)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
+        a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, 0));
+}
+
+// (A*gamma)*(B*alpha + beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
+        a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, 0));
+}
+
+// (A*alpha + beta)*B^t
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
+        a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, GEMM_2_T));
+}
+
+// A^t*(B*alpha + beta)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
+        a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, GEMM_1_T));
+}
+
+// (A*B + C)*alpha
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
+             double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a, double alpha )
+{
+    typedef MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2,
+        a.e.a3*alpha, a.e.a4, a.e.a5*alpha, a.e.a6));
+}
+
+// alpha*(A*B + C)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator * ( double alpha, const MatExpr_<MatExpr_Op6_<A, B, double, C,
+             double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
+{ return a*alpha; }
+
+// -(A*B + C)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
+             double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
+{ return a*(-1); }
+
+
+// (A*B) + C
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const M& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, b, 1, a.e.a4));
+}
+
+// C + (A*B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const M& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{ return a + b; }
+
+
+// (A*B) - C
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const M& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, b, -1, a.e.a4));
+}
+
+// C - (A*B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const M& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, -a.e.a3, b, 1, a.e.a4));
+}
+
+
+// (A*B) + C
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const MatExpr_<C, M>& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, 1, a.e.a4));
+}
+
+// C + (A*B)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<C, M>& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{ return a + b; }
+
+
+// (A*B) - C
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const MatExpr_<C, M>& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, -1, a.e.a4));
+}
+
+// C - (A*B)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<C, M>& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b, 1, a.e.a4));
+}
+
+
+// (A*B) + C*alpha
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
+}
+
+// C*alpha + (A*B)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{ return a + b; }
+
+
+// (A*B) - (C*alpha)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4));
+}
+
+// (C*alpha) - (A*B)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
+}
+
+
+// (A*B) + C^t
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4 + GEMM_3_T));
+}
+
+// C^t + (A*B)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{ return a + b; }
+
+
+// (A*B) - C^t
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
+             const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4+GEMM_3_T));
+}
+
+// C^t - (A*B)
+template<typename A, typename B, typename C, typename M> static inline
+MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
+operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
+             const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
+{
+    typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
+        (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4+GEMM_3_T));
+}
+
+
+////////////////////////////// Augmenting algebraic operations //////////////////////////////////
+
+static inline Mat& operator += (const Mat& a, const Mat& b)
+{
+    add(a, b, (Mat&)a);
+    return (Mat&)a;
+}
+
+static inline Mat& operator -= (const Mat& a, const Mat& b)
+{
+    subtract(a, b, (Mat&)a);
+    return (Mat&)a;
+}
+
+static inline Mat& operator *= (const Mat& a, const Mat& b)
+{
+    gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
+    return (Mat&)a;
+}
+
+static inline Mat& operator *= (const Mat& a, double alpha)
+{
+    a.convertTo((Mat&)a, -1, alpha);
+    return (Mat&)a;
+}
+
+static inline Mat& operator += (const Mat& a, const Scalar& s)
+{
+    add(a, s, (Mat&)a);
+    return (Mat&)a;
+}
+
+static inline Mat& operator -= (const Mat& a, const Scalar& s)
+{ return (a += -s); }
+
+template<typename T> static inline
+Mat_<T>& operator += (const Mat_<T>& a, const Mat_<T>& b)
+{
+    (Mat&)a += (const Mat&)b;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline
+Mat_<T>& operator -= (const Mat_<T>& a, const Mat_<T>& b)
+{
+    (Mat&)a -= (const Mat&)b;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline
+Mat_<T>& operator *= (const Mat_<T>& a, const Mat_<T>& b)
+{
+    (Mat&)a *= (const Mat&)b;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline
+Mat_<T>& operator += (const Mat_<T>& a, const Scalar& s)
+{
+    (Mat&)a += s;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline
+Mat_<T>& operator -= (const Mat_<T>& a, const Scalar& s)
+{
+    (Mat&)a -= s;
+    return (Mat_<T>&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator += (const M& a, const MatExpr_<A, M>& b)
+{ return (a += (M)b); }
+
+template<typename A, typename M> static inline
+M& operator -= (const M& a, const MatExpr_<A, M>& b)
+{ return (a -= (M)b); }
+
+template<typename A, typename M> static inline
+M& operator *= (const M& a, const MatExpr_<A, M>& b)
+{ return (a *= (M)b); }
+
+template<typename A, typename M> static inline
+M& operator += (const M& a,
+                const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
+{
+    scaleAdd( b.e.a1, Scalar(b.e.a2), a, a );
+    return (M&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator -= (const M& a,
+                const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
+{
+    CvMat _a = a;
+    CvMat _b = b.e.a1;
+    cvScaleAdd( &_b, -b.e.a2, &_a, &_a );
+    return (M&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator += (const M& a,
+                const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
+{
+    MatOp_AddEx_<Mat>::apply( a, 1, (M)b.e.a1, b.e.a2, b.e.a3, a );
+    return (M&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator -= (const M& a,
+                const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
+{
+    MatOp_AddEx_<Mat>::apply( a, 1, (M)b.e.a1, -b.e.a2, -b.e.a3, a );
+    return (M&)a;
+}
+
+template<typename A, typename B, typename M> static inline
+M& operator += (const M& a,
+                const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& b)
+{
+    MatOp_MatMulAdd_<Mat>::apply( (M)b.e.a1, (M)b.e.a2, b.e.a3, a, 1, b.e.a4, a );
+    return (M&)a;
+}
+
+template<typename A, typename B, typename M> static inline
+M& operator -= (const M& a,
+                const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& b)
+{
+    MatOp_MatMulAdd_<Mat>::apply( (M)b.e.a1, (M)b.e.a2, -b.e.a3, a, 1, b.e.a4, a );
+    return (M&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator *= (const M& a,
+                const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
+{
+    MatOp_MatMul_<Mat>::apply( a, (M)b.e.a1, b.e.a2, 0, a );
+    return (M&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator *= (const M& a,
+                const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
+{
+    MatOp_MatMulAdd_<Mat>::apply( a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0, a );
+    return (M&)a;
+}
+
+template<typename A, typename M> static inline
+M& operator *= (const M& a,
+                const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b)
+{
+    MatOp_MatMul_<Mat>::apply( a, (M)b.e.a1, b.e.a2, GEMM_2_T, a );
+    return (M&)a;
+}
+
+////////////////////////////// Logical operations ///////////////////////////////
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
+operator & (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '&'));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
+operator | (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '|'));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
+operator ^ (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '^'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+            MatOp_Bin_<Mat> >, Mat_<T> >
+operator & (const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+        MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(
+        a, b, '&'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+            MatOp_Bin_<Mat> >, Mat_<T> >
+operator | (const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+        MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(
+        a, b, '|'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+            MatOp_Bin_<Mat> >, Mat_<T> >
+operator ^ (const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+        MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(
+        a, b, '^'));
+}
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator & (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
+{ return (M)a & (M)b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator & (const MatExpr_<A, M>& a, const M& b)
+{ return (M)a & b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator & (const M& a, const MatExpr_<A, M>& b)
+{ return a & (M)b; }
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator | (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
+{ return (M)a | (M)b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator | (const MatExpr_<A, M>& a, const M& b)
+{ return (M)a | b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator | (const M& a, const MatExpr_<A, M>& b)
+{ return a | (M)b; }
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator ^ (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
+{ return (M)a ^ (M)b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator ^ (const MatExpr_<A, M>& a, const M& b)
+{ return (M)a ^ b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+operator ^ (const M& a, const MatExpr_<A, M>& b)
+{ return a ^ (M)b; }
+
+static inline Mat& operator &= (const Mat& a, const Mat& b)
+{
+    MatOp_Bin_<Mat>::apply( a, b, '&', (Mat&)a );
+    return (Mat&)a;
+}
+
+static inline Mat& operator |= (const Mat& a, const Mat& b)
+{
+    MatOp_Bin_<Mat>::apply( a, b, '|', (Mat&)a );
+    return (Mat&)a;
+}
+
+static inline Mat& operator ^= (const Mat& a, const Mat& b)
+{
+    MatOp_Bin_<Mat>::apply( a, b, '^', (Mat&)a );
+    return (Mat&)a;
+}
+
+template<typename T> static inline Mat_<T>&
+operator &= (const Mat_<T>& a, const Mat_<T>& b)
+{
+    (Mat&)a &= (const Mat&)b;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline Mat_<T>&
+operator |= (const Mat_<T>& a, const Mat_<T>& b)
+{
+    (Mat&)a |= (const Mat&)b;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline Mat_<T>&
+operator ^= (const Mat_<T>& a, const Mat_<T>& b)
+{
+    (Mat&)a ^= (const Mat&)b;
+    return (Mat_<T>&)a;
+}
+
+template<typename A, typename M> static inline M&
+operator &= (const M& a, const MatExpr_<A, M>& b)
+{ return (a &= (M)b); }
+
+template<typename A, typename M> static inline M&
+operator |= (const M& a, const MatExpr_<A, M>& b)
+{ return (a |= (M)b); }
+
+template<typename A, typename M> static inline M&
+operator ^= (const M& a, const MatExpr_<A, M>& b)
+{ return (a ^= (M)b); }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator & (const Mat& a, const Scalar& s)
+{
+    typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '&'));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator & (const Scalar& s, const Mat& a)
+{ return a & s; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator | (const Mat& a, const Scalar& s)
+{
+    typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '|'));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator | (const Scalar& s, const Mat& a)
+{ return a | s; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator ^ (const Mat& a, const Scalar& s)
+{
+    typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '^'));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator ^ (const Scalar& s, const Mat& a)
+{ return a ^ s; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+operator ~ (const Mat& a)
+{
+    typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, Scalar(), '~'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator & (const Mat_<T>& a, const Scalar& s)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, s, '&'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator & (const Scalar& s, const Mat_<T>& a)
+{ return a & s; }
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator | (const Mat_<T>& a, const Scalar& s)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, s, '|'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator | (const Scalar& s, const Mat_<T>& a)
+{ return a | s; }
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator ^ (const Mat_<T>& a, const Scalar& s)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, s, '^'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator ^ (const Scalar& s, const Mat_<T>& a)
+{ return a ^ s; }
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> >, Mat_<T> >
+operator ~ (const Mat_<T>& a)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, Scalar(), '~'));
+}
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator & (const MatExpr_<A, M>& a, const Scalar& s)
+{ return (M)a & s; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator & (const Scalar& s, const MatExpr_<A, M>& a)
+{ return (M)a & s; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator | (const MatExpr_<A, M>& a, const Scalar& s)
+{ return (M)a | s; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator | (const Scalar& s, const MatExpr_<A, M>& a)
+{ return (M)a | s; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator ^ (const MatExpr_<A, M>& a, const Scalar& s)
+{ return (M)a ^ s; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator ^ (const Scalar& s, const MatExpr_<A, M>& a)
+{ return (M)a ^ s; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
+operator ~ (const MatExpr_<A, M>& a)
+{ return ~(M)a; }
+
+static inline Mat& operator &= (const Mat& a, const Scalar& s)
+{
+    MatOp_BinS_<Mat>::apply( a, s, '&', (Mat&)a );
+    return (Mat&)a;
+}
+
+static inline Mat& operator |= (const Mat& a, const Scalar& s)
+{
+    MatOp_BinS_<Mat>::apply( a, s, '|', (Mat&)a );
+    return (Mat&)a;
+}
+
+static inline Mat& operator ^= (const Mat& a, const Scalar& s)
+{
+    MatOp_BinS_<Mat>::apply( a, s, '^', (Mat&)a );
+    return (Mat&)a;
+}
+
+template<typename T> static inline Mat_<T>&
+operator &= (const Mat_<T>& a, const Scalar& s)
+{
+    (Mat&)a &= s;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline Mat_<T>&
+operator |= (const Mat_<T>& a, const Scalar& s)
+{
+    (Mat&)a |= s;
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline Mat_<T>&
+operator ^= (const Mat_<T>& a, const Scalar& s)
+{
+    (Mat&)a ^= s;
+    return (Mat_<T>&)a;
+}
+
+////////////////////////////// Comparison operations ///////////////////////////////
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
+operator == (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_EQ));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
+operator >= (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_GE));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
+operator > (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_GT));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
+operator <= (const Mat& a, const Mat& b)
+{ return b >= a; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
+operator < (const Mat& a, const Mat& b)
+{ return b > a; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
+operator != (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_NE));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator == (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_EQ));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator >= (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_GE));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator > (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_GT));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator <= (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_LE));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator < (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_LT));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator != (const Mat& a, double alpha)
+{
+    typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_NE));
+}
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator == (double alpha, const Mat& a)
+{ return a == alpha; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator >= (double alpha, const Mat& a)
+{ return a <= alpha; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator > (double alpha, const Mat& a)
+{ return a < alpha; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator <= (double alpha, const Mat& a)
+{ return a >= alpha; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator < (double alpha, const Mat& a)
+{ return a > alpha; }
+
+static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
+operator != (double alpha, const Mat& a)
+{ return a != alpha; }
+
+/////////////////////////////// Miscellaneous operations //////////////////////////////
+
+// max(A, B)
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
+max(const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 'M'));
+}
+
+// min(A, B)
+static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
+min(const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 'm'));
+}
+
+// abs(A)
+static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
+abs(const Mat& a)
+{
+    typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, Scalar(0), 'a'));
+}
+
+// max(A, B)
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+            MatOp_Bin_<Mat> >, Mat_<T> >
+max(const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+        MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(
+        a, b, 'M'));
+}
+
+// min(A, B)
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+            MatOp_Bin_<Mat> >, Mat_<T> >
+min(const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Mat_<T>, int, Mat_<T>,
+        MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(
+        a, b, 'm'));
+}
+
+// abs(A)
+template<typename T> static inline
+MatExpr_<MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>,
+            MatOp_BinS_<Mat> >, Mat_<T> >
+abs(const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op3_<Mat_<T>, Scalar, int, Mat_<T>,
+        MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(
+        a, Scalar(0), 'a'));
+}
+
+// max(A, B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+max(const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
+{ return max((M)a, (M)b); }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+max(const MatExpr_<A, M>& a, const M& b)
+{ return max((M)a, b); }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+max(const M& a, const MatExpr_<A, M>& b)
+{ return max(a, (M)b); }
+
+// min(A, B)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+min(const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
+{ return min((M)a, (M)b); }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+min(const MatExpr_<A, M>& a, const M& b)
+{ return min((M)a, b); }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+min(const M& a, const MatExpr_<A, M>& b)
+{ return min(a, (M)b); }
+
+// abs(A)
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
+abs(const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
+{
+    typedef MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, 'a'));
+}
+
+template<typename T> void merge(const Vector<Mat_<T> >& mv, Mat& dst)
+{ merge( (const Vector<Mat>&)mv, dst ); }
+
+template<typename T> void split(const Mat& src, Vector<Mat_<T> >& mv)
+{ split(src, (Vector<Mat>&)mv ); }
+
+///// Element-wise multiplication
+
+inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
+Mat::mul(const Mat& m, double scale) const
+{
+    typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m, scale, '*'));
+}
+
+inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
+Mat::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>& m, double scale) const
+{
+    typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*'));
+}
+
+inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
+Mat::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat>& m, double scale) const
+{
+    typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/'));
+}
+
+template<typename T> inline
+MatExpr_<MatExpr_Op4_<Mat_<T>, Mat_<T>, double, char, Mat_<T>, MatOp_MulDiv_<Mat> >, Mat_<T> >
+Mat_<T>::mul(const Mat_<T>& m, double scale) const
+{
+    typedef MatExpr_Op4_<Mat_<T>, Mat_<T>, double, char, Mat_<T>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(*this, m, scale, '*'));
+}
+
+template<typename T> inline
+MatExpr_<MatExpr_Op4_<Mat_<T>, Mat_<T>, double, char, Mat_<T>, MatOp_MulDiv_<Mat> >, Mat_<T> >
+Mat_<T>::mul(const MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_Scale_<Mat> >, Mat_<T> >& m, double scale) const
+{
+    typedef MatExpr_Op4_<Mat_<T>, Mat_<T>, double, char, Mat_<T>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*'));
+}
+
+template<typename T> inline
+MatExpr_<MatExpr_Op4_<Mat_<T>, Mat_<T>, double, char, Mat_<T>, MatOp_MulDiv_<Mat> >, Mat_<T> >
+Mat_<T>::mul(const MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_DivRS_<Mat> >, Mat_<T> >& m, double scale) const
+{
+    typedef MatExpr_Op4_<Mat_<T>, Mat_<T>, double, char, Mat_<T>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/'));
+}
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op4_<A, B, double, char, M, MatOp_MulDiv_<Mat> >, M>& a,
+            double alpha)
+{
+    typedef MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, a.e.a3*alpha, a.e.a4));
+}
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator * (double alpha,
+            const MatExpr_<MatExpr_Op4_<A, B, double, char, M, MatOp_MulDiv_<Mat> >, M>& a)
+{ return a*alpha; }
+
+
+////// Element-wise division
+
+static inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
+operator / (const Mat& a, const Mat& b)
+{
+    typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, '/'));
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op4_<Mat_<T>, Mat_<T>, double,
+char, Mat_<T>, MatOp_MulDiv_<Mat> >, Mat_<T> >
+operator / (const Mat_<T>& a, const Mat_<T>& b)
+{
+    typedef MatExpr_Op4_<Mat_<T>, Mat_<T>, double,
+        char, Mat_<T>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, b, 1, '/'));
+}
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
+{ return (M)a/(M)b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const MatExpr_<A, M>& a, const M& b)
+{ return (M)a/b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const M& a, const MatExpr_<A, M>& b)
+{ return a/(M)b; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const M& b)
+{ return ((M)a.e.a1/b)*a.e.a2; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const M& a,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
+{ return (a/(M)b.e.a1)*(1./b.e.a2); }
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
+            const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b)
+{ return ((M)a.e.a1/(M)b.e.a1)*(a.e.a2/b.e.a2); }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const M& a,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_DivRS_<Mat> >, M>& b)
+{ return a.mul((M)b.e.a1, 1./b.e.a2); }
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
+operator / (const MatExpr_<A, M>& a,
+            const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_DivRS_<Mat> >, M>& b)
+{ return ((M)a).mul((M)b.e.a1, 1./b.e.a2); }
+
+static inline
+MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat >
+operator / (double alpha, const Mat& a)
+{
+    typedef MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
+}
+
+static inline Mat& operator /= (const Mat& a, double alpha)
+{
+    MatOp_Scale_<Mat>::apply( a, 1./alpha, (Mat&)a );
+    return (Mat&)a;
+}
+
+template<typename T>
+static inline Mat_<T>& operator /= (const Mat_<T>& a, double alpha)
+{
+    MatOp_Scale_<Mat>::apply( a, 1./alpha, (Mat&)a );
+    return (Mat_<T>&)a;
+}
+
+template<typename T> static inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, double, Mat_<T>, MatOp_DivRS_<Mat> >, Mat_<T> >
+operator / (double alpha, const Mat_<T>& a)
+{
+    typedef MatExpr_Op2_<Mat_<T>, double, Mat_<T>,
+        MatOp_DivRS_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(a, alpha));
+}
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, double, M, MatOp_DivRS_<Mat> >, M>
+operator / (double alpha, const MatExpr_<A, M>& a)
+{ return alpha/(M)a; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, double, M, MatOp_DivRS_<Mat> >, M>
+operator / (double alpha,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
+{ return (alpha/a.e.a2)/(M)a.e.a1; }
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
+operator / (double alpha,
+            const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_DivRS_<Mat> >, M>& a)
+{ return (M)a.e.a1*(alpha/a.e.a2); }
+
+static inline Mat& operator /= (const Mat& a, const Mat& b)
+{
+    MatOp_MulDiv_<Mat>::apply( a, b, 1, '/', (Mat&)a );
+    return (Mat&)a;
+}
+
+template<typename A, typename M>
+static inline M& operator /= (const M& a, const MatExpr_<MatExpr_Op2_<A, double,
+                              M, MatOp_Scale_<Mat> >, M>& b)
+{
+    MatOp_MulDiv_<Mat>::apply( a, (M)b.e.a1, 1./b.e.a2, '/', (M&)a );
+    return (M&)a;
+}
+
+template<typename A, typename M>
+static inline M& operator /= (const M& a, const MatExpr_<MatExpr_Op2_<A, double,
+                              M, MatOp_DivRS_<Mat> >, M>& b)
+{
+    MatOp_MulDiv_<Mat>::apply( a, (M)b.e.a1, 1./b.e.a2, '*', (M&)a );
+    return (M&)a;
+}
+
+// Mat Inversion and solving linear systems
+
+inline MatExpr_<MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> >, Mat>
+Mat::inv(int method) const
+{
+    typedef MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, method));
+}
+
+template<typename T> inline
+MatExpr_<MatExpr_Op2_<Mat_<T>, int, Mat_<T>, MatOp_Inv_<Mat> >, Mat_<T> >
+Mat_<T>::inv(int method) const
+{
+    typedef MatExpr_Op2_<Mat_<T>, int, Mat_<T>, MatOp_Inv_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat_<T> >(MatExpr_Temp(*this, method));
+}
+
+template<typename A, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op2_<A, int, M, MatOp_Inv_<Mat> >, M>& a,
+            const M& b)
+{
+    typedef MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2));
+}
+
+template<typename A, typename B, typename M> static inline
+MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> >, M>
+operator * (const MatExpr_<MatExpr_Op2_<A, int, M, MatOp_Inv_<Mat> >, M>& a,
+            const MatExpr_<B, M>& b)
+{ return a*(M)b; }
+
+
+/////////////////////////////// Initialization ////////////////////////////////////////
+
+inline MatExpr_Initializer Mat::zeros(int rows, int cols, int type)
+{
+    typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(Size(cols, rows), type, 0, 0));
+}
+
+inline MatExpr_Initializer Mat::zeros(Size size, int type)
+{
+    return zeros(size.height, size.width, type);
+}
+
+inline MatExpr_Initializer Mat::ones(int rows, int cols, int type)
+{
+    typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
+    return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(Size(cols, rows), type, 1, 1));
+}
+
+inline MatExpr_Initializer Mat::ones(Size size, int type)
+{
+    return ones(size.height, size.width, type);
+}
+
+inline MatExpr_Initializer Mat::eye(int rows, int cols, int type)
+{
+    typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
+    return MatExpr_Initializer(MatExpr_Temp(Size(cols, rows), type, 1, 2));
+}
+
+inline MatExpr_Initializer Mat::eye(Size size, int type)
+{
+    return eye(size.height, size.width, type);
+}
+
+static inline MatExpr_Initializer operator * (const MatExpr_Initializer& a, double alpha)
+{
+    typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
+    return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
+}
+
+static inline MatExpr_Initializer operator * (double alpha, MatExpr_Initializer& a)
+{ return a*alpha; }
+
+template<typename T> inline MatExpr_Initializer Mat_<T>::zeros(int rows, int cols)
+{ return Mat::zeros(rows, cols, DataType<T>::type); }
+
+template<typename T> inline MatExpr_Initializer Mat_<T>::zeros(Size size)
+{ return Mat::zeros(size, DataType<T>::type); }
+
+template<typename T> inline MatExpr_Initializer Mat_<T>::ones(int rows, int cols)
+{ return Mat::ones(rows, cols, DataType<T>::type); }
+
+template<typename T> inline MatExpr_Initializer Mat_<T>::ones(Size size)
+{ return Mat::ones(size, DataType<T>::type); }
+
+template<typename T> inline MatExpr_Initializer Mat_<T>::eye(int rows, int cols)
+{ return Mat::eye(rows, cols, DataType<T>::type); }
+
+template<typename T> inline MatExpr_Initializer Mat_<T>::eye(Size size)
+{ return Mat::eye(size, DataType<T>::type); }
+
+
+//////////// Iterators & Comma initializers //////////////////
+
+template<typename T> inline MatConstIterator_<T>::MatConstIterator_()
+    : m(0), ptr(0), sliceEnd(0) {}
+
+template<typename T> inline MatConstIterator_<T>::MatConstIterator_(const Mat_<T>* _m) : m(_m)
+{
+    if( !_m )
+        ptr = sliceEnd = 0;
+    else
+    {
+        ptr = (T*)_m->data;
+        sliceEnd = ptr + (_m->isContinuous() ? _m->rows*_m->cols : _m->cols);
+    }
+}
+
+template<typename T> inline MatConstIterator_<T>::
+    MatConstIterator_(const Mat_<T>* _m, int _row, int _col) : m(_m)
+{
+    if( !_m )
+        ptr = sliceEnd = 0;
+    else
+    {
+        assert( (unsigned)_row < _m->rows && (unsigned)_col < _m->cols );
+        ptr = (T*)(_m->data + _m->step*_row);
+        sliceEnd = _m->isContinuous() ? (T*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
+        ptr += _col;
+    }
+}
+
+template<typename T> inline MatConstIterator_<T>::
+    MatConstIterator_(const Mat_<T>* _m, Point _pt) : m(_m)
+{
+    if( !_m )
+        ptr = sliceEnd = 0;
+    else
+    {
+        assert( (unsigned)_pt.y < (unsigned)_m->rows && (unsigned)_pt.x < (unsigned)_m->cols );
+        ptr = (T*)(_m->data + _m->step*_pt.y);
+        sliceEnd = _m->isContinuous() ? (T*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
+        ptr += _pt.x;
+    }
+}
+
+template<typename T> inline MatConstIterator_<T>::
+    MatConstIterator_(const MatConstIterator_& it)
+    : m(it.m), ptr(it.ptr), sliceEnd(it.sliceEnd) {}
+
+template<typename T> inline MatConstIterator_<T>&
+    MatConstIterator_<T>::operator = (const MatConstIterator_& it )
+{
+    m = it.m; ptr = it.ptr; sliceEnd = it.sliceEnd;
+    return *this;
+}
+
+template<typename T> inline T MatConstIterator_<T>::operator *() const { return *ptr; }
+
+template<typename T> inline MatConstIterator_<T>& MatConstIterator_<T>::operator += (int ofs)
+{
+    if( !m || ofs == 0 )
+        return *this;
+    ptr += ofs;
+    if( m->isContinuous() )
+    {
+        if( ptr > sliceEnd )
+            ptr = sliceEnd;
+        else if( ptr < (T*)m->data )
+            ptr = (T*)m->data;
+    }
+    else if( ptr >= sliceEnd || ptr < sliceEnd - m->cols )
+    {
+        ptr -= ofs;
+        Point pt = pos();
+        int cols = m->cols;
+        ofs += pt.y*cols + pt.x;
+        if( ofs > cols*m->rows )
+            ofs = cols*m->rows;
+        else if( ofs < 0 )
+            ofs = 0;
+        pt.y = ofs/cols;
+        pt.x = ofs - pt.y*cols;
+        ptr = (T*)(m->data + m->step*pt.y);
+        sliceEnd = ptr + cols;
+        ptr += pt.x;
+    }
+    return *this;
+}
+
+template<typename T> inline MatConstIterator_<T>& MatConstIterator_<T>::operator -= (int ofs)
+{ return (*this += -ofs); }
+
+template<typename T> inline MatConstIterator_<T>& MatConstIterator_<T>::operator --()
+{ return (*this += -1); }
+
+template<typename T> inline MatConstIterator_<T> MatConstIterator_<T>::operator --(int)
+{
+    MatConstIterator_ b = *this;
+    *this += -1;
+    return b;
+}
+
+template<typename T> inline MatConstIterator_<T>& MatConstIterator_<T>::operator ++()
+{
+    if( m && ++ptr >= sliceEnd )
+    {
+        --ptr;
+        *this += 1;
+    }
+    return *this;
+}
+
+template<typename T> inline MatConstIterator_<T> MatConstIterator_<T>::operator ++(int)
+{
+    MatConstIterator_ b = *this;
+    if( m && ++ptr >= sliceEnd )
+    {
+        --ptr;
+        *this += 1;
+    }
+    return b;
+}
+
+template<typename T> inline Point MatConstIterator_<T>::pos() const
+{
+    if( !m )
+        return Point();
+    if( m->isContinuous() )
+    {
+        int ofs = ptr - (T*)m->data, y = ofs / m->cols, x = ofs - y*m->cols;
+        return Point(x,y);
+    }
+    else
+    {
+        int stepT = m->stepT(), y = (ptr - (T*)m->data)/stepT, x = (ptr - (T*)m->data) - y*stepT;
+        return Point(x,y);
+    }
+}
+
+template<typename T> inline MatIterator_<T>::MatIterator_() : MatConstIterator_<T>() {}
+
+template<typename T> inline MatIterator_<T>::MatIterator_(Mat_<T>* _m)
+    : MatConstIterator_<T>(_m) {}
+
+template<typename T> inline MatIterator_<T>::MatIterator_(Mat_<T>* _m, int _row, int _col)
+    : MatConstIterator_<T>(_m, _row, _col) {}
+
+template<typename T> inline MatIterator_<T>::MatIterator_(const Mat_<T>* _m, Point _pt)
+    : MatConstIterator_<T>(_m, _pt) {}
+
+template<typename T> inline MatIterator_<T>::MatIterator_(const MatIterator_& it)
+    : MatConstIterator_<T>(it) {}
+
+template<typename T> inline MatIterator_<T>& MatIterator_<T>::operator = (const MatIterator_<T>& it )
+{
+    this->m = it.m; this->ptr = it.ptr; this->sliceEnd = it.sliceEnd;
+    return *this;
+}
+
+template<typename T> inline T& MatIterator_<T>::operator *() const { return *(this->ptr); }
+
+template<typename T> inline MatIterator_<T>& MatIterator_<T>::operator += (int ofs)
+{
+    MatConstIterator_<T>::operator += (ofs);
+    return *this;
+}
+
+template<typename T> inline MatIterator_<T>& MatIterator_<T>::operator -= (int ofs)
+{
+    MatConstIterator_<T>::operator += (-ofs);
+    return *this;
+}
+
+template<typename T> inline MatIterator_<T>& MatIterator_<T>::operator --()
+{
+    MatConstIterator_<T>::operator += (-1);
+    return *this;
+}
+
+template<typename T> inline MatIterator_<T> MatIterator_<T>::operator --(int)
+{
+    MatIterator_ b = *this;
+    MatConstIterator_<T>::operator += (-1);
+    return b;
+}
+
+template<typename T> inline MatIterator_<T>& MatIterator_<T>::operator ++()
+{
+    if( this->m && ++this->ptr >= this->sliceEnd )
+    {
+        --this->ptr;
+        MatConstIterator_<T>::operator += (1);
+    }
+    return *this;
+}
+
+template<typename T> inline MatIterator_<T> MatIterator_<T>::operator ++(int)
+{
+    MatIterator_ b = *this;
+    if( this->m && ++this->ptr >= this->sliceEnd )
+    {
+        --this->ptr;
+        MatConstIterator_<T>::operator += (1);
+    }
+    return b;
+}
+
+template<typename T> static inline bool
+operator == (const MatConstIterator_<T>& a, const MatConstIterator_<T>& b)
+{ return a.m == b.m && a.ptr == b.ptr; }
+
+template<typename T> static inline bool
+operator != (const MatConstIterator_<T>& a, const MatConstIterator_<T>& b)
+{ return !(a == b); }
+
+template<typename T> static inline bool
+operator < (const MatConstIterator_<T>& a, const MatConstIterator_<T>& b)
+{ return a.ptr < b.ptr; }
+
+template<typename T> static inline bool
+operator > (const MatConstIterator_<T>& a, const MatConstIterator_<T>& b)
+{ return a.ptr > b.ptr; }
+
+template<typename T> static inline bool
+operator <= (const MatConstIterator_<T>& a, const MatConstIterator_<T>& b)
+{ return a.ptr <= b.ptr; }
+
+template<typename T> static inline bool
+operator >= (const MatConstIterator_<T>& a, const MatConstIterator_<T>& b)
+{ return a.ptr >= b.ptr; }
+
+template<typename T> static inline int
+operator - (const MatConstIterator_<T>& b, const MatConstIterator_<T>& a)
+{
+    if( a.m != b.m )
+        return INT_MAX;
+    if( a.sliceEnd == b.sliceEnd )
+        return b.ptr - a.ptr;
+    {
+        Point ap = a.pos(), bp = b.pos();
+        if( bp.y > ap.y )
+            return (bp.y - ap.y - 1)*a.m->cols + (a.m->cols - ap.x) + bp.x;
+        if( bp.y < ap.y )
+            return -((ap.y - bp.y - 1)*a.m->cols + (a.m->cols - bp.x) + ap.x);
+        return bp.x - ap.x;
+    }
+}
+
+template<typename T> static inline MatConstIterator_<T>
+operator + (const MatConstIterator_<T>& a, int ofs)
+{ MatConstIterator_<T> b = a; return b += ofs; }
+
+template<typename T> static inline MatConstIterator_<T>
+operator + (int ofs, const MatConstIterator_<T>& a)
+{ MatConstIterator_<T> b = a; return b += ofs; }
+
+template<typename T> static inline MatConstIterator_<T>
+operator - (const MatConstIterator_<T>& a, int ofs)
+{ MatConstIterator_<T> b = a; return b += -ofs; }
+
+template<typename T> inline T MatConstIterator_<T>::operator [](int i) const
+{ return *(*this + i); }
+
+template<typename T> static inline MatIterator_<T>
+operator + (const MatIterator_<T>& a, int ofs)
+{ MatIterator_<T> b = a; return b += ofs; }
+
+template<typename T> static inline MatIterator_<T>
+operator + (int ofs, const MatIterator_<T>& a)
+{ MatIterator_<T> b = a; return b += ofs; }
+
+template<typename T> static inline MatIterator_<T>
+operator - (const MatIterator_<T>& a, int ofs)
+{ MatIterator_<T> b = a; return b += -ofs; }
+
+template<typename T> inline T& MatIterator_<T>::operator [](int i) const
+{ return *(*this + i); }
+
+template<typename T> inline MatConstIterator_<T> Mat_<T>::begin() const
+{ return MatConstIterator_<T>(this); }
+
+template<typename T> inline MatConstIterator_<T> Mat_<T>::end() const
+{
+    MatConstIterator_<T> it(this);
+    it.ptr = it.sliceEnd = (T*)(data + step*(rows-1)) + cols;
+    return it;
+}
+
+template<typename T> inline MatIterator_<T> Mat_<T>::begin()
+{ return MatIterator_<T>(this); }
+
+template<typename T> inline MatIterator_<T> Mat_<T>::end()
+{
+    MatIterator_<T> it(this);
+    it.ptr = it.sliceEnd = (T*)(data + step*(rows-1)) + cols;
+    return it;
+}
+
+template<typename T> struct CV_EXPORTS MatOp_Iter_
+{
+    MatOp_Iter_() {}
+    
+    static void apply(const MatIterator_<T>& a, Mat& c, int type=-1)
+    {
+        if( type < 0 )
+            c = *a.m;
+        else
+            a.m->convertTo(c, type);
+    }
+};
+
+template<typename T> inline MatCommaInitializer_<T>::MatCommaInitializer_(Mat_<T>* _m) :
+    MatExpr_<MatExpr_Op1_<MatIterator_<T>, Mat_<T>,
+        MatOp_Iter_<T> >, Mat_<T> >(MatIterator_<T>(_m)) {}
+
+template<typename T> template<typename T2> inline MatCommaInitializer_<T>&
+MatCommaInitializer_<T>::operator , (T2 v)
+{
+    assert( this->e.a1 < this->e.a1.m->end() );
+    *this->e.a1 = T(v); ++this->e.a1;
+    return *this;
+}
+
+template<typename T> inline MatCommaInitializer_<T>::operator Mat_<T>() const
+{
+    assert( this->e.a1 == this->e.a1.m->end() );
+    return *this->e.a1.m;
+}
+    
+template<typename T> inline Mat_<T> MatCommaInitializer_<T>::operator *() const
+{
+    assert( this->e.a1 == this->e.a1.m->end() );
+    return *this->e.a1.m;
+}
+
+template<typename T> inline void
+MatCommaInitializer_<T>::assignTo(Mat& m, int type) const
+{
+    Mat_<T>(*this).assignTo(m, type);
+}
+
+template<typename T, typename T2> static inline MatCommaInitializer_<T>
+operator << (const Mat_<T>& m, T2 val)
+{
+    MatCommaInitializer_<T> commaInitializer((Mat_<T>*)&m);
+    return (commaInitializer, val);
+}
+
+template<typename T> inline VectorCommaInitializer_<T>::
+VectorCommaInitializer_(Vector<T>* _vec) : vec(_vec), idx(0) {}
+
+template<typename T> template<typename T2> inline VectorCommaInitializer_<T>&
+VectorCommaInitializer_<T>::operator , (T2 val)
+{
+    if( (size_t)idx < vec->size() )
+        (*vec)[idx] = T(val);
+    else
+        vec->push_back(T(val));
+    idx++;
+    return *this;
+}
+
+template<typename T> inline VectorCommaInitializer_<T>::operator Vector<T>() const
+{ return *vec; }
+
+template<typename T> inline Vector<T> VectorCommaInitializer_<T>::operator *() const
+{ return *vec; }  
+    
+template<typename T, typename T2> static inline VectorCommaInitializer_<T>
+operator << (const Vector<T>& vec, T2 val)
+{
+    VectorCommaInitializer_<T> commaInitializer((Vector<T>*)&vec);
+    return (commaInitializer, val);
+}
+
+/////////////////////////////// AutoBuffer ////////////////////////////////////////
+
+template<typename T, size_t fixed_size> inline AutoBuffer<T, fixed_size>::AutoBuffer()
+: ptr(buf), size(fixed_size) {}
+
+template<typename T, size_t fixed_size> inline AutoBuffer<T, fixed_size>::AutoBuffer(size_t _size)
+: ptr(buf), size(fixed_size) { allocate(_size); }
+
+template<typename T, size_t fixed_size> inline AutoBuffer<T, fixed_size>::~AutoBuffer()
+{ deallocate(); }
+
+template<typename T, size_t fixed_size> inline void AutoBuffer<T, fixed_size>::allocate(size_t _size)
+{
+    if(_size <= size)
+        return;
+    deallocate();
+    if(_size > fixed_size)
+    {
+        ptr = (T*)fastMalloc(_size*sizeof(T));
+        size = _size;
+    }
+}
+
+template<typename T, size_t fixed_size> inline void AutoBuffer<T, fixed_size>::deallocate()
+{
+    if( ptr != buf )
+    {
+        fastFree(ptr);
+        ptr = buf;
+        size = fixed_size;
+    }
+}
+
+template<typename T, size_t fixed_size> inline AutoBuffer<T, fixed_size>::operator T* ()
+{ return ptr; }
+
+template<typename T, size_t fixed_size> inline AutoBuffer<T, fixed_size>::operator const T* () const
+{ return ptr; }
+
+
+/////////////////////////////////// ObjPtr ////////////////////////////////////////
+
+template<typename T> inline ObjPtr<T>::ObjPtr() : obj(0), refcount(0) {}
+template<typename T> inline ObjPtr<T>::ObjPtr(T* _obj) : obj(_obj)
+{
+    if(obj)
+    {
+        refcount = (int*)fastMalloc(sizeof(*refcount));
+        *refcount = 1;
+    }
+    else
+        refcount = 0;
+}
+
+template<typename T> inline void ObjPtr<T>::addref()
+{ if( refcount ) ++*refcount; }
+
+template<typename T> inline void ObjPtr<T>::release()
+{
+    if( refcount && --*refcount == 0 )
+    {
+        delete_obj();
+        fastFree(refcount);
+    }
+    refcount = 0;
+    obj = 0;
+}
+
+template<typename T> inline void ObjPtr<T>::delete_obj()
+{
+    if( obj ) delete obj;
+}
+
+template<typename T> inline ObjPtr<T>::~ObjPtr() { release(); }
+    
+template<typename T> inline ObjPtr<T>::ObjPtr(const ObjPtr<T>& ptr)
+{
+    obj = ptr.obj;
+    refcount = ptr.refcount;
+    addref();
+}
+
+template<typename T> inline ObjPtr<T>& ObjPtr<T>::operator = (const ObjPtr<T>& ptr)
+{
+    int* _refcount = ptr.refcount;
+    if( _refcount )
+        ++*_refcount;
+    release();
+    obj = ptr.obj;
+    refcount = _refcount;
+    return *this;
+}
+
+template<typename T> inline T* ObjPtr<T>::operator -> () { return obj; }
+template<typename T> inline const T* ObjPtr<T>::operator -> () const { return obj; }
+
+template<typename T> inline ObjPtr<T>::operator T* () { return obj; }
+template<typename T> inline ObjPtr<T>::operator const T*() const { return obj; }
+
+//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
+
+template<> inline void ObjPtr<CvFileStorage>::delete_obj()
+{ cvReleaseFileStorage(&obj); }
+
+static inline void write( FileStorage& fs, const String& name, int value )
+{ cvWriteInt( *fs, name.size() ? name.c_str() : 0, value ); }
+
+static inline void write( FileStorage& fs, const String& name, float value )
+{ cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); }
+
+static inline void write( FileStorage& fs, const String& name, double value )
+{ cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); }
+
+static inline void write( FileStorage& fs, const String& name, const String& value )
+{ cvWriteString( *fs, name.size() ? name.c_str() : 0, value.c_str() ); }
+
+template<typename T> static inline void write(FileStorage& fs, const T& value)
+{ write(fs, String(), value); }
+
+template<> static inline void write(FileStorage& fs, const int& value )
+{ cvWriteInt( *fs, 0, value ); }
+
+template<> static inline void write(FileStorage& fs, const float& value )
+{ cvWriteReal( *fs, 0, value ); }
+
+template<> static inline void write(FileStorage& fs, const double& value )
+{ cvWriteReal( *fs, 0, value ); }
+
+template<> static inline void write(FileStorage& fs, const String& value )
+{ cvWriteString( *fs, 0, value.c_str() ); }
+
+template<typename T, int numflag> struct CV_EXPORTS VecWriterProxy
+{
+    VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
+    void operator()(const Vector<T>& vec) const
+    {
+        size_t i, count = vec.size();
+        for( i = 0; i < count; i++ )
+            write( *fs, vec[i] );
+    }
+    FileStorage* fs;
+};
+
+template<typename T> struct CV_EXPORTS VecWriterProxy<T,1>
+{
+    VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
+    void operator()(const Vector<T>& vec) const
+    {
+        int _fmt = DataType<T>::fmt;
+        char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
+        fs->writeRaw( String(fmt), Vector<uchar>((uchar*)&*vec, vec.size()*sizeof(T)) );
+    }
+    FileStorage* fs;
+};
+
+
+template<typename T> static inline void write( FileStorage& fs, const Vector<T>& vec )
+{
+    VecWriterProxy<T, DataType<T>::fmt != 0> w(&fs);
+    w(vec);
+}
+
+template<typename T> static inline FileStorage&
+operator << ( FileStorage& fs, const Vector<T>& vec )
+{
+    VecWriterProxy<T, DataType<T>::fmt != 0> w(&fs);
+    w(vec);
+    return fs;
+}
+
+CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value );
+
+template<typename T> static inline FileStorage& operator << (FileStorage& fs, const T& value)
+{
+    if( !fs.isOpened() )
+        return fs;
+    if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
+        CV_Error( CV_StsError, "No element name has been given" );
+    write( fs, fs.elname, value );
+    if( fs.state & FileStorage::INSIDE_MAP )
+        fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
+    return fs;
+}
+
+template<> CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str);
+
+static inline FileStorage& operator << (FileStorage& fs, const char* str)
+{ return (fs << String(str)); }
+
+inline FileNode FileStorage::operator[](const String& nodename) const
+{
+    return FileNode(fs.obj, cvGetFileNodeByName(fs.obj, 0, nodename.c_str()));
+}
+inline FileNode FileStorage::operator[](const char* nodename) const
+{
+    return FileNode(fs.obj, cvGetFileNodeByName(fs.obj, 0, nodename));
+}
+
+inline FileNode::FileNode() : fs(0), node(0) {}
+inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node)
+    : fs(_fs), node(_node) {}
+
+inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
+inline FileNode FileNode::operator[](const String& nodename) const
+{
+    return FileNode(fs, cvGetFileNodeByName(fs, node, nodename.c_str()));
+}
+inline FileNode FileNode::operator[](const char* nodename) const
+{
+    return FileNode(fs, cvGetFileNodeByName(fs, node, nodename));
+}
+
+inline FileNode FileNode::operator[](int i) const
+{
+    return isSeq() ? FileNode(fs, (CvFileNode*)cvGetSeqElem(node->data.seq, i)) :
+        i == 0 ? *this : FileNode();
+}
+
+inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
+inline bool FileNode::isNone() const { return type() == NONE; }
+inline bool FileNode::isSeq() const { return type() == SEQ; }
+inline bool FileNode::isMap() const { return type() == MAP; }
+inline bool FileNode::isInt() const { return type() == INT; }
+inline bool FileNode::isReal() const { return type() == REAL; }
+inline bool FileNode::isString() const { return type() == STR; }
+inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
+inline String FileNode::name() const
+{
+    const char* str;
+    return !node || (str = cvGetFileNodeName(node)) == 0 ? String() : String(str);
+}
+inline size_t FileNode::count() const
+{
+    int t = type();
+    return t == MAP ? ((CvSet*)node->data.map)->active_count :
+        t == SEQ ? node->data.seq->total : node != 0;
+}
+
+static inline void read(const FileNode& node, uchar& value, uchar default_value)
+{ value = saturate_cast<uchar>(cvReadInt(node.node, default_value)); }
+
+static inline void read(const FileNode& node, schar& value, schar default_value)
+{ value = saturate_cast<schar>(cvReadInt(node.node, default_value)); }
+
+static inline void read(const FileNode& node, ushort& value, ushort default_value)
+{ value = saturate_cast<ushort>(cvReadInt(node.node, default_value)); }
+
+static inline void read(const FileNode& node, short& value, short default_value)
+{ value = saturate_cast<short>(cvReadInt(node.node, default_value)); }
+
+static inline void read(const FileNode& node, int& value, int default_value)
+{ value = cvReadInt(node.node, default_value); }
+
+static inline void read(const FileNode& node, float& value, float default_value)
+{ value = (float)cvReadReal(node.node, default_value); }
+
+static inline void read(const FileNode& node, double& value, double default_value)
+{ value = cvReadReal(node.node, default_value); }
+
+static inline void read(const FileNode& node, String& value, const String& default_value)
+{ value = String(cvReadString(node.node, default_value.c_str())); }
+
+inline FileNode::operator int() const
+{
+    return cvReadInt(node, 0);
+}
+inline FileNode::operator float() const
+{
+    return (float)cvReadReal(node, 0);
+}
+inline FileNode::operator double() const
+{
+    return cvReadReal(node, 0);
+}
+inline FileNode::operator String() const
+{
+    return String(cvReadString(node, ""));
+}
+
+inline void FileNode::readRaw( const String& fmt, Vector<uchar>& vec ) const
+{
+    begin().readRaw( fmt, vec );
+}
+
+template<typename T, int numflag> struct CV_EXPORTS VecReaderProxy
+{
+    VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
+    void operator()(Vector<T>& vec, size_t count) const
+    {
+        count = std::min(count, it->remaining);
+        vec.resize(count);
+        for( size_t i = 0; i < count; i++, ++(*it) )
+            read(**it, vec[i], T());
+    }
+    FileNodeIterator* it;
+};
+
+template<typename T> struct CV_EXPORTS VecReaderProxy<T,1>
+{
+    VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
+    void operator()(Vector<T>& vec, size_t count) const
+    {
+        size_t remaining = it->remaining, cn = DataType<T>::channels;
+        int _fmt = DataType<T>::fmt;
+        char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
+        count = std::min(count, remaining/cn);
+        vec.resize(count);
+        Vector<uchar> _vec((uchar*)&*vec, count*sizeof(T), false);
+        it->readRaw( String(fmt), _vec, count );
+    }
+    FileNodeIterator* it;
+};
+
+template<typename T> static inline void
+read( FileNodeIterator& it, Vector<T>& vec, size_t maxCount=(size_t)INT_MAX )
+{
+    VecReaderProxy<T, DataType<T>::fmt != 0> r(&it);
+    r(vec, maxCount);
+}
+
+template<typename T> static inline void
+read( FileNode& node, Vector<T>& vec, const Vector<T>& /*default_value*/ )
+{
+    read( node.begin(), vec );
+}
+
+inline FileNodeIterator FileNode::begin() const
+{
+    return FileNodeIterator(fs, node);
+}
+
+inline FileNodeIterator FileNode::end() const
+{
+    return FileNodeIterator(fs, node, count());
+}
+
+inline FileNode FileNodeIterator::operator *() const
+{ return FileNode(fs, (const CvFileNode*)reader.ptr); }
+
+inline FileNode FileNodeIterator::operator ->() const
+{ return FileNode(fs, (const CvFileNode*)reader.ptr); }
+
+template<typename T> static inline FileNodeIterator& operator >> (FileNodeIterator& it, T& value)
+{ read( *it, value, T()); return ++it; }
+
+template<typename T> static inline
+FileNodeIterator& operator >> (FileNodeIterator& it, Vector<T>& vec)
+{
+    VecReaderProxy<T, DataType<T>::fmt != 0> r(&it);
+    r(vec, (size_t)INT_MAX);
+    return it;
+}
+
+template<typename T> static inline void operator >> (const FileNode& n, T& value)
+{ FileNodeIterator it = n.begin(); it >> value; }
+
+static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+    return it1.fs == it2.fs && it1.container == it2.container &&
+        it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
+}
+
+static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+    return !(it1 == it2);
+}
+
+static inline int operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+    return it2.remaining - it1.remaining;
+}
+
+static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
+{
+    return it1.remaining > it2.remaining;
+}
+
+/****************************************************************************************\
+
+  Generic implementation of QuickSort algorithm
+  Use it as: Vector<T> a; ... sort(a,<less_than_predictor>);
+
+  The current implementation was derived from *BSD system qsort():
+
+    * Copyright (c) 1992, 1993
+    *  The Regents of the University of California.  All rights reserved.
+    *
+    * Redistribution and use in source and binary forms, with or without
+    * modification, are permitted provided that the following conditions
+    * are met:
+    * 1. Redistributions of source code must retain the above copyright
+    *    notice, this list of conditions and the following disclaimer.
+    * 2. Redistributions in binary form must reproduce the above copyright
+    *    notice, this list of conditions and the following disclaimer in the
+    *    documentation and/or other materials provided with the distribution.
+    * 3. All advertising materials mentioning features or use of this software
+    *    must display the following acknowledgement:
+    *  This product includes software developed by the University of
+    *  California, Berkeley and its contributors.
+    * 4. Neither the name of the University nor the names of its contributors
+    *    may be used to endorse or promote products derived from this software
+    *    without specific prior written permission.
+    *
+    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    * SUCH DAMAGE.
+
+\****************************************************************************************/
+
+template<typename T, class _LT> void sort( Vector<T>& vec, _LT LT=_LT() )
+{
+    int isort_thresh = 7;
+    int sp = 0;
+
+    struct
+    {
+        T *lb;
+        T *ub;
+    }
+    stack[48];
+
+    T* array = &vec[0];
+    int total = vec.size();
+
+    if( total <= 1 )
+        return;
+
+    stack[0].lb = array;
+    stack[0].ub = array + (total - 1);
+
+    while( sp >= 0 )
+    {
+        T* left = stack[sp].lb;
+        T* right = stack[sp--].ub;
+
+        for(;;)
+        {
+            int i, n = (int)(right - left) + 1, m;
+            T* ptr;
+            T* ptr2;
+
+            if( n <= isort_thresh )
+            {
+            insert_sort:
+                for( ptr = left + 1; ptr <= right; ptr++ )
+                {
+                    for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)
+                        std::swap( ptr2[0], ptr2[-1] );
+                }
+                break;
+            }
+            else
+            {
+                T* left0;
+                T* left1;
+                T* right0;
+                T* right1;
+                T* pivot;
+                T* a;
+                T* b;
+                T* c;
+                int swap_cnt = 0;
+
+                left0 = left;
+                right0 = right;
+                pivot = left + (n/2);
+
+                if( n > 40 )
+                {
+                    int d = n / 8;
+                    a = left, b = left + d, c = left + 2*d;
+                    left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
+                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
+
+                    a = pivot - d, b = pivot, c = pivot + d;
+                    pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
+                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
+
+                    a = right - 2*d, b = right - d, c = right;
+                    right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
+                                      : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
+                }
+
+                a = left, b = pivot, c = right;
+                pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
+                                   : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
+                if( pivot != left0 )
+                {
+                    std::swap( *pivot, *left0 );
+                    pivot = left0;
+                }
+                left = left1 = left0 + 1;
+                right = right1 = right0;
+
+                for(;;)
+                {
+                    while( left <= right && !LT(*pivot, *left) )
+                    {
+                        if( !LT(*left, *pivot) )
+                        {
+                            if( left > left1 )
+                                std::swap( *left1, *left );
+                            swap_cnt = 1;
+                            left1++;
+                        }
+                        left++;
+                    }
+
+                    while( left <= right && !LT(*right, *pivot) )
+                    {
+                        if( !LT(*pivot, *right) )
+                        {
+                            if( right < right1 )
+                                std::swap( *right1, *right );
+                            swap_cnt = 1;
+                            right1--;
+                        }
+                        right--;
+                    }
+
+                    if( left > right )
+                        break;
+                    std::swap( *left, *right );
+                    swap_cnt = 1;
+                    left++;
+                    right--;
+                }
+
+                if( swap_cnt == 0 )
+                {
+                    left = left0, right = right0;
+                    goto insert_sort;
+                }
+
+                n = MIN( (int)(left1 - left0), (int)(left - left1) );
+                for( i = 0; i < n; i++ )
+                    std::swap( left0[i], left[i-n] );
+
+                n = MIN( (int)(right0 - right1), (int)(right1 - right) );
+                for( i = 0; i < n; i++ )
+                    std::swap( left[i], right0[i-n+1] );
+                n = (int)(left - left1);
+                m = (int)(right1 - right);
+                if( n > 1 )
+                {
+                    if( m > 1 )
+                    {
+                        if( n > m )
+                        {
+                            stack[++sp].lb = left0;
+                            stack[sp].ub = left0 + n - 1;
+                            left = right0 - m + 1, right = right0;
+                        }
+                        else
+                        {
+                            stack[++sp].lb = right0 - m + 1;
+                            stack[sp].ub = right0;
+                            left = left0, right = left0 + n - 1;
+                        }
+                    }
+                    else
+                        left = left0, right = left0 + n - 1;
+                }
+                else if( m > 1 )
+                    left = right0 - m + 1, right = right0;
+                else
+                    break;
+            }
+        }
+    }
+}
+
+template<typename T> struct CV_EXPORTS LessThan
+{
+    bool operator()(const T& a, const T& b) const { return a < b; }
+};
+
+template<typename T> struct CV_EXPORTS GreaterEq
+{
+    bool operator()(const T& a, const T& b) const { return a >= b; }
+};
+
+template<typename T> struct CV_EXPORTS LessThanIdx
+{
+    LessThanIdx( const T* _arr ) : arr(_arr) {}
+    bool operator()(int a, int b) const { return arr[a] < arr[b]; }
+    const T* arr;
+};
+
+template<typename T> struct CV_EXPORTS GreaterEqIdx
+{
+    GreaterEqIdx( const T* _arr ) : arr(_arr) {}
+    bool operator()(int a, int b) const { return arr[a] >= arr[b]; }
+    const T* arr;
+};
+
+}
+
+#endif
+#endif
index 35b578907eb26f1b387f95fd24db8fb7d59dd948..7042e0739b741fa60260abf45721d47b33ade81f 100644 (file)
-/*M///////////////////////////////////////////////////////////////////////////////////////
-//
-//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-//
-//  By downloading, copying, installing or using the software you agree to this license.
-//  If you do not agree to this license, do not download, install,
-//  copy or use the software.
-//
-//
-//                        Intel License Agreement
-//                For Open Source Computer Vision Library
-//
-// Copyright (C) 2000, Intel Corporation, all rights reserved.
-// Third party copyrights are property of their respective owners.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-//   * Redistribution's of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//
-//   * Redistribution's in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//
-//   * The name of Intel Corporation may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// This software is provided by the copyright holders and contributors "as is" and
-// any express or implied warranties, including, but not limited to, the implied
-// warranties of merchantability and fitness for a particular purpose are disclaimed.
-// In no event shall the Intel Corporation or contributors be liable for any direct,
-// indirect, incidental, special, exemplary, or consequential damages
-// (including, but not limited to, procurement of substitute goods or services;
-// loss of use, data, or profits; or business interruption) however caused
-// and on any theory of liability, whether in contract, strict liability,
-// or tort (including negligence or otherwise) arising in any way out of
-// the use of this software, even if advised of the possibility of such damage.
-//
-//M*/
-
-#ifndef _CXCORE_TYPES_H_
-#define _CXCORE_TYPES_H_
-
-#if !defined _CRT_SECURE_NO_DEPRECATE && _MSC_VER > 1300
-#define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio 2005 warnings */
-#endif
-
-#ifndef SKIP_INCLUDES
-  #include <assert.h>
-  #include <stdlib.h>
-  #include <string.h>
-  #include <float.h>
-
-  #if defined __ICL
-    #define CV_ICC   __ICL
-  #elif defined __ICC
-    #define CV_ICC   __ICC
-  #elif defined __ECL
-    #define CV_ICC   __ECL
-  #elif defined __ECC
-    #define CV_ICC   __ECC
-  #endif
-
-  #if defined WIN32 && (!defined WIN64 || defined EM64T) && \
-      (_MSC_VER >= 1400 || defined CV_ICC) \
-      || (defined __SSE2__ && defined __GNUC__ && __GNUC__ >= 4)
-    #include <emmintrin.h>
-    #define CV_SSE2 1
-  #else
-    #define CV_SSE2 0
-  #endif
-
-  #if ((defined __SSE__ || defined __MMX__) && defined __GNUC__ && __GNUC__ >= 3)
-    #include <mmintrin.h>
-  #endif
-
-  #if defined __BORLANDC__
-    #include <fastmath.h>
-  #elif defined WIN64 && !defined EM64T && defined CV_ICC
-    #include <mathimf.h>
-  #else
-    #include <math.h>
-  #endif
-
-  #ifdef HAVE_IPL
-      #ifndef __IPL_H__
-          #if defined WIN32 || defined WIN64
-              #include <ipl.h>
-          #else
-              #include <ipl/ipl.h>
-          #endif
-      #endif
-  #elif defined __IPL_H__
-      #define HAVE_IPL
-  #endif
-#endif // SKIP_INCLUDES
-
-#if defined WIN32 || defined WIN64
-    #define CV_CDECL __cdecl
-    #define CV_STDCALL __stdcall
-#else
-    #define CV_CDECL
-    #define CV_STDCALL
-#endif
-
-#ifndef CV_EXTERN_C
-    #ifdef __cplusplus
-        #define CV_EXTERN_C extern "C"
-        #define CV_DEFAULT(val) = val
-    #else
-        #define CV_EXTERN_C
-        #define CV_DEFAULT(val)
-    #endif
-#endif
-
-#ifndef CV_EXTERN_C_FUNCPTR
-    #ifdef __cplusplus
-        #define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; }
-    #else
-        #define CV_EXTERN_C_FUNCPTR(x) typedef x
-    #endif
-#endif
-
-#ifndef CV_INLINE
-#if defined __cplusplus
-    #define CV_INLINE inline
-#elif (defined WIN32 || defined WIN64 || defined WINCE) && !defined __GNUC__
-    #define CV_INLINE __inline
-#else
-    #define CV_INLINE static
-#endif
-#endif /* CV_INLINE */
-
-#if (defined WIN32 || defined WIN64 || defined WINCE) && defined CVAPI_EXPORTS
-    #define CV_EXPORTS __declspec(dllexport)
-#else
-    #define CV_EXPORTS
-#endif
-
-#ifndef CVAPI
-    #define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL
-#endif
-
-#if defined _MSC_VER || defined __BORLANDC__
-typedef __int64 int64;
-typedef unsigned __int64 uint64;
-#else
-typedef long long int64;
-typedef unsigned long long uint64;
-#endif
-
-#ifndef HAVE_IPL
-typedef unsigned char uchar;
-typedef unsigned short ushort;
-#endif
-
-typedef signed char schar;
-
-/* CvArr* is used to pass arbitrary
- * array-like data structures
- * into functions where the particular
- * array type is recognized at runtime:
- */
-typedef void CvArr;
-
-typedef union Cv32suf
-{
-    int i;
-    unsigned u;
-    float f;
-}
-Cv32suf;
-
-typedef union Cv64suf
-{
-    int64 i;
-    uint64 u;
-    double f;
-}
-Cv64suf;
-
-/****************************************************************************************\
-*                             Common macros and inline functions                         *
-\****************************************************************************************/
-
-#define CV_PI   3.1415926535897932384626433832795
-#define CV_LOG2 0.69314718055994530941723212145818
-
-#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))
-
-#ifndef MIN
-#define MIN(a,b)  ((a) > (b) ? (b) : (a))
-#endif
-
-#ifndef MAX
-#define MAX(a,b)  ((a) < (b) ? (b) : (a))
-#endif
-
-/* min & max without jumps */
-#define  CV_IMIN(a, b)  ((a) ^ (((a)^(b)) & (((a) < (b)) - 1)))
-
-#define  CV_IMAX(a, b)  ((a) ^ (((a)^(b)) & (((a) > (b)) - 1)))
-
-/* absolute value without jumps */
-#ifndef __cplusplus
-#define  CV_IABS(a)     (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))
-#else
-#define  CV_IABS(a)     abs(a)
-#endif
-#define  CV_CMP(a,b)    (((a) > (b)) - ((a) < (b)))
-#define  CV_SIGN(a)     CV_CMP((a),0)
-
-CV_INLINE  int  cvRound( double value )
-{
-#if CV_SSE2
-    __m128d t = _mm_load_sd( &value );
-    return _mm_cvtsd_si32(t);
-#elif defined WIN32 && !defined WIN64 && defined _MSC_VER
-    int t;
-    __asm
-    {
-        fld value;
-        fistp t;
-    }
-    return t;
-#elif (defined HAVE_LRINT) || (defined WIN64 && !defined EM64T && defined CV_ICC)
-    return (int)lrint(value);
-#else
-    /*
-     the algorithm was taken from Agner Fog's optimization guide
-     at http://www.agner.org/assem
-     */
-    Cv64suf temp;
-    temp.f = value + 6755399441055744.0;
-    return (int)temp.u;
-#endif
-}
-
-
-CV_INLINE  int  cvFloor( double value )
-{
-#if CV_SSE2
-    __m128d t = _mm_load_sd( &value );
-    int i = _mm_cvtsd_si32(t);
-    return i - _mm_movemask_pd(_mm_cmplt_sd(t,_mm_cvtsi32_sd(t,i)));
-#else
-    int temp = cvRound(value);
-    Cv32suf diff;
-    diff.f = (float)(value - temp);
-    return temp - (diff.i < 0);
-#endif
-}
-
-
-CV_INLINE  int  cvCeil( double value )
-{
-#if CV_SSE2
-    __m128d t = _mm_load_sd( &value );
-    int i = _mm_cvtsd_si32(t);
-    return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i),t));
-#else
-    int temp = cvRound(value);
-    Cv32suf diff;
-    diff.f = (float)(temp - value);
-    return temp + (diff.i < 0);
-#endif
-}
-
-#define cvInvSqrt(value) ((float)(1./sqrt(value)))
-#define cvSqrt(value)  ((float)sqrt(value))
-
-CV_INLINE int cvIsNaN( double value )
-{
-#if 1/*defined _MSC_VER || defined __BORLANDC__
-    return _isnan(value);
-#elif defined __GNUC__
-    return isnan(value);
-#else*/
-    Cv64suf ieee754;
-    ieee754.f = value;
-    return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
-           ((unsigned)ieee754.u != 0) > 0x7ff00000;
-#endif
-}
-
-
-CV_INLINE int cvIsInf( double value )
-{
-#if 1/*defined _MSC_VER || defined __BORLANDC__
-    return !_finite(value);
-#elif defined __GNUC__
-    return isinf(value);
-#else*/
-    Cv64suf ieee754;
-    ieee754.f = value;
-    return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
-           (unsigned)ieee754.u == 0;
-#endif
-}
-
-
-/*************** Random number generation *******************/
-
-typedef uint64 CvRNG;
-
-CV_INLINE CvRNG cvRNG( int64 seed CV_DEFAULT(-1))
-{
-    CvRNG rng = seed ? (uint64)seed : (uint64)(int64)-1;
-    return rng;
-}
-
-/* Return random 32-bit unsigned integer: */
-CV_INLINE unsigned cvRandInt( CvRNG* rng )
-{
-    uint64 temp = *rng;
-    temp = (uint64)(unsigned)temp*1554115554 + (temp >> 32);
-    *rng = temp;
-    return (unsigned)temp;
-}
-
-/* Returns random floating-point number between 0 and 1: */
-CV_INLINE double cvRandReal( CvRNG* rng )
-{
-    return cvRandInt(rng)*2.3283064365386962890625e-10 /* 2^-32 */;
-}
-
-/****************************************************************************************\
-*                                  Image type (IplImage)                                 *
-\****************************************************************************************/
-
-#ifndef HAVE_IPL
-
-/*
- * The following definitions (until #endif)
- * is an extract from IPL headers.
- * Copyright (c) 1995 Intel Corporation.
- */
-#define IPL_DEPTH_SIGN 0x80000000
-
-#define IPL_DEPTH_1U     1
-#define IPL_DEPTH_8U     8
-#define IPL_DEPTH_16U   16
-#define IPL_DEPTH_32F   32
-
-#define IPL_DEPTH_8S  (IPL_DEPTH_SIGN| 8)
-#define IPL_DEPTH_16S (IPL_DEPTH_SIGN|16)
-#define IPL_DEPTH_32S (IPL_DEPTH_SIGN|32)
-
-#define IPL_DATA_ORDER_PIXEL  0
-#define IPL_DATA_ORDER_PLANE  1
-
-#define IPL_ORIGIN_TL 0
-#define IPL_ORIGIN_BL 1
-
-#define IPL_ALIGN_4BYTES   4
-#define IPL_ALIGN_8BYTES   8
-#define IPL_ALIGN_16BYTES 16
-#define IPL_ALIGN_32BYTES 32
-
-#define IPL_ALIGN_DWORD   IPL_ALIGN_4BYTES
-#define IPL_ALIGN_QWORD   IPL_ALIGN_8BYTES
-
-#define IPL_BORDER_CONSTANT   0
-#define IPL_BORDER_REPLICATE  1
-#define IPL_BORDER_REFLECT    2
-#define IPL_BORDER_WRAP       3
-
-typedef struct _IplImage
-{
-    int  nSize;             /* sizeof(IplImage) */
-    int  ID;                /* version (=0)*/
-    int  nChannels;         /* Most of OpenCV functions support 1,2,3 or 4 channels */
-    int  alphaChannel;      /* Ignored by OpenCV */
-    int  depth;             /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
-                               IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.  */
-    char colorModel[4];     /* Ignored by OpenCV */
-    char channelSeq[4];     /* ditto */
-    int  dataOrder;         /* 0 - interleaved color channels, 1 - separate color channels.
-                               cvCreateImage can only create interleaved images */
-    int  origin;            /* 0 - top-left origin,
-                               1 - bottom-left origin (Windows bitmaps style).  */
-    int  align;             /* Alignment of image rows (4 or 8).
-                               OpenCV ignores it and uses widthStep instead.    */
-    int  width;             /* Image width in pixels.                           */
-    int  height;            /* Image height in pixels.                          */
-    struct _IplROI *roi;    /* Image ROI. If NULL, the whole image is selected. */
-    struct _IplImage *maskROI;      /* Must be NULL. */
-    void  *imageId;                 /* "           " */
-    struct _IplTileInfo *tileInfo;  /* "           " */
-    int  imageSize;         /* Image data size in bytes
-                               (==image->height*image->widthStep
-                               in case of interleaved data)*/
-    char *imageData;        /* Pointer to aligned image data.         */
-    int  widthStep;         /* Size of aligned image row in bytes.    */
-    int  BorderMode[4];     /* Ignored by OpenCV.                     */
-    int  BorderConst[4];    /* Ditto.                                 */
-    char *imageDataOrigin;  /* Pointer to very origin of image data
-                               (not necessarily aligned) -
-                               needed for correct deallocation */
-}
-IplImage;
-
-typedef struct _IplTileInfo IplTileInfo;
-
-typedef struct _IplROI
-{
-    int  coi; /* 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/
-    int  xOffset;
-    int  yOffset;
-    int  width;
-    int  height;
-}
-IplROI;
-
-typedef struct _IplConvKernel
-{
-    int  nCols;
-    int  nRows;
-    int  anchorX;
-    int  anchorY;
-    int *values;
-    int  nShiftR;
-}
-IplConvKernel;
-
-typedef struct _IplConvKernelFP
-{
-    int  nCols;
-    int  nRows;
-    int  anchorX;
-    int  anchorY;
-    float *values;
-}
-IplConvKernelFP;
-
-#define IPL_IMAGE_HEADER 1
-#define IPL_IMAGE_DATA   2
-#define IPL_IMAGE_ROI    4
-
-#endif/*HAVE_IPL*/
-
-/* extra border mode */
-#define IPL_BORDER_REFLECT_101    4
-
-#define IPL_IMAGE_MAGIC_VAL  ((int)sizeof(IplImage))
-#define CV_TYPE_NAME_IMAGE "opencv-image"
-
-#define CV_IS_IMAGE_HDR(img) \
-    ((img) != NULL && ((const IplImage*)(img))->nSize == sizeof(IplImage))
-
-#define CV_IS_IMAGE(img) \
-    (CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->imageData != NULL)
-
-/* for storing double-precision
-   floating point data in IplImage's */
-#define IPL_DEPTH_64F  64
-
-/* get reference to pixel at (col,row),
-   for multi-channel images (col) should be multiplied by number of channels */
-#define CV_IMAGE_ELEM( image, elemtype, row, col )       \
-    (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])
-
-/****************************************************************************************\
-*                                  Matrix type (CvMat)                                   *
-\****************************************************************************************/
-
-#define CV_CN_MAX     64
-#define CV_CN_SHIFT   3
-#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)
-
-#define CV_8U   0
-#define CV_8S   1
-#define CV_16U  2
-#define CV_16S  3
-#define CV_32S  4
-#define CV_32F  5
-#define CV_64F  6
-#define CV_USRTYPE1 7
-
-#define CV_MAKETYPE(depth,cn) ((depth) + (((cn)-1) << CV_CN_SHIFT))
-#define CV_MAKE_TYPE CV_MAKETYPE
-
-#define CV_8UC1 CV_MAKETYPE(CV_8U,1)
-#define CV_8UC2 CV_MAKETYPE(CV_8U,2)
-#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
-#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
-#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
-
-#define CV_8SC1 CV_MAKETYPE(CV_8S,1)
-#define CV_8SC2 CV_MAKETYPE(CV_8S,2)
-#define CV_8SC3 CV_MAKETYPE(CV_8S,3)
-#define CV_8SC4 CV_MAKETYPE(CV_8S,4)
-#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))
-
-#define CV_16UC1 CV_MAKETYPE(CV_16U,1)
-#define CV_16UC2 CV_MAKETYPE(CV_16U,2)
-#define CV_16UC3 CV_MAKETYPE(CV_16U,3)
-#define CV_16UC4 CV_MAKETYPE(CV_16U,4)
-#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))
-
-#define CV_16SC1 CV_MAKETYPE(CV_16S,1)
-#define CV_16SC2 CV_MAKETYPE(CV_16S,2)
-#define CV_16SC3 CV_MAKETYPE(CV_16S,3)
-#define CV_16SC4 CV_MAKETYPE(CV_16S,4)
-#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))
-
-#define CV_32SC1 CV_MAKETYPE(CV_32S,1)
-#define CV_32SC2 CV_MAKETYPE(CV_32S,2)
-#define CV_32SC3 CV_MAKETYPE(CV_32S,3)
-#define CV_32SC4 CV_MAKETYPE(CV_32S,4)
-#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))
-
-#define CV_32FC1 CV_MAKETYPE(CV_32F,1)
-#define CV_32FC2 CV_MAKETYPE(CV_32F,2)
-#define CV_32FC3 CV_MAKETYPE(CV_32F,3)
-#define CV_32FC4 CV_MAKETYPE(CV_32F,4)
-#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))
-
-#define CV_64FC1 CV_MAKETYPE(CV_64F,1)
-#define CV_64FC2 CV_MAKETYPE(CV_64F,2)
-#define CV_64FC3 CV_MAKETYPE(CV_64F,3)
-#define CV_64FC4 CV_MAKETYPE(CV_64F,4)
-#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))
-
-#define CV_AUTO_STEP  0x7fffffff
-#define CV_WHOLE_ARR  cvSlice( 0, 0x3fffffff )
-
-#define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)
-#define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
-#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)
-#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)
-#define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)
-#define CV_MAT_TYPE(flags)      ((flags) & CV_MAT_TYPE_MASK)
-#define CV_MAT_CONT_FLAG_SHIFT  14
-#define CV_MAT_CONT_FLAG        (1 << CV_MAT_CONT_FLAG_SHIFT)
-#define CV_IS_MAT_CONT(flags)   ((flags) & CV_MAT_CONT_FLAG)
-#define CV_IS_CONT_MAT          CV_IS_MAT_CONT
-#define CV_MAT_TEMP_FLAG_SHIFT  15
-#define CV_MAT_TEMP_FLAG        (1 << CV_MAT_TEMP_FLAG_SHIFT)
-#define CV_IS_TEMP_MAT(flags)   ((flags) & CV_MAT_TEMP_FLAG)
-
-#define CV_MAGIC_MASK       0xFFFF0000
-#define CV_MAT_MAGIC_VAL    0x42420000
-#define CV_TYPE_NAME_MAT    "opencv-matrix"
-
-typedef struct CvMat
-{
-    int type;
-    int step;
-
-    /* for internal use only */
-    int* refcount;
-    int hdr_refcount;
-
-    union
-    {
-        uchar* ptr;
-        short* s;
-        int* i;
-        float* fl;
-        double* db;
-    } data;
-
-#ifdef __cplusplus
-    union
-    {
-        int rows;
-        int height;
-    };
-
-    union
-    {
-        int cols;
-        int width;
-    };
-#else
-    int rows;
-    int cols;
-#endif
-
-}
-CvMat;
-
-
-#define CV_IS_MAT_HDR(mat) \
-    ((mat) != NULL && \
-    (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \
-    ((const CvMat*)(mat))->cols > 0 && ((const CvMat*)(mat))->rows > 0)
-
-#define CV_IS_MAT(mat) \
-    (CV_IS_MAT_HDR(mat) && ((const CvMat*)(mat))->data.ptr != NULL)
-
-#define CV_IS_MASK_ARR(mat) \
-    (((mat)->type & (CV_MAT_TYPE_MASK & ~CV_8SC1)) == 0)
-
-#define CV_ARE_TYPES_EQ(mat1, mat2) \
-    ((((mat1)->type ^ (mat2)->type) & CV_MAT_TYPE_MASK) == 0)
-
-#define CV_ARE_CNS_EQ(mat1, mat2) \
-    ((((mat1)->type ^ (mat2)->type) & CV_MAT_CN_MASK) == 0)
-
-#define CV_ARE_DEPTHS_EQ(mat1, mat2) \
-    ((((mat1)->type ^ (mat2)->type) & CV_MAT_DEPTH_MASK) == 0)
-
-#define CV_ARE_SIZES_EQ(mat1, mat2) \
-    ((mat1)->rows == (mat2)->rows && (mat1)->cols == (mat2)->cols)
-
-#define CV_IS_MAT_CONST(mat)  \
-    (((mat)->rows|(mat)->cols) == 1)
-
-/* Size of each channel item,
-   0x124489 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */
-#define CV_ELEM_SIZE1(type) \
-    ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15)
-
-/* 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */
-#define CV_ELEM_SIZE(type) \
-    (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3))
-
-/* Inline constructor. No data is allocated internally!!!
- * (Use together with cvCreateData, or use cvCreateMat instead to
- * get a matrix with allocated data):
- */
-CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))
-{
-    CvMat m;
-
-    assert( (unsigned)CV_MAT_DEPTH(type) <= CV_64F );
-    type = CV_MAT_TYPE(type);
-    m.type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | type;
-    m.cols = cols;
-    m.rows = rows;
-    m.step = rows > 1 ? m.cols*CV_ELEM_SIZE(type) : 0;
-    m.data.ptr = (uchar*)data;
-    m.refcount = NULL;
-    m.hdr_refcount = 0;
-
-    return m;
-}
-
-
-#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size )  \
-    (assert( (unsigned)(row) < (unsigned)(mat).rows &&   \
-             (unsigned)(col) < (unsigned)(mat).cols ),   \
-     (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))
-
-#define CV_MAT_ELEM_PTR( mat, row, col )                 \
-    CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) )
-
-#define CV_MAT_ELEM( mat, elemtype, row, col )           \
-    (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))
-
-
-CV_INLINE  double  cvmGet( const CvMat* mat, int row, int col )
-{
-    int type;
-
-    type = CV_MAT_TYPE(mat->type);
-    assert( (unsigned)row < (unsigned)mat->rows &&
-            (unsigned)col < (unsigned)mat->cols );
-
-    if( type == CV_32FC1 )
-        return ((float*)(mat->data.ptr + (size_t)mat->step*row))[col];
-    else
-    {
-        assert( type == CV_64FC1 );
-        return ((double*)(mat->data.ptr + (size_t)mat->step*row))[col];
-    }
-}
-
-
-CV_INLINE  void  cvmSet( CvMat* mat, int row, int col, double value )
-{
-    int type;
-    type = CV_MAT_TYPE(mat->type);
-    assert( (unsigned)row < (unsigned)mat->rows &&
-            (unsigned)col < (unsigned)mat->cols );
-
-    if( type == CV_32FC1 )
-        ((float*)(mat->data.ptr + (size_t)mat->step*row))[col] = (float)value;
-    else
-    {
-        assert( type == CV_64FC1 );
-        ((double*)(mat->data.ptr + (size_t)mat->step*row))[col] = (double)value;
-    }
-}
-
-
-CV_INLINE int cvCvToIplDepth( int type )
-{
-    int depth = CV_MAT_DEPTH(type);
-    return CV_ELEM_SIZE1(depth)*8 | (depth == CV_8S || depth == CV_16S ||
-           depth == CV_32S ? IPL_DEPTH_SIGN : 0);
-}
-
-
-/****************************************************************************************\
-*                       Multi-dimensional dense array (CvMatND)                          *
-\****************************************************************************************/
-
-#define CV_MATND_MAGIC_VAL    0x42430000
-#define CV_TYPE_NAME_MATND    "opencv-nd-matrix"
-
-#define CV_MAX_DIM            32
-#define CV_MAX_DIM_HEAP       (1 << 16)
-
-typedef struct CvMatND
-{
-    int type;
-    int dims;
-
-    int* refcount;
-    int hdr_refcount;
-
-    union
-    {
-        uchar* ptr;
-        float* fl;
-        double* db;
-        int* i;
-        short* s;
-    } data;
-
-    struct
-    {
-        int size;
-        int step;
-    }
-    dim[CV_MAX_DIM];
-}
-CvMatND;
-
-#define CV_IS_MATND_HDR(mat) \
-    ((mat) != NULL && (((const CvMatND*)(mat))->type & CV_MAGIC_MASK) == CV_MATND_MAGIC_VAL)
-
-#define CV_IS_MATND(mat) \
-    (CV_IS_MATND_HDR(mat) && ((const CvMatND*)(mat))->data.ptr != NULL)
-
-
-/****************************************************************************************\
-*                      Multi-dimensional sparse array (CvSparseMat)                      *
-\****************************************************************************************/
-
-#define CV_SPARSE_MAT_MAGIC_VAL    0x42440000
-#define CV_TYPE_NAME_SPARSE_MAT    "opencv-sparse-matrix"
-
-struct CvSet;
-
-typedef struct CvSparseMat
-{
-    int type;
-    int dims;
-    int* refcount;
-    int hdr_refcount;
-
-    struct CvSet* heap;
-    void** hashtable;
-    int hashsize;
-    int valoffset;
-    int idxoffset;
-    int size[CV_MAX_DIM];
-}
-CvSparseMat;
-
-#define CV_IS_SPARSE_MAT_HDR(mat) \
-    ((mat) != NULL && \
-    (((const CvSparseMat*)(mat))->type & CV_MAGIC_MASK) == CV_SPARSE_MAT_MAGIC_VAL)
-
-#define CV_IS_SPARSE_MAT(mat) \
-    CV_IS_SPARSE_MAT_HDR(mat)
-
-/**************** iteration through a sparse array *****************/
-
-typedef struct CvSparseNode
-{
-    unsigned hashval;
-    struct CvSparseNode* next;
-}
-CvSparseNode;
-
-typedef struct CvSparseMatIterator
-{
-    CvSparseMat* mat;
-    CvSparseNode* node;
-    int curidx;
-}
-CvSparseMatIterator;
-
-#define CV_NODE_VAL(mat,node)   ((void*)((uchar*)(node) + (mat)->valoffset))
-#define CV_NODE_IDX(mat,node)   ((int*)((uchar*)(node) + (mat)->idxoffset))
-
-/****************************************************************************************\
-*                                         Histogram                                      *
-\****************************************************************************************/
-
-typedef int CvHistType;
-
-#define CV_HIST_MAGIC_VAL     0x42450000
-#define CV_HIST_UNIFORM_FLAG  (1 << 10)
-
-/* indicates whether bin ranges are set already or not */
-#define CV_HIST_RANGES_FLAG   (1 << 11)
-
-#define CV_HIST_ARRAY         0
-#define CV_HIST_SPARSE        1
-#define CV_HIST_TREE          CV_HIST_SPARSE
-
-/* should be used as a parameter only,
-   it turns to CV_HIST_UNIFORM_FLAG of hist->type */
-#define CV_HIST_UNIFORM       1
-
-typedef struct CvHistogram
-{
-    int     type;
-    CvArr*  bins;
-    float   thresh[CV_MAX_DIM][2];  /* For uniform histograms.                      */
-    float** thresh2;                /* For non-uniform histograms.                  */
-    CvMatND mat;                    /* Embedded matrix header for array histograms. */
-}
-CvHistogram;
-
-#define CV_IS_HIST( hist ) \
-    ((hist) != NULL  && \
-     (((CvHistogram*)(hist))->type & CV_MAGIC_MASK) == CV_HIST_MAGIC_VAL && \
-     (hist)->bins != NULL)
-
-#define CV_IS_UNIFORM_HIST( hist ) \
-    (((hist)->type & CV_HIST_UNIFORM_FLAG) != 0)
-
-#define CV_IS_SPARSE_HIST( hist ) \
-    CV_IS_SPARSE_MAT((hist)->bins)
-
-#define CV_HIST_HAS_RANGES( hist ) \
-    (((hist)->type & CV_HIST_RANGES_FLAG) != 0)
-
-/****************************************************************************************\
-*                      Other supplementary data type definitions                         *
-\****************************************************************************************/
-
-/*************************************** CvRect *****************************************/
-
-typedef struct CvRect
-{
-    int x;
-    int y;
-    int width;
-    int height;
-}
-CvRect;
-
-CV_INLINE  CvRect  cvRect( int x, int y, int width, int height )
-{
-    CvRect r;
-
-    r.x = x;
-    r.y = y;
-    r.width = width;
-    r.height = height;
-
-    return r;
-}
-
-
-CV_INLINE  IplROI  cvRectToROI( CvRect rect, int coi )
-{
-    IplROI roi;
-    roi.xOffset = rect.x;
-    roi.yOffset = rect.y;
-    roi.width = rect.width;
-    roi.height = rect.height;
-    roi.coi = coi;
-
-    return roi;
-}
-
-
-CV_INLINE  CvRect  cvROIToRect( IplROI roi )
-{
-    return cvRect( roi.xOffset, roi.yOffset, roi.width, roi.height );
-}
-
-/*********************************** CvTermCriteria *************************************/
-
-#define CV_TERMCRIT_ITER    1
-#define CV_TERMCRIT_NUMBER  CV_TERMCRIT_ITER
-#define CV_TERMCRIT_EPS     2
-
-typedef struct CvTermCriteria
-{
-    int    type;  /* may be combination of
-                     CV_TERMCRIT_ITER
-                     CV_TERMCRIT_EPS */
-    int    max_iter;
-    double epsilon;
-}
-CvTermCriteria;
-
-CV_INLINE  CvTermCriteria  cvTermCriteria( int type, int max_iter, double epsilon )
-{
-    CvTermCriteria t;
-
-    t.type = type;
-    t.max_iter = max_iter;
-    t.epsilon = (float)epsilon;
-
-    return t;
-}
-
-
-/******************************* CvPoint and variants ***********************************/
-
-typedef struct CvPoint
-{
-    int x;
-    int y;
-}
-CvPoint;
-
-
-CV_INLINE  CvPoint  cvPoint( int x, int y )
-{
-    CvPoint p;
-
-    p.x = x;
-    p.y = y;
-
-    return p;
-}
-
-
-typedef struct CvPoint2D32f
-{
-    float x;
-    float y;
-}
-CvPoint2D32f;
-
-
-CV_INLINE  CvPoint2D32f  cvPoint2D32f( double x, double y )
-{
-    CvPoint2D32f p;
-
-    p.x = (float)x;
-    p.y = (float)y;
-
-    return p;
-}
-
-
-CV_INLINE  CvPoint2D32f  cvPointTo32f( CvPoint point )
-{
-    return cvPoint2D32f( (float)point.x, (float)point.y );
-}
-
-
-CV_INLINE  CvPoint  cvPointFrom32f( CvPoint2D32f point )
-{
-    CvPoint ipt;
-    ipt.x = cvRound(point.x);
-    ipt.y = cvRound(point.y);
-
-    return ipt;
-}
-
-
-typedef struct CvPoint3D32f
-{
-    float x;
-    float y;
-    float z;
-}
-CvPoint3D32f;
-
-
-CV_INLINE  CvPoint3D32f  cvPoint3D32f( double x, double y, double z )
-{
-    CvPoint3D32f p;
-
-    p.x = (float)x;
-    p.y = (float)y;
-    p.z = (float)z;
-
-    return p;
-}
-
-
-typedef struct CvPoint2D64f
-{
-    double x;
-    double y;
-}
-CvPoint2D64f;
-
-
-CV_INLINE  CvPoint2D64f  cvPoint2D64f( double x, double y )
-{
-    CvPoint2D64f p;
-
-    p.x = x;
-    p.y = y;
-
-    return p;
-}
-
-
-typedef struct CvPoint3D64f
-{
-    double x;
-    double y;
-    double z;
-}
-CvPoint3D64f;
-
-
-CV_INLINE  CvPoint3D64f  cvPoint3D64f( double x, double y, double z )
-{
-    CvPoint3D64f p;
-
-    p.x = x;
-    p.y = y;
-    p.z = z;
-
-    return p;
-}
-
-
-/******************************** CvSize's & CvBox **************************************/
-
-typedef struct
-{
-    int width;
-    int height;
-}
-CvSize;
-
-CV_INLINE  CvSize  cvSize( int width, int height )
-{
-    CvSize s;
-
-    s.width = width;
-    s.height = height;
-
-    return s;
-}
-
-typedef struct CvSize2D32f
-{
-    float width;
-    float height;
-}
-CvSize2D32f;
-
-
-CV_INLINE  CvSize2D32f  cvSize2D32f( double width, double height )
-{
-    CvSize2D32f s;
-
-    s.width = (float)width;
-    s.height = (float)height;
-
-    return s;
-}
-
-typedef struct CvBox2D
-{
-    CvPoint2D32f center;  /* Center of the box.                          */
-    CvSize2D32f  size;    /* Box width and length.                       */
-    float angle;          /* Angle between the horizontal axis           */
-                          /* and the first side (i.e. length) in degrees */
-}
-CvBox2D;
-
-
-/* Line iterator state: */
-typedef struct CvLineIterator
-{
-    /* Pointer to the current point: */
-    uchar* ptr;
-
-    /* Bresenham algorithm state: */
-    int  err;
-    int  plus_delta;
-    int  minus_delta;
-    int  plus_step;
-    int  minus_step;
-}
-CvLineIterator;
-
-
-
-/************************************* CvSlice ******************************************/
-
-typedef struct CvSlice
-{
-    int  start_index, end_index;
-}
-CvSlice;
-
-CV_INLINE  CvSlice  cvSlice( int start, int end )
-{
-    CvSlice slice;
-    slice.start_index = start;
-    slice.end_index = end;
-
-    return slice;
-}
-
-#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff
-#define CV_WHOLE_SEQ  cvSlice(0, CV_WHOLE_SEQ_END_INDEX)
-
-
-/************************************* CvScalar *****************************************/
-
-typedef struct CvScalar
-{
-    double val[4];
-}
-CvScalar;
-
-CV_INLINE  CvScalar  cvScalar( double val0, double val1 CV_DEFAULT(0),
-                               double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0))
-{
-    CvScalar scalar;
-    scalar.val[0] = val0; scalar.val[1] = val1;
-    scalar.val[2] = val2; scalar.val[3] = val3;
-    return scalar;
-}
-
-
-CV_INLINE  CvScalar  cvRealScalar( double val0 )
-{
-    CvScalar scalar;
-    scalar.val[0] = val0;
-    scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
-    return scalar;
-}
-
-CV_INLINE  CvScalar  cvScalarAll( double val0123 )
-{
-    CvScalar scalar;
-    scalar.val[0] = val0123;
-    scalar.val[1] = val0123;
-    scalar.val[2] = val0123;
-    scalar.val[3] = val0123;
-    return scalar;
-}
-
-/****************************************************************************************\
-*                                   Dynamic Data structures                              *
-\****************************************************************************************/
-
-/******************************** Memory storage ****************************************/
-
-typedef struct CvMemBlock
-{
-    struct CvMemBlock*  prev;
-    struct CvMemBlock*  next;
-}
-CvMemBlock;
-
-#define CV_STORAGE_MAGIC_VAL    0x42890000
-
-typedef struct CvMemStorage
-{
-    int signature;
-    CvMemBlock* bottom;           /* First allocated block.                   */
-    CvMemBlock* top;              /* Current memory block - top of the stack. */
-    struct  CvMemStorage* parent; /* We get new blocks from parent as needed. */
-    int block_size;               /* Block size.                              */
-    int free_space;               /* Remaining free space in current block.   */
-}
-CvMemStorage;
-
-#define CV_IS_STORAGE(storage)  \
-    ((storage) != NULL &&       \
-    (((CvMemStorage*)(storage))->signature & CV_MAGIC_MASK) == CV_STORAGE_MAGIC_VAL)
-
-
-typedef struct CvMemStoragePos
-{
-    CvMemBlock* top;
-    int free_space;
-}
-CvMemStoragePos;
-
-
-/*********************************** Sequence *******************************************/
-
-typedef struct CvSeqBlock
-{
-    struct CvSeqBlock*  prev; /* Previous sequence block.                   */
-    struct CvSeqBlock*  next; /* Next sequence block.                       */
-  int    start_index;         /* Index of the first element in the block +  */
-                              /* sequence->first->start_index.              */
-    int    count;             /* Number of elements in the block.           */
-    schar* data;              /* Pointer to the first element of the block. */
-}
-CvSeqBlock;
-
-
-#define CV_TREE_NODE_FIELDS(node_type)                               \
-    int       flags;             /* Miscellaneous flags.     */      \
-    int       header_size;       /* Size of sequence header. */      \
-    struct    node_type* h_prev; /* Previous sequence.       */      \
-    struct    node_type* h_next; /* Next sequence.           */      \
-    struct    node_type* v_prev; /* 2nd previous sequence.   */      \
-    struct    node_type* v_next  /* 2nd next sequence.       */
-
-/*
-   Read/Write sequence.
-   Elements can be dynamically inserted to or deleted from the sequence.
-*/
-#define CV_SEQUENCE_FIELDS()                                              \
-    CV_TREE_NODE_FIELDS(CvSeq);                                           \
-    int       total;          /* Total number of elements.            */  \
-    int       elem_size;      /* Size of sequence element in bytes.   */  \
-    schar*    block_max;      /* Maximal bound of the last block.     */  \
-    schar*    ptr;            /* Current write pointer.               */  \
-    int       delta_elems;    /* Grow seq this many at a time.        */  \
-    CvMemStorage* storage;    /* Where the seq is stored.             */  \
-    CvSeqBlock* free_blocks;  /* Free blocks list.                    */  \
-    CvSeqBlock* first;        /* Pointer to the first sequence block. */
-
-typedef struct CvSeq
-{
-    CV_SEQUENCE_FIELDS()
-}
-CvSeq;
-
-#define CV_TYPE_NAME_SEQ             "opencv-sequence"
-#define CV_TYPE_NAME_SEQ_TREE        "opencv-sequence-tree"
-
-/*************************************** Set ********************************************/
-/*
-  Set.
-  Order is not preserved. There can be gaps between sequence elements.
-  After the element has been inserted it stays in the same place all the time.
-  The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists.
-*/
-#define CV_SET_ELEM_FIELDS(elem_type)   \
-    int  flags;                         \
-    struct elem_type* next_free;
-
-typedef struct CvSetElem
-{
-    CV_SET_ELEM_FIELDS(CvSetElem)
-}
-CvSetElem;
-
-#define CV_SET_FIELDS()      \
-    CV_SEQUENCE_FIELDS()     \
-    CvSetElem* free_elems;   \
-    int active_count;
-
-typedef struct CvSet
-{
-    CV_SET_FIELDS()
-}
-CvSet;
-
-
-#define CV_SET_ELEM_IDX_MASK   ((1 << 26) - 1)
-#define CV_SET_ELEM_FREE_FLAG  (1 << (sizeof(int)*8-1))
-
-/* Checks whether the element pointed by ptr belongs to a set or not */
-#define CV_IS_SET_ELEM( ptr )  (((CvSetElem*)(ptr))->flags >= 0)
-
-/************************************* Graph ********************************************/
-
-/*
-  We represent a graph as a set of vertices.
-  Vertices contain their adjacency lists (more exactly, pointers to first incoming or
-  outcoming edge (or 0 if isolated vertex)). Edges are stored in another set.
-  There is a singly-linked list of incoming/outcoming edges for each vertex.
-
-  Each edge consists of
-
-     o   Two pointers to the starting and ending vertices
-         (vtx[0] and vtx[1] respectively).
-
-        A graph may be oriented or not. In the latter case, edges between
-        vertex i to vertex j are not distinguished during search operations.
-
-     o   Two pointers to next edges for the starting and ending vertices, where
-         next[0] points to the next edge in the vtx[0] adjacency list and
-         next[1] points to the next edge in the vtx[1] adjacency list.
-*/
-#define CV_GRAPH_EDGE_FIELDS()      \
-    int flags;                      \
-    float weight;                   \
-    struct CvGraphEdge* next[2];    \
-    struct CvGraphVtx* vtx[2];
-
-
-#define CV_GRAPH_VERTEX_FIELDS()    \
-    int flags;                      \
-    struct CvGraphEdge* first;
-
-
-typedef struct CvGraphEdge
-{
-    CV_GRAPH_EDGE_FIELDS()
-}
-CvGraphEdge;
-
-typedef struct CvGraphVtx
-{
-    CV_GRAPH_VERTEX_FIELDS()
-}
-CvGraphVtx;
-
-typedef struct CvGraphVtx2D
-{
-    CV_GRAPH_VERTEX_FIELDS()
-    CvPoint2D32f* ptr;
-}
-CvGraphVtx2D;
-
-/*
-   Graph is "derived" from the set (this is set a of vertices)
-   and includes another set (edges)
-*/
-#define  CV_GRAPH_FIELDS()   \
-    CV_SET_FIELDS()          \
-    CvSet* edges;
-
-typedef struct CvGraph
-{
-    CV_GRAPH_FIELDS()
-}
-CvGraph;
-
-#define CV_TYPE_NAME_GRAPH "opencv-graph"
-
-/*********************************** Chain/Countour *************************************/
-
-typedef struct CvChain
-{
-    CV_SEQUENCE_FIELDS()
-    CvPoint  origin;
-}
-CvChain;
-
-#define CV_CONTOUR_FIELDS()  \
-    CV_SEQUENCE_FIELDS()     \
-    CvRect rect;             \
-    int color;               \
-    int reserved[3];
-
-typedef struct CvContour
-{
-    CV_CONTOUR_FIELDS()
-}
-CvContour;
-
-typedef CvContour CvPoint2DSeq;
-
-/****************************************************************************************\
-*                                    Sequence types                                      *
-\****************************************************************************************/
-
-#define CV_SEQ_MAGIC_VAL             0x42990000
-
-#define CV_IS_SEQ(seq) \
-    ((seq) != NULL && (((CvSeq*)(seq))->flags & CV_MAGIC_MASK) == CV_SEQ_MAGIC_VAL)
-
-#define CV_SET_MAGIC_VAL             0x42980000
-#define CV_IS_SET(set) \
-    ((set) != NULL && (((CvSeq*)(set))->flags & CV_MAGIC_MASK) == CV_SET_MAGIC_VAL)
-
-#define CV_SEQ_ELTYPE_BITS           9
-#define CV_SEQ_ELTYPE_MASK           ((1 << CV_SEQ_ELTYPE_BITS) - 1)
-
-#define CV_SEQ_ELTYPE_POINT          CV_32SC2  /* (x,y) */
-#define CV_SEQ_ELTYPE_CODE           CV_8UC1   /* freeman code: 0..7 */
-#define CV_SEQ_ELTYPE_GENERIC        0
-#define CV_SEQ_ELTYPE_PTR            CV_USRTYPE1
-#define CV_SEQ_ELTYPE_PPOINT         CV_SEQ_ELTYPE_PTR  /* &(x,y) */
-#define CV_SEQ_ELTYPE_INDEX          CV_32SC1  /* #(x,y) */
-#define CV_SEQ_ELTYPE_GRAPH_EDGE     0  /* &next_o, &next_d, &vtx_o, &vtx_d */
-#define CV_SEQ_ELTYPE_GRAPH_VERTEX   0  /* first_edge, &(x,y) */
-#define CV_SEQ_ELTYPE_TRIAN_ATR      0  /* vertex of the binary tree   */
-#define CV_SEQ_ELTYPE_CONNECTED_COMP 0  /* connected component  */
-#define CV_SEQ_ELTYPE_POINT3D        CV_32FC3  /* (x,y,z)  */
-
-#define CV_SEQ_KIND_BITS        3
-#define CV_SEQ_KIND_MASK        (((1 << CV_SEQ_KIND_BITS) - 1)<<CV_SEQ_ELTYPE_BITS)
-
-/* types of sequences */
-#define CV_SEQ_KIND_GENERIC     (0 << CV_SEQ_ELTYPE_BITS)
-#define CV_SEQ_KIND_CURVE       (1 << CV_SEQ_ELTYPE_BITS)
-#define CV_SEQ_KIND_BIN_TREE    (2 << CV_SEQ_ELTYPE_BITS)
-
-/* types of sparse sequences (sets) */
-#define CV_SEQ_KIND_GRAPH       (3 << CV_SEQ_ELTYPE_BITS)
-#define CV_SEQ_KIND_SUBDIV2D    (4 << CV_SEQ_ELTYPE_BITS)
-
-#define CV_SEQ_FLAG_SHIFT       (CV_SEQ_KIND_BITS + CV_SEQ_ELTYPE_BITS)
-
-/* flags for curves */
-#define CV_SEQ_FLAG_CLOSED     (1 << CV_SEQ_FLAG_SHIFT)
-#define CV_SEQ_FLAG_SIMPLE     (2 << CV_SEQ_FLAG_SHIFT)
-#define CV_SEQ_FLAG_CONVEX     (4 << CV_SEQ_FLAG_SHIFT)
-#define CV_SEQ_FLAG_HOLE       (8 << CV_SEQ_FLAG_SHIFT)
-
-/* flags for graphs */
-#define CV_GRAPH_FLAG_ORIENTED (1 << CV_SEQ_FLAG_SHIFT)
-
-#define CV_GRAPH               CV_SEQ_KIND_GRAPH
-#define CV_ORIENTED_GRAPH      (CV_SEQ_KIND_GRAPH|CV_GRAPH_FLAG_ORIENTED)
-
-/* point sets */
-#define CV_SEQ_POINT_SET       (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT)
-#define CV_SEQ_POINT3D_SET     (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT3D)
-#define CV_SEQ_POLYLINE        (CV_SEQ_KIND_CURVE  | CV_SEQ_ELTYPE_POINT)
-#define CV_SEQ_POLYGON         (CV_SEQ_FLAG_CLOSED | CV_SEQ_POLYLINE )
-#define CV_SEQ_CONTOUR         CV_SEQ_POLYGON
-#define CV_SEQ_SIMPLE_POLYGON  (CV_SEQ_FLAG_SIMPLE | CV_SEQ_POLYGON  )
-
-/* chain-coded curves */
-#define CV_SEQ_CHAIN           (CV_SEQ_KIND_CURVE  | CV_SEQ_ELTYPE_CODE)
-#define CV_SEQ_CHAIN_CONTOUR   (CV_SEQ_FLAG_CLOSED | CV_SEQ_CHAIN)
-
-/* binary tree for the contour */
-#define CV_SEQ_POLYGON_TREE    (CV_SEQ_KIND_BIN_TREE  | CV_SEQ_ELTYPE_TRIAN_ATR)
-
-/* sequence of the connected components */
-#define CV_SEQ_CONNECTED_COMP  (CV_SEQ_KIND_GENERIC  | CV_SEQ_ELTYPE_CONNECTED_COMP)
-
-/* sequence of the integer numbers */
-#define CV_SEQ_INDEX           (CV_SEQ_KIND_GENERIC  | CV_SEQ_ELTYPE_INDEX)
-
-#define CV_SEQ_ELTYPE( seq )   ((seq)->flags & CV_SEQ_ELTYPE_MASK)
-#define CV_SEQ_KIND( seq )     ((seq)->flags & CV_SEQ_KIND_MASK )
-
-/* flag checking */
-#define CV_IS_SEQ_INDEX( seq )      ((CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_INDEX) && \
-                                     (CV_SEQ_KIND(seq) == CV_SEQ_KIND_GENERIC))
-
-#define CV_IS_SEQ_CURVE( seq )      (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE)
-#define CV_IS_SEQ_CLOSED( seq )     (((seq)->flags & CV_SEQ_FLAG_CLOSED) != 0)
-#define CV_IS_SEQ_CONVEX( seq )     (((seq)->flags & CV_SEQ_FLAG_CONVEX) != 0)
-#define CV_IS_SEQ_HOLE( seq )       (((seq)->flags & CV_SEQ_FLAG_HOLE) != 0)
-#define CV_IS_SEQ_SIMPLE( seq )     ((((seq)->flags & CV_SEQ_FLAG_SIMPLE) != 0) || \
-                                    CV_IS_SEQ_CONVEX(seq))
-
-/* type checking macros */
-#define CV_IS_SEQ_POINT_SET( seq ) \
-    ((CV_SEQ_ELTYPE(seq) == CV_32SC2 || CV_SEQ_ELTYPE(seq) == CV_32FC2))
-
-#define CV_IS_SEQ_POINT_SUBSET( seq ) \
-    (CV_IS_SEQ_INDEX( seq ) || CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_PPOINT)
-
-#define CV_IS_SEQ_POLYLINE( seq )   \
-    (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && CV_IS_SEQ_POINT_SET(seq))
-
-#define CV_IS_SEQ_POLYGON( seq )   \
-    (CV_IS_SEQ_POLYLINE(seq) && CV_IS_SEQ_CLOSED(seq))
-
-#define CV_IS_SEQ_CHAIN( seq )   \
-    (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && (seq)->elem_size == 1)
-
-#define CV_IS_SEQ_CONTOUR( seq )   \
-    (CV_IS_SEQ_CLOSED(seq) && (CV_IS_SEQ_POLYLINE(seq) || CV_IS_SEQ_CHAIN(seq)))
-
-#define CV_IS_SEQ_CHAIN_CONTOUR( seq ) \
-    (CV_IS_SEQ_CHAIN( seq ) && CV_IS_SEQ_CLOSED( seq ))
-
-#define CV_IS_SEQ_POLYGON_TREE( seq ) \
-    (CV_SEQ_ELTYPE (seq) ==  CV_SEQ_ELTYPE_TRIAN_ATR &&    \
-    CV_SEQ_KIND( seq ) ==  CV_SEQ_KIND_BIN_TREE )
-
-#define CV_IS_GRAPH( seq )    \
-    (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_GRAPH)
-
-#define CV_IS_GRAPH_ORIENTED( seq )   \
-    (((seq)->flags & CV_GRAPH_FLAG_ORIENTED) != 0)
-
-#define CV_IS_SUBDIV2D( seq )  \
-    (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_SUBDIV2D)
-
-/****************************************************************************************/
-/*                            Sequence writer & reader                                  */
-/****************************************************************************************/
-
-#define CV_SEQ_WRITER_FIELDS()                                     \
-    int          header_size;                                      \
-    CvSeq*       seq;        /* the sequence written */            \
-    CvSeqBlock*  block;      /* current block */                   \
-    schar*       ptr;        /* pointer to free space */           \
-    schar*       block_min;  /* pointer to the beginning of block*/\
-    schar*       block_max;  /* pointer to the end of block */
-
-typedef struct CvSeqWriter
-{
-    CV_SEQ_WRITER_FIELDS()
-}
-CvSeqWriter;
-
-
-#define CV_SEQ_READER_FIELDS()                                      \
-    int          header_size;                                       \
-    CvSeq*       seq;        /* sequence, beign read */             \
-    CvSeqBlock*  block;      /* current block */                    \
-    schar*       ptr;        /* pointer to element be read next */  \
-    schar*       block_min;  /* pointer to the beginning of block */\
-    schar*       block_max;  /* pointer to the end of block */      \
-    int          delta_index;/* = seq->first->start_index   */      \
-    schar*       prev_elem;  /* pointer to previous element */
-
-
-typedef struct CvSeqReader
-{
-    CV_SEQ_READER_FIELDS()
-}
-CvSeqReader;
-
-/****************************************************************************************/
-/*                                Operations on sequences                               */
-/****************************************************************************************/
-
-#define  CV_SEQ_ELEM( seq, elem_type, index )                    \
-/* assert gives some guarantee that <seq> parameter is valid */  \
-(   assert(sizeof((seq)->first[0]) == sizeof(CvSeqBlock) &&      \
-    (seq)->elem_size == sizeof(elem_type)),                      \
-    (elem_type*)((seq)->first && (unsigned)index <               \
-    (unsigned)((seq)->first->count) ?                            \
-    (seq)->first->data + (index) * sizeof(elem_type) :           \
-    cvGetSeqElem( (CvSeq*)(seq), (index) )))
-#define CV_GET_SEQ_ELEM( elem_type, seq, index ) CV_SEQ_ELEM( (seq), elem_type, (index) )
-
-/* Add element to sequence: */
-#define CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer )     \
-{                                                     \
-    if( (writer).ptr >= (writer).block_max )          \
-    {                                                 \
-        cvCreateSeqBlock( &writer);                   \
-    }                                                 \
-    memcpy((writer).ptr, elem_ptr, (writer).seq->elem_size);\
-    (writer).ptr += (writer).seq->elem_size;          \
-}
-
-#define CV_WRITE_SEQ_ELEM( elem, writer )             \
-{                                                     \
-    assert( (writer).seq->elem_size == sizeof(elem)); \
-    if( (writer).ptr >= (writer).block_max )          \
-    {                                                 \
-        cvCreateSeqBlock( &writer);                   \
-    }                                                 \
-    assert( (writer).ptr <= (writer).block_max - sizeof(elem));\
-    memcpy((writer).ptr, &(elem), sizeof(elem));      \
-    (writer).ptr += sizeof(elem);                     \
-}
-
-
-/* Move reader position forward: */
-#define CV_NEXT_SEQ_ELEM( elem_size, reader )                 \
-{                                                             \
-    if( ((reader).ptr += (elem_size)) >= (reader).block_max ) \
-    {                                                         \
-        cvChangeSeqBlock( &(reader), 1 );                     \
-    }                                                         \
-}
-
-
-/* Move reader position backward: */
-#define CV_PREV_SEQ_ELEM( elem_size, reader )                \
-{                                                            \
-    if( ((reader).ptr -= (elem_size)) < (reader).block_min ) \
-    {                                                        \
-        cvChangeSeqBlock( &(reader), -1 );                   \
-    }                                                        \
-}
-
-/* Read element and move read position forward: */
-#define CV_READ_SEQ_ELEM( elem, reader )                       \
-{                                                              \
-    assert( (reader).seq->elem_size == sizeof(elem));          \
-    memcpy( &(elem), (reader).ptr, sizeof((elem)));            \
-    CV_NEXT_SEQ_ELEM( sizeof(elem), reader )                   \
-}
-
-/* Read element and move read position backward: */
-#define CV_REV_READ_SEQ_ELEM( elem, reader )                     \
-{                                                                \
-    assert( (reader).seq->elem_size == sizeof(elem));            \
-    memcpy(&(elem), (reader).ptr, sizeof((elem)));               \
-    CV_PREV_SEQ_ELEM( sizeof(elem), reader )                     \
-}
-
-
-#define CV_READ_CHAIN_POINT( _pt, reader )                              \
-{                                                                       \
-    (_pt) = (reader).pt;                                                \
-    if( (reader).ptr )                                                  \
-    {                                                                   \
-        CV_READ_SEQ_ELEM( (reader).code, (reader));                     \
-        assert( ((reader).code & ~7) == 0 );                            \
-        (reader).pt.x += (reader).deltas[(int)(reader).code][0];        \
-        (reader).pt.y += (reader).deltas[(int)(reader).code][1];        \
-    }                                                                   \
-}
-
-#define CV_CURRENT_POINT( reader )  (*((CvPoint*)((reader).ptr)))
-#define CV_PREV_POINT( reader )     (*((CvPoint*)((reader).prev_elem)))
-
-#define CV_READ_EDGE( pt1, pt2, reader )               \
-{                                                      \
-    assert( sizeof(pt1) == sizeof(CvPoint) &&          \
-            sizeof(pt2) == sizeof(CvPoint) &&          \
-            reader.seq->elem_size == sizeof(CvPoint)); \
-    (pt1) = CV_PREV_POINT( reader );                   \
-    (pt2) = CV_CURRENT_POINT( reader );                \
-    (reader).prev_elem = (reader).ptr;                 \
-    CV_NEXT_SEQ_ELEM( sizeof(CvPoint), (reader));      \
-}
-
-/************ Graph macros ************/
-
-/* Return next graph edge for given vertex: */
-#define  CV_NEXT_GRAPH_EDGE( edge, vertex )                              \
-     (assert((edge)->vtx[0] == (vertex) || (edge)->vtx[1] == (vertex)),  \
-      (edge)->next[(edge)->vtx[1] == (vertex)])
-
-
-
-/****************************************************************************************\
-*             Data structures for persistence (a.k.a serialization) functionality        *
-\****************************************************************************************/
-
-/* "black box" file storage */
-typedef struct CvFileStorage CvFileStorage;
-
-/* Storage flags: */
-#define CV_STORAGE_READ          0
-#define CV_STORAGE_WRITE         1
-#define CV_STORAGE_WRITE_TEXT    CV_STORAGE_WRITE
-#define CV_STORAGE_WRITE_BINARY  CV_STORAGE_WRITE
-#define CV_STORAGE_APPEND        2
-
-/* List of attributes: */
-typedef struct CvAttrList
-{
-    const char** attr;         /* NULL-terminated array of (attribute_name,attribute_value) pairs. */
-    struct CvAttrList* next;   /* Pointer to next chunk of the attributes list.                    */
-}
-CvAttrList;
-
-CV_INLINE CvAttrList cvAttrList( const char** attr CV_DEFAULT(NULL),
-                                 CvAttrList* next CV_DEFAULT(NULL) )
-{
-    CvAttrList l;
-    l.attr = attr;
-    l.next = next;
-
-    return l;
-}
-
-struct CvTypeInfo;
-
-#define CV_NODE_NONE        0
-#define CV_NODE_INT         1
-#define CV_NODE_INTEGER     CV_NODE_INT
-#define CV_NODE_REAL        2
-#define CV_NODE_FLOAT       CV_NODE_REAL
-#define CV_NODE_STR         3
-#define CV_NODE_STRING      CV_NODE_STR
-#define CV_NODE_REF         4 /* not used */
-#define CV_NODE_SEQ         5
-#define CV_NODE_MAP         6
-#define CV_NODE_TYPE_MASK   7
-
-#define CV_NODE_TYPE(flags)  ((flags) & CV_NODE_TYPE_MASK)
-
-/* file node flags */
-#define CV_NODE_FLOW        8 /* Used only for writing structures in YAML format. */
-#define CV_NODE_USER        16
-#define CV_NODE_EMPTY       32
-#define CV_NODE_NAMED       64
-
-#define CV_NODE_IS_INT(flags)        (CV_NODE_TYPE(flags) == CV_NODE_INT)
-#define CV_NODE_IS_REAL(flags)       (CV_NODE_TYPE(flags) == CV_NODE_REAL)
-#define CV_NODE_IS_STRING(flags)     (CV_NODE_TYPE(flags) == CV_NODE_STRING)
-#define CV_NODE_IS_SEQ(flags)        (CV_NODE_TYPE(flags) == CV_NODE_SEQ)
-#define CV_NODE_IS_MAP(flags)        (CV_NODE_TYPE(flags) == CV_NODE_MAP)
-#define CV_NODE_IS_COLLECTION(flags) (CV_NODE_TYPE(flags) >= CV_NODE_SEQ)
-#define CV_NODE_IS_FLOW(flags)       (((flags) & CV_NODE_FLOW) != 0)
-#define CV_NODE_IS_EMPTY(flags)      (((flags) & CV_NODE_EMPTY) != 0)
-#define CV_NODE_IS_USER(flags)       (((flags) & CV_NODE_USER) != 0)
-#define CV_NODE_HAS_NAME(flags)      (((flags) & CV_NODE_NAMED) != 0)
-
-#define CV_NODE_SEQ_SIMPLE 256
-#define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0)
-
-typedef struct CvString
-{
-    int len;
-    char* ptr;
-}
-CvString;
-
-/* All the keys (names) of elements in the readed file storage
-   are stored in the hash to speed up the lookup operations: */
-typedef struct CvStringHashNode
-{
-    unsigned hashval;
-    CvString str;
-    struct CvStringHashNode* next;
-}
-CvStringHashNode;
-
-typedef struct CvGenericHash CvFileNodeHash;
-
-/* Basic element of the file storage - scalar or collection: */
-typedef struct CvFileNode
-{
-    int tag;
-    struct CvTypeInfo* info; /* type information
-            (only for user-defined object, for others it is 0) */
-    union
-    {
-        double f; /* scalar floating-point number */
-        int i;    /* scalar integer number */
-        CvString str; /* text string */
-        CvSeq* seq; /* sequence (ordered collection of file nodes) */
-        CvFileNodeHash* map; /* map (collection of named file nodes) */
-    } data;
-}
-CvFileNode;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr );
-typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr );
-typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node );
-typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name,
-                                      const void* struct_ptr, CvAttrList attributes );
-typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr );
-#ifdef __cplusplus
-}
-#endif
-
-typedef struct CvTypeInfo
-{
-    int flags;
-    int header_size;
-    struct CvTypeInfo* prev;
-    struct CvTypeInfo* next;
-    const char* type_name;
-    CvIsInstanceFunc is_instance;
-    CvReleaseFunc release;
-    CvReadFunc read;
-    CvWriteFunc write;
-    CvCloneFunc clone;
-}
-CvTypeInfo;
-
-
-/**** System data types ******/
-
-typedef struct CvPluginFuncInfo
-{
-    void** func_addr;
-    void* default_func_addr;
-    const char* func_names;
-    int search_modules;
-    int loaded_from;
-}
-CvPluginFuncInfo;
-
-typedef struct CvModuleInfo
-{
-    struct CvModuleInfo* next;
-    const char* name;
-    const char* version;
-    CvPluginFuncInfo* func_tab;
-}
-CvModuleInfo;
-
-#endif /*_CXCORE_TYPES_H_*/
-
-/* End of file. */
+/*M///////////////////////////////////////////////////////////////////////////////////////\r
+//\r
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
+//\r
+//  By downloading, copying, installing or using the software you agree to this license.\r
+//  If you do not agree to this license, do not download, install,\r
+//  copy or use the software.\r
+//\r
+//\r
+//                          License Agreement\r
+//                For Open Source Computer Vision Library\r
+//\r
+// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.\r
+// Copyright (C) 2009, Willow Garage Inc., all rights reserved.\r
+// Third party copyrights are property of their respective owners.\r
+//\r
+// Redistribution and use in source and binary forms, with or without modification,\r
+// are permitted provided that the following conditions are met:\r
+//\r
+//   * Redistribution's of source code must retain the above copyright notice,\r
+//     this list of conditions and the following disclaimer.\r
+//\r
+//   * Redistribution's in binary form must reproduce the above copyright notice,\r
+//     this list of conditions and the following disclaimer in the documentation\r
+//     and/or other materials provided with the distribution.\r
+//\r
+//   * The name of the copyright holders may not be used to endorse or promote products\r
+//     derived from this software without specific prior written permission.\r
+//\r
+// This software is provided by the copyright holders and contributors "as is" and\r
+// any express or implied warranties, including, but not limited to, the implied\r
+// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
+// In no event shall the Intel Corporation or contributors be liable for any direct,\r
+// indirect, incidental, special, exemplary, or consequential damages\r
+// (including, but not limited to, procurement of substitute goods or services;\r
+// loss of use, data, or profits; or business interruption) however caused\r
+// and on any theory of liability, whether in contract, strict liability,\r
+// or tort (including negligence or otherwise) arising in any way out of\r
+// the use of this software, even if advised of the possibility of such damage.\r
+//\r
+//M*/\r
+\r
+#ifndef _CXCORE_TYPES_H_\r
+#define _CXCORE_TYPES_H_\r
+\r
+#if !defined _CRT_SECURE_NO_DEPRECATE && _MSC_VER > 1300\r
+#define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio 2005 warnings */\r
+#endif\r
+\r
+#ifndef SKIP_INCLUDES\r
+  #include <assert.h>\r
+  #include <stdlib.h>\r
+  #include <string.h>\r
+  #include <float.h>\r
+\r
+  #if defined __ICL\r
+    #define CV_ICC   __ICL\r
+  #elif defined __ICC\r
+    #define CV_ICC   __ICC\r
+  #elif defined __ECL\r
+    #define CV_ICC   __ECL\r
+  #elif defined __ECC\r
+    #define CV_ICC   __ECC\r
+  #endif\r
+\r
+  #if defined WIN32 && (!defined WIN64 || defined EM64T) && \\r
+      (_MSC_VER >= 1400 || defined CV_ICC) \\r
+      || (defined __SSE2__ && defined __GNUC__ && __GNUC__ >= 4)\r
+    #include <emmintrin.h>\r
+    #define CV_SSE2 1\r
+  #else\r
+    #define CV_SSE2 0\r
+  #endif\r
+\r
+  #if ((defined __SSE__ || defined __MMX__) && defined __GNUC__ && __GNUC__ >= 3)\r
+    #include <mmintrin.h>\r
+  #endif\r
+\r
+  #if defined __BORLANDC__\r
+    #include <fastmath.h>\r
+  #elif defined WIN64 && !defined EM64T && defined CV_ICC\r
+    #include <mathimf.h>\r
+  #else\r
+    #include <math.h>\r
+  #endif\r
+\r
+  #ifdef HAVE_IPL\r
+      #ifndef __IPL_H__\r
+          #if defined WIN32 || defined WIN64\r
+              #include <ipl.h>\r
+          #else\r
+              #include <ipl/ipl.h>\r
+          #endif\r
+      #endif\r
+  #elif defined __IPL_H__\r
+      #define HAVE_IPL\r
+  #endif\r
+#endif // SKIP_INCLUDES\r
+\r
+#if defined WIN32 || defined WIN64\r
+    #define CV_CDECL __cdecl\r
+    #define CV_STDCALL __stdcall\r
+#else\r
+    #define CV_CDECL\r
+    #define CV_STDCALL\r
+#endif\r
+\r
+#ifndef CV_EXTERN_C\r
+    #ifdef __cplusplus\r
+        #define CV_EXTERN_C extern "C"\r
+        #define CV_DEFAULT(val) = val\r
+    #else\r
+        #define CV_EXTERN_C\r
+        #define CV_DEFAULT(val)\r
+    #endif\r
+#endif\r
+\r
+#ifndef CV_EXTERN_C_FUNCPTR\r
+    #ifdef __cplusplus\r
+        #define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; }\r
+    #else\r
+        #define CV_EXTERN_C_FUNCPTR(x) typedef x\r
+    #endif\r
+#endif\r
+\r
+#ifndef CV_INLINE\r
+#if defined __cplusplus\r
+    #define CV_INLINE inline\r
+#elif (defined WIN32 || defined WIN64 || defined WINCE) && !defined __GNUC__\r
+    #define CV_INLINE __inline\r
+#else\r
+    #define CV_INLINE static\r
+#endif\r
+#endif /* CV_INLINE */\r
+\r
+#if (defined WIN32 || defined WIN64 || defined WINCE) && defined CVAPI_EXPORTS\r
+    #define CV_EXPORTS __declspec(dllexport)\r
+#else\r
+    #define CV_EXPORTS\r
+#endif\r
+\r
+#ifndef CVAPI\r
+    #define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL\r
+#endif\r
+\r
+#if defined _MSC_VER || defined __BORLANDC__\r
+typedef __int64 int64;\r
+typedef unsigned __int64 uint64;\r
+#else\r
+typedef long long int64;\r
+typedef unsigned long long uint64;\r
+#endif\r
+\r
+#ifndef HAVE_IPL\r
+typedef unsigned char uchar;\r
+typedef unsigned short ushort;\r
+#endif\r
+\r
+typedef signed char schar;\r
+\r
+/* CvArr* is used to pass arbitrary\r
+ * array-like data structures\r
+ * into functions where the particular\r
+ * array type is recognized at runtime:\r
+ */\r
+typedef void CvArr;\r
+\r
+typedef union Cv32suf\r
+{\r
+    int i;\r
+    unsigned u;\r
+    float f;\r
+}\r
+Cv32suf;\r
+\r
+typedef union Cv64suf\r
+{\r
+    int64 i;\r
+    uint64 u;\r
+    double f;\r
+}\r
+Cv64suf;\r
+\r
+/****************************************************************************************\\r
+*                             Common macros and inline functions                         *\r
+\****************************************************************************************/\r
+\r
+#define CV_PI   3.1415926535897932384626433832795\r
+#define CV_LOG2 0.69314718055994530941723212145818\r
+\r
+#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))\r
+\r
+#ifndef MIN\r
+#define MIN(a,b)  ((a) > (b) ? (b) : (a))\r
+#endif\r
+\r
+#ifndef MAX\r
+#define MAX(a,b)  ((a) < (b) ? (b) : (a))\r
+#endif\r
+\r
+/* min & max without jumps */\r
+#define  CV_IMIN(a, b)  ((a) ^ (((a)^(b)) & (((a) < (b)) - 1)))\r
+\r
+#define  CV_IMAX(a, b)  ((a) ^ (((a)^(b)) & (((a) > (b)) - 1)))\r
+\r
+/* absolute value without jumps */\r
+#ifndef __cplusplus\r
+#define  CV_IABS(a)     (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))\r
+#else\r
+#define  CV_IABS(a)     abs(a)\r
+#endif\r
+#define  CV_CMP(a,b)    (((a) > (b)) - ((a) < (b)))\r
+#define  CV_SIGN(a)     CV_CMP((a),0)\r
+\r
+CV_INLINE  int  cvRound( double value )\r
+{\r
+#if CV_SSE2\r
+    __m128d t = _mm_load_sd( &value );\r
+    return _mm_cvtsd_si32(t);\r
+#elif defined WIN32 && !defined WIN64 && defined _MSC_VER\r
+    int t;\r
+    __asm\r
+    {\r
+        fld value;\r
+        fistp t;\r
+    }\r
+    return t;\r
+#elif (defined HAVE_LRINT) || (defined WIN64 && !defined EM64T && defined CV_ICC)\r
+    return (int)lrint(value);\r
+#else\r
+    /*\r
+     the algorithm was taken from Agner Fog's optimization guide\r
+     at http://www.agner.org/assem\r
+     */\r
+    Cv64suf temp;\r
+    temp.f = value + 6755399441055744.0;\r
+    return (int)temp.u;\r
+#endif\r
+}\r
+\r
+\r
+CV_INLINE  int  cvFloor( double value )\r
+{\r
+#if CV_SSE2\r
+    __m128d t = _mm_load_sd( &value );\r
+    int i = _mm_cvtsd_si32(t);\r
+    return i - _mm_movemask_pd(_mm_cmplt_sd(t,_mm_cvtsi32_sd(t,i)));\r
+#else\r
+    int temp = cvRound(value);\r
+    Cv32suf diff;\r
+    diff.f = (float)(value - temp);\r
+    return temp - (diff.i < 0);\r
+#endif\r
+}\r
+\r
+\r
+CV_INLINE  int  cvCeil( double value )\r
+{\r
+#if CV_SSE2\r
+    __m128d t = _mm_load_sd( &value );\r
+    int i = _mm_cvtsd_si32(t);\r
+    return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i),t));\r
+#else\r
+    int temp = cvRound(value);\r
+    Cv32suf diff;\r
+    diff.f = (float)(temp - value);\r
+    return temp + (diff.i < 0);\r
+#endif\r
+}\r
+\r
+#define cvInvSqrt(value) ((float)(1./sqrt(value)))\r
+#define cvSqrt(value)  ((float)sqrt(value))\r
+\r
+CV_INLINE int cvIsNaN( double value )\r
+{\r
+#if 1/*defined _MSC_VER || defined __BORLANDC__\r
+    return _isnan(value);\r
+#elif defined __GNUC__\r
+    return isnan(value);\r
+#else*/\r
+    Cv64suf ieee754;\r
+    ieee754.f = value;\r
+    return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +\r
+           ((unsigned)ieee754.u != 0) > 0x7ff00000;\r
+#endif\r
+}\r
+\r
+\r
+CV_INLINE int cvIsInf( double value )\r
+{\r
+#if 1/*defined _MSC_VER || defined __BORLANDC__\r
+    return !_finite(value);\r
+#elif defined __GNUC__\r
+    return isinf(value);\r
+#else*/\r
+    Cv64suf ieee754;\r
+    ieee754.f = value;\r
+    return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&\r
+           (unsigned)ieee754.u == 0;\r
+#endif\r
+}\r
+\r
+\r
+/*************** Random number generation *******************/\r
+\r
+typedef uint64 CvRNG;\r
+\r
+CV_INLINE CvRNG cvRNG( int64 seed CV_DEFAULT(-1))\r
+{\r
+    CvRNG rng = seed ? (uint64)seed : (uint64)(int64)-1;\r
+    return rng;\r
+}\r
+\r
+/* Return random 32-bit unsigned integer: */\r
+CV_INLINE unsigned cvRandInt( CvRNG* rng )\r
+{\r
+    uint64 temp = *rng;\r
+    temp = (uint64)(unsigned)temp*4164903690U + (temp >> 32);\r
+    *rng = temp;\r
+    return (unsigned)temp;\r
+}\r
+\r
+/* Returns random floating-point number between 0 and 1: */\r
+CV_INLINE double cvRandReal( CvRNG* rng )\r
+{\r
+    return cvRandInt(rng)*2.3283064365386962890625e-10 /* 2^-32 */;\r
+}\r
+\r
+/****************************************************************************************\\r
+*                                  Image type (IplImage)                                 *\r
+\****************************************************************************************/\r
+\r
+#ifndef HAVE_IPL\r
+\r
+/*\r
+ * The following definitions (until #endif)\r
+ * is an extract from IPL headers.\r
+ * Copyright (c) 1995 Intel Corporation.\r
+ */\r
+#define IPL_DEPTH_SIGN 0x80000000\r
+\r
+#define IPL_DEPTH_1U     1\r
+#define IPL_DEPTH_8U     8\r
+#define IPL_DEPTH_16U   16\r
+#define IPL_DEPTH_32F   32\r
+\r
+#define IPL_DEPTH_8S  (IPL_DEPTH_SIGN| 8)\r
+#define IPL_DEPTH_16S (IPL_DEPTH_SIGN|16)\r
+#define IPL_DEPTH_32S (IPL_DEPTH_SIGN|32)\r
+\r
+#define IPL_DATA_ORDER_PIXEL  0\r
+#define IPL_DATA_ORDER_PLANE  1\r
+\r
+#define IPL_ORIGIN_TL 0\r
+#define IPL_ORIGIN_BL 1\r
+\r
+#define IPL_ALIGN_4BYTES   4\r
+#define IPL_ALIGN_8BYTES   8\r
+#define IPL_ALIGN_16BYTES 16\r
+#define IPL_ALIGN_32BYTES 32\r
+\r
+#define IPL_ALIGN_DWORD   IPL_ALIGN_4BYTES\r
+#define IPL_ALIGN_QWORD   IPL_ALIGN_8BYTES\r
+\r
+#define IPL_BORDER_CONSTANT   0\r
+#define IPL_BORDER_REPLICATE  1\r
+#define IPL_BORDER_REFLECT    2\r
+#define IPL_BORDER_WRAP       3\r
+\r
+typedef struct _IplImage\r
+{\r
+    int  nSize;             /* sizeof(IplImage) */\r
+    int  ID;                /* version (=0)*/\r
+    int  nChannels;         /* Most of OpenCV functions support 1,2,3 or 4 channels */\r
+    int  alphaChannel;      /* Ignored by OpenCV */\r
+    int  depth;             /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,\r
+                               IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported.  */\r
+    char colorModel[4];     /* Ignored by OpenCV */\r
+    char channelSeq[4];     /* ditto */\r
+    int  dataOrder;         /* 0 - interleaved color channels, 1 - separate color channels.\r
+                               cvCreateImage can only create interleaved images */\r
+    int  origin;            /* 0 - top-left origin,\r
+                               1 - bottom-left origin (Windows bitmaps style).  */\r
+    int  align;             /* Alignment of image rows (4 or 8).\r
+                               OpenCV ignores it and uses widthStep instead.    */\r
+    int  width;             /* Image width in pixels.                           */\r
+    int  height;            /* Image height in pixels.                          */\r
+    struct _IplROI *roi;    /* Image ROI. If NULL, the whole image is selected. */\r
+    struct _IplImage *maskROI;      /* Must be NULL. */\r
+    void  *imageId;                 /* "           " */\r
+    struct _IplTileInfo *tileInfo;  /* "           " */\r
+    int  imageSize;         /* Image data size in bytes\r
+                               (==image->height*image->widthStep\r
+                               in case of interleaved data)*/\r
+    char *imageData;        /* Pointer to aligned image data.         */\r
+    int  widthStep;         /* Size of aligned image row in bytes.    */\r
+    int  BorderMode[4];     /* Ignored by OpenCV.                     */\r
+    int  BorderConst[4];    /* Ditto.                                 */\r
+    char *imageDataOrigin;  /* Pointer to very origin of image data\r
+                               (not necessarily aligned) -\r
+                               needed for correct deallocation */\r
+}\r
+IplImage;\r
+\r
+typedef struct _IplTileInfo IplTileInfo;\r
+\r
+typedef struct _IplROI\r
+{\r
+    int  coi; /* 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/\r
+    int  xOffset;\r
+    int  yOffset;\r
+    int  width;\r
+    int  height;\r
+}\r
+IplROI;\r
+\r
+typedef struct _IplConvKernel\r
+{\r
+    int  nCols;\r
+    int  nRows;\r
+    int  anchorX;\r
+    int  anchorY;\r
+    int *values;\r
+    int  nShiftR;\r
+}\r
+IplConvKernel;\r
+\r
+typedef struct _IplConvKernelFP\r
+{\r
+    int  nCols;\r
+    int  nRows;\r
+    int  anchorX;\r
+    int  anchorY;\r
+    float *values;\r
+}\r
+IplConvKernelFP;\r
+\r
+#define IPL_IMAGE_HEADER 1\r
+#define IPL_IMAGE_DATA   2\r
+#define IPL_IMAGE_ROI    4\r
+\r
+#endif/*HAVE_IPL*/\r
+\r
+/* extra border mode */\r
+#define IPL_BORDER_REFLECT_101    4\r
+\r
+#define IPL_IMAGE_MAGIC_VAL  ((int)sizeof(IplImage))\r
+#define CV_TYPE_NAME_IMAGE "opencv-image"\r
+\r
+#define CV_IS_IMAGE_HDR(img) \\r
+    ((img) != NULL && ((const IplImage*)(img))->nSize == sizeof(IplImage))\r
+\r
+#define CV_IS_IMAGE(img) \\r
+    (CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->imageData != NULL)\r
+\r
+/* for storing double-precision\r
+   floating point data in IplImage's */\r
+#define IPL_DEPTH_64F  64\r
+\r
+/* get reference to pixel at (col,row),\r
+   for multi-channel images (col) should be multiplied by number of channels */\r
+#define CV_IMAGE_ELEM( image, elemtype, row, col )       \\r
+    (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])\r
+\r
+/****************************************************************************************\\r
+*                                  Matrix type (CvMat)                                   *\r
+\****************************************************************************************/\r
+\r
+#define CV_CN_MAX     64\r
+#define CV_CN_SHIFT   3\r
+#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)\r
+\r
+#define CV_8U   0\r
+#define CV_8S   1\r
+#define CV_16U  2\r
+#define CV_16S  3\r
+#define CV_32S  4\r
+#define CV_32F  5\r
+#define CV_64F  6\r
+#define CV_USRTYPE1 7\r
+\r
+#define CV_MAKETYPE(depth,cn) ((depth) + (((cn)-1) << CV_CN_SHIFT))\r
+#define CV_MAKE_TYPE CV_MAKETYPE\r
+\r
+#define CV_8UC1 CV_MAKETYPE(CV_8U,1)\r
+#define CV_8UC2 CV_MAKETYPE(CV_8U,2)\r
+#define CV_8UC3 CV_MAKETYPE(CV_8U,3)\r
+#define CV_8UC4 CV_MAKETYPE(CV_8U,4)\r
+#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))\r
+\r
+#define CV_8SC1 CV_MAKETYPE(CV_8S,1)\r
+#define CV_8SC2 CV_MAKETYPE(CV_8S,2)\r
+#define CV_8SC3 CV_MAKETYPE(CV_8S,3)\r
+#define CV_8SC4 CV_MAKETYPE(CV_8S,4)\r
+#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n))\r
+\r
+#define CV_16UC1 CV_MAKETYPE(CV_16U,1)\r
+#define CV_16UC2 CV_MAKETYPE(CV_16U,2)\r
+#define CV_16UC3 CV_MAKETYPE(CV_16U,3)\r
+#define CV_16UC4 CV_MAKETYPE(CV_16U,4)\r
+#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n))\r
+\r
+#define CV_16SC1 CV_MAKETYPE(CV_16S,1)\r
+#define CV_16SC2 CV_MAKETYPE(CV_16S,2)\r
+#define CV_16SC3 CV_MAKETYPE(CV_16S,3)\r
+#define CV_16SC4 CV_MAKETYPE(CV_16S,4)\r
+#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n))\r
+\r
+#define CV_32SC1 CV_MAKETYPE(CV_32S,1)\r
+#define CV_32SC2 CV_MAKETYPE(CV_32S,2)\r
+#define CV_32SC3 CV_MAKETYPE(CV_32S,3)\r
+#define CV_32SC4 CV_MAKETYPE(CV_32S,4)\r
+#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n))\r
+\r
+#define CV_32FC1 CV_MAKETYPE(CV_32F,1)\r
+#define CV_32FC2 CV_MAKETYPE(CV_32F,2)\r
+#define CV_32FC3 CV_MAKETYPE(CV_32F,3)\r
+#define CV_32FC4 CV_MAKETYPE(CV_32F,4)\r
+#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n))\r
+\r
+#define CV_64FC1 CV_MAKETYPE(CV_64F,1)\r
+#define CV_64FC2 CV_MAKETYPE(CV_64F,2)\r
+#define CV_64FC3 CV_MAKETYPE(CV_64F,3)\r
+#define CV_64FC4 CV_MAKETYPE(CV_64F,4)\r
+#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n))\r
+\r
+#define CV_AUTO_STEP  0x7fffffff\r
+#define CV_WHOLE_ARR  cvSlice( 0, 0x3fffffff )\r
+\r
+#define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)\r
+#define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)\r
+#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)\r
+#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)\r
+#define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)\r
+#define CV_MAT_TYPE(flags)      ((flags) & CV_MAT_TYPE_MASK)\r
+#define CV_MAT_CONT_FLAG_SHIFT  14\r
+#define CV_MAT_CONT_FLAG        (1 << CV_MAT_CONT_FLAG_SHIFT)\r
+#define CV_IS_MAT_CONT(flags)   ((flags) & CV_MAT_CONT_FLAG)\r
+#define CV_IS_CONT_MAT          CV_IS_MAT_CONT\r
+#define CV_MAT_TEMP_FLAG_SHIFT  15\r
+#define CV_MAT_TEMP_FLAG        (1 << CV_MAT_TEMP_FLAG_SHIFT)\r
+#define CV_IS_TEMP_MAT(flags)   ((flags) & CV_MAT_TEMP_FLAG)\r
+\r
+#define CV_MAGIC_MASK       0xFFFF0000\r
+#define CV_MAT_MAGIC_VAL    0x42420000\r
+#define CV_TYPE_NAME_MAT    "opencv-matrix"\r
+\r
+typedef struct CvMat\r
+{\r
+    int type;\r
+    int step;\r
+\r
+    /* for internal use only */\r
+    int* refcount;\r
+    int hdr_refcount;\r
+\r
+    union\r
+    {\r
+        uchar* ptr;\r
+        short* s;\r
+        int* i;\r
+        float* fl;\r
+        double* db;\r
+    } data;\r
+\r
+#ifdef __cplusplus\r
+    union\r
+    {\r
+        int rows;\r
+        int height;\r
+    };\r
+\r
+    union\r
+    {\r
+        int cols;\r
+        int width;\r
+    };\r
+#else\r
+    int rows;\r
+    int cols;\r
+#endif\r
+\r
+}\r
+CvMat;\r
+\r
+\r
+#define CV_IS_MAT_HDR(mat) \\r
+    ((mat) != NULL && \\r
+    (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \\r
+    ((const CvMat*)(mat))->cols > 0 && ((const CvMat*)(mat))->rows > 0)\r
+\r
+#define CV_IS_MAT(mat) \\r
+    (CV_IS_MAT_HDR(mat) && ((const CvMat*)(mat))->data.ptr != NULL)\r
+\r
+#define CV_IS_MASK_ARR(mat) \\r
+    (((mat)->type & (CV_MAT_TYPE_MASK & ~CV_8SC1)) == 0)\r
+\r
+#define CV_ARE_TYPES_EQ(mat1, mat2) \\r
+    ((((mat1)->type ^ (mat2)->type) & CV_MAT_TYPE_MASK) == 0)\r
+\r
+#define CV_ARE_CNS_EQ(mat1, mat2) \\r
+    ((((mat1)->type ^ (mat2)->type) & CV_MAT_CN_MASK) == 0)\r
+\r
+#define CV_ARE_DEPTHS_EQ(mat1, mat2) \\r
+    ((((mat1)->type ^ (mat2)->type) & CV_MAT_DEPTH_MASK) == 0)\r
+\r
+#define CV_ARE_SIZES_EQ(mat1, mat2) \\r
+    ((mat1)->rows == (mat2)->rows && (mat1)->cols == (mat2)->cols)\r
+\r
+#define CV_IS_MAT_CONST(mat)  \\r
+    (((mat)->rows|(mat)->cols) == 1)\r
+\r
+/* Size of each channel item,\r
+   0x124489 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */\r
+#define CV_ELEM_SIZE1(type) \\r
+    ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15)\r
+\r
+/* 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */\r
+#define CV_ELEM_SIZE(type) \\r
+    (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3))\r
+\r
+/* Inline constructor. No data is allocated internally!!!\r
+ * (Use together with cvCreateData, or use cvCreateMat instead to\r
+ * get a matrix with allocated data):\r
+ */\r
+CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))\r
+{\r
+    CvMat m;\r
+\r
+    assert( (unsigned)CV_MAT_DEPTH(type) <= CV_64F );\r
+    type = CV_MAT_TYPE(type);\r
+    m.type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | type;\r
+    m.cols = cols;\r
+    m.rows = rows;\r
+    m.step = rows > 1 ? m.cols*CV_ELEM_SIZE(type) : 0;\r
+    m.data.ptr = (uchar*)data;\r
+    m.refcount = NULL;\r
+    m.hdr_refcount = 0;\r
+\r
+    return m;\r
+}\r
+\r
+\r
+#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size )  \\r
+    (assert( (unsigned)(row) < (unsigned)(mat).rows &&   \\r
+             (unsigned)(col) < (unsigned)(mat).cols ),   \\r
+     (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col))\r
+\r
+#define CV_MAT_ELEM_PTR( mat, row, col )                 \\r
+    CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) )\r
+\r
+#define CV_MAT_ELEM( mat, elemtype, row, col )           \\r
+    (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))\r
+\r
+\r
+CV_INLINE  double  cvmGet( const CvMat* mat, int row, int col )\r
+{\r
+    int type;\r
+\r
+    type = CV_MAT_TYPE(mat->type);\r
+    assert( (unsigned)row < (unsigned)mat->rows &&\r
+            (unsigned)col < (unsigned)mat->cols );\r
+\r
+    if( type == CV_32FC1 )\r
+        return ((float*)(mat->data.ptr + (size_t)mat->step*row))[col];\r
+    else\r
+    {\r
+        assert( type == CV_64FC1 );\r
+        return ((double*)(mat->data.ptr + (size_t)mat->step*row))[col];\r
+    }\r
+}\r
+\r
+\r
+CV_INLINE  void  cvmSet( CvMat* mat, int row, int col, double value )\r
+{\r
+    int type;\r
+    type = CV_MAT_TYPE(mat->type);\r
+    assert( (unsigned)row < (unsigned)mat->rows &&\r
+            (unsigned)col < (unsigned)mat->cols );\r
+\r
+    if( type == CV_32FC1 )\r
+        ((float*)(mat->data.ptr + (size_t)mat->step*row))[col] = (float)value;\r
+    else\r
+    {\r
+        assert( type == CV_64FC1 );\r
+        ((double*)(mat->data.ptr + (size_t)mat->step*row))[col] = (double)value;\r
+    }\r
+}\r
+\r
+\r
+CV_INLINE int cvCvToIplDepth( int type )\r
+{\r
+    int depth = CV_MAT_DEPTH(type);\r
+    return CV_ELEM_SIZE1(depth)*8 | (depth == CV_8S || depth == CV_16S ||\r
+           depth == CV_32S ? IPL_DEPTH_SIGN : 0);\r
+}\r
+\r
+\r
+/****************************************************************************************\\r
+*                       Multi-dimensional dense array (CvMatND)                          *\r
+\****************************************************************************************/\r
+\r
+#define CV_MATND_MAGIC_VAL    0x42430000\r
+#define CV_TYPE_NAME_MATND    "opencv-nd-matrix"\r
+\r
+#define CV_MAX_DIM            32\r
+#define CV_MAX_DIM_HEAP       (1 << 16)\r
+\r
+typedef struct CvMatND\r
+{\r
+    int type;\r
+    int dims;\r
+\r
+    int* refcount;\r
+    int hdr_refcount;\r
+\r
+    union\r
+    {\r
+        uchar* ptr;\r
+        float* fl;\r
+        double* db;\r
+        int* i;\r
+        short* s;\r
+    } data;\r
+\r
+    struct\r
+    {\r
+        int size;\r
+        int step;\r
+    }\r
+    dim[CV_MAX_DIM];\r
+}\r
+CvMatND;\r
+\r
+#define CV_IS_MATND_HDR(mat) \\r
+    ((mat) != NULL && (((const CvMatND*)(mat))->type & CV_MAGIC_MASK) == CV_MATND_MAGIC_VAL)\r
+\r
+#define CV_IS_MATND(mat) \\r
+    (CV_IS_MATND_HDR(mat) && ((const CvMatND*)(mat))->data.ptr != NULL)\r
+\r
+\r
+/****************************************************************************************\\r
+*                      Multi-dimensional sparse array (CvSparseMat)                      *\r
+\****************************************************************************************/\r
+\r
+#define CV_SPARSE_MAT_MAGIC_VAL    0x42440000\r
+#define CV_TYPE_NAME_SPARSE_MAT    "opencv-sparse-matrix"\r
+\r
+struct CvSet;\r
+\r
+typedef struct CvSparseMat\r
+{\r
+    int type;\r
+    int dims;\r
+    int* refcount;\r
+    int hdr_refcount;\r
+\r
+    struct CvSet* heap;\r
+    void** hashtable;\r
+    int hashsize;\r
+    int valoffset;\r
+    int idxoffset;\r
+    int size[CV_MAX_DIM];\r
+}\r
+CvSparseMat;\r
+\r
+#define CV_IS_SPARSE_MAT_HDR(mat) \\r
+    ((mat) != NULL && \\r
+    (((const CvSparseMat*)(mat))->type & CV_MAGIC_MASK) == CV_SPARSE_MAT_MAGIC_VAL)\r
+\r
+#define CV_IS_SPARSE_MAT(mat) \\r
+    CV_IS_SPARSE_MAT_HDR(mat)\r
+\r
+/**************** iteration through a sparse array *****************/\r
+\r
+typedef struct CvSparseNode\r
+{\r
+    unsigned hashval;\r
+    struct CvSparseNode* next;\r
+}\r
+CvSparseNode;\r
+\r
+typedef struct CvSparseMatIterator\r
+{\r
+    CvSparseMat* mat;\r
+    CvSparseNode* node;\r
+    int curidx;\r
+}\r
+CvSparseMatIterator;\r
+\r
+#define CV_NODE_VAL(mat,node)   ((void*)((uchar*)(node) + (mat)->valoffset))\r
+#define CV_NODE_IDX(mat,node)   ((int*)((uchar*)(node) + (mat)->idxoffset))\r
+\r
+/****************************************************************************************\\r
+*                                         Histogram                                      *\r
+\****************************************************************************************/\r
+\r
+typedef int CvHistType;\r
+\r
+#define CV_HIST_MAGIC_VAL     0x42450000\r
+#define CV_HIST_UNIFORM_FLAG  (1 << 10)\r
+\r
+/* indicates whether bin ranges are set already or not */\r
+#define CV_HIST_RANGES_FLAG   (1 << 11)\r
+\r
+#define CV_HIST_ARRAY         0\r
+#define CV_HIST_SPARSE        1\r
+#define CV_HIST_TREE          CV_HIST_SPARSE\r
+\r
+/* should be used as a parameter only,\r
+   it turns to CV_HIST_UNIFORM_FLAG of hist->type */\r
+#define CV_HIST_UNIFORM       1\r
+\r
+typedef struct CvHistogram\r
+{\r
+    int     type;\r
+    CvArr*  bins;\r
+    float   thresh[CV_MAX_DIM][2];  /* For uniform histograms.                      */\r
+    float** thresh2;                /* For non-uniform histograms.                  */\r
+    CvMatND mat;                    /* Embedded matrix header for array histograms. */\r
+}\r
+CvHistogram;\r
+\r
+#define CV_IS_HIST( hist ) \\r
+    ((hist) != NULL  && \\r
+     (((CvHistogram*)(hist))->type & CV_MAGIC_MASK) == CV_HIST_MAGIC_VAL && \\r
+     (hist)->bins != NULL)\r
+\r
+#define CV_IS_UNIFORM_HIST( hist ) \\r
+    (((hist)->type & CV_HIST_UNIFORM_FLAG) != 0)\r
+\r
+#define CV_IS_SPARSE_HIST( hist ) \\r
+    CV_IS_SPARSE_MAT((hist)->bins)\r
+\r
+#define CV_HIST_HAS_RANGES( hist ) \\r
+    (((hist)->type & CV_HIST_RANGES_FLAG) != 0)\r
+\r
+/****************************************************************************************\\r
+*                      Other supplementary data type definitions                         *\r
+\****************************************************************************************/\r
+\r
+/*************************************** CvRect *****************************************/\r
+\r
+typedef struct CvRect\r
+{\r
+    int x;\r
+    int y;\r
+    int width;\r
+    int height;\r
+}\r
+CvRect;\r
+\r
+CV_INLINE  CvRect  cvRect( int x, int y, int width, int height )\r
+{\r
+    CvRect r;\r
+\r
+    r.x = x;\r
+    r.y = y;\r
+    r.width = width;\r
+    r.height = height;\r
+\r
+    return r;\r
+}\r
+\r
+\r
+CV_INLINE  IplROI  cvRectToROI( CvRect rect, int coi )\r
+{\r
+    IplROI roi;\r
+    roi.xOffset = rect.x;\r
+    roi.yOffset = rect.y;\r
+    roi.width = rect.width;\r
+    roi.height = rect.height;\r
+    roi.coi = coi;\r
+\r
+    return roi;\r
+}\r
+\r
+\r
+CV_INLINE  CvRect  cvROIToRect( IplROI roi )\r
+{\r
+    return cvRect( roi.xOffset, roi.yOffset, roi.width, roi.height );\r
+}\r
+\r
+/*********************************** CvTermCriteria *************************************/\r
+\r
+#define CV_TERMCRIT_ITER    1\r
+#define CV_TERMCRIT_NUMBER  CV_TERMCRIT_ITER\r
+#define CV_TERMCRIT_EPS     2\r
+\r
+typedef struct CvTermCriteria\r
+{\r
+    int    type;  /* may be combination of\r
+                     CV_TERMCRIT_ITER\r
+                     CV_TERMCRIT_EPS */\r
+    int    max_iter;\r
+    double epsilon;\r
+}\r
+CvTermCriteria;\r
+\r
+CV_INLINE  CvTermCriteria  cvTermCriteria( int type, int max_iter, double epsilon )\r
+{\r
+    CvTermCriteria t;\r
+\r
+    t.type = type;\r
+    t.max_iter = max_iter;\r
+    t.epsilon = (float)epsilon;\r
+\r
+    return t;\r
+}\r
+\r
+\r
+/******************************* CvPoint and variants ***********************************/\r
+\r
+typedef struct CvPoint\r
+{\r
+    int x;\r
+    int y;\r
+}\r
+CvPoint;\r
+\r
+\r
+CV_INLINE  CvPoint  cvPoint( int x, int y )\r
+{\r
+    CvPoint p;\r
+\r
+    p.x = x;\r
+    p.y = y;\r
+\r
+    return p;\r
+}\r
+\r
+\r
+typedef struct CvPoint2D32f\r
+{\r
+    float x;\r
+    float y;\r
+}\r
+CvPoint2D32f;\r
+\r
+\r
+CV_INLINE  CvPoint2D32f  cvPoint2D32f( double x, double y )\r
+{\r
+    CvPoint2D32f p;\r
+\r
+    p.x = (float)x;\r
+    p.y = (float)y;\r
+\r
+    return p;\r
+}\r
+\r
+\r
+CV_INLINE  CvPoint2D32f  cvPointTo32f( CvPoint point )\r
+{\r
+    return cvPoint2D32f( (float)point.x, (float)point.y );\r
+}\r
+\r
+\r
+CV_INLINE  CvPoint  cvPointFrom32f( CvPoint2D32f point )\r
+{\r
+    CvPoint ipt;\r
+    ipt.x = cvRound(point.x);\r
+    ipt.y = cvRound(point.y);\r
+\r
+    return ipt;\r
+}\r
+\r
+\r
+typedef struct CvPoint3D32f\r
+{\r
+    float x;\r
+    float y;\r
+    float z;\r
+}\r
+CvPoint3D32f;\r
+\r
+\r
+CV_INLINE  CvPoint3D32f  cvPoint3D32f( double x, double y, double z )\r
+{\r
+    CvPoint3D32f p;\r
+\r
+    p.x = (float)x;\r
+    p.y = (float)y;\r
+    p.z = (float)z;\r
+\r
+    return p;\r
+}\r
+\r
+\r
+typedef struct CvPoint2D64f\r
+{\r
+    double x;\r
+    double y;\r
+}\r
+CvPoint2D64f;\r
+\r
+\r
+CV_INLINE  CvPoint2D64f  cvPoint2D64f( double x, double y )\r
+{\r
+    CvPoint2D64f p;\r
+\r
+    p.x = x;\r
+    p.y = y;\r
+\r
+    return p;\r
+}\r
+\r
+\r
+typedef struct CvPoint3D64f\r
+{\r
+    double x;\r
+    double y;\r
+    double z;\r
+}\r
+CvPoint3D64f;\r
+\r
+\r
+CV_INLINE  CvPoint3D64f  cvPoint3D64f( double x, double y, double z )\r
+{\r
+    CvPoint3D64f p;\r
+\r
+    p.x = x;\r
+    p.y = y;\r
+    p.z = z;\r
+\r
+    return p;\r
+}\r
+\r
+\r
+/******************************** CvSize's & CvBox **************************************/\r
+\r
+typedef struct\r
+{\r
+    int width;\r
+    int height;\r
+}\r
+CvSize;\r
+\r
+CV_INLINE  CvSize  cvSize( int width, int height )\r
+{\r
+    CvSize s;\r
+\r
+    s.width = width;\r
+    s.height = height;\r
+\r
+    return s;\r
+}\r
+\r
+typedef struct CvSize2D32f\r
+{\r
+    float width;\r
+    float height;\r
+}\r
+CvSize2D32f;\r
+\r
+\r
+CV_INLINE  CvSize2D32f  cvSize2D32f( double width, double height )\r
+{\r
+    CvSize2D32f s;\r
+\r
+    s.width = (float)width;\r
+    s.height = (float)height;\r
+\r
+    return s;\r
+}\r
+\r
+typedef struct CvBox2D\r
+{\r
+    CvPoint2D32f center;  /* Center of the box.                          */\r
+    CvSize2D32f  size;    /* Box width and length.                       */\r
+    float angle;          /* Angle between the horizontal axis           */\r
+                          /* and the first side (i.e. length) in degrees */\r
+}\r
+CvBox2D;\r
+\r
+\r
+/* Line iterator state: */\r
+typedef struct CvLineIterator\r
+{\r
+    /* Pointer to the current point: */\r
+    uchar* ptr;\r
+\r
+    /* Bresenham algorithm state: */\r
+    int  err;\r
+    int  plus_delta;\r
+    int  minus_delta;\r
+    int  plus_step;\r
+    int  minus_step;\r
+}\r
+CvLineIterator;\r
+\r
+\r
+\r
+/************************************* CvSlice ******************************************/\r
+\r
+typedef struct CvSlice\r
+{\r
+    int  start_index, end_index;\r
+}\r
+CvSlice;\r
+\r
+CV_INLINE  CvSlice  cvSlice( int start, int end )\r
+{\r
+    CvSlice slice;\r
+    slice.start_index = start;\r
+    slice.end_index = end;\r
+\r
+    return slice;\r
+}\r
+\r
+#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff\r
+#define CV_WHOLE_SEQ  cvSlice(0, CV_WHOLE_SEQ_END_INDEX)\r
+\r
+\r
+/************************************* CvScalar *****************************************/\r
+\r
+typedef struct CvScalar\r
+{\r
+    double val[4];\r
+}\r
+CvScalar;\r
+\r
+CV_INLINE  CvScalar  cvScalar( double val0, double val1 CV_DEFAULT(0),\r
+                               double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0))\r
+{\r
+    CvScalar scalar;\r
+    scalar.val[0] = val0; scalar.val[1] = val1;\r
+    scalar.val[2] = val2; scalar.val[3] = val3;\r
+    return scalar;\r
+}\r
+\r
+\r
+CV_INLINE  CvScalar  cvRealScalar( double val0 )\r
+{\r
+    CvScalar scalar;\r
+    scalar.val[0] = val0;\r
+    scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;\r
+    return scalar;\r
+}\r
+\r
+CV_INLINE  CvScalar  cvScalarAll( double val0123 )\r
+{\r
+    CvScalar scalar;\r
+    scalar.val[0] = val0123;\r
+    scalar.val[1] = val0123;\r
+    scalar.val[2] = val0123;\r
+    scalar.val[3] = val0123;\r
+    return scalar;\r
+}\r
+\r
+/****************************************************************************************\\r
+*                                   Dynamic Data structures                              *\r
+\****************************************************************************************/\r
+\r
+/******************************** Memory storage ****************************************/\r
+\r
+typedef struct CvMemBlock\r
+{\r
+    struct CvMemBlock*  prev;\r
+    struct CvMemBlock*  next;\r
+}\r
+CvMemBlock;\r
+\r
+#define CV_STORAGE_MAGIC_VAL    0x42890000\r
+\r
+typedef struct CvMemStorage\r
+{\r
+    int signature;\r
+    CvMemBlock* bottom;           /* First allocated block.                   */\r
+    CvMemBlock* top;              /* Current memory block - top of the stack. */\r
+    struct  CvMemStorage* parent; /* We get new blocks from parent as needed. */\r
+    int block_size;               /* Block size.                              */\r
+    int free_space;               /* Remaining free space in current block.   */\r
+}\r
+CvMemStorage;\r
+\r
+#define CV_IS_STORAGE(storage)  \\r
+    ((storage) != NULL &&       \\r
+    (((CvMemStorage*)(storage))->signature & CV_MAGIC_MASK) == CV_STORAGE_MAGIC_VAL)\r
+\r
+\r
+typedef struct CvMemStoragePos\r
+{\r
+    CvMemBlock* top;\r
+    int free_space;\r
+}\r
+CvMemStoragePos;\r
+\r
+\r
+/*********************************** Sequence *******************************************/\r
+\r
+typedef struct CvSeqBlock\r
+{\r
+    struct CvSeqBlock*  prev; /* Previous sequence block.                   */\r
+    struct CvSeqBlock*  next; /* Next sequence block.                       */\r
+  int    start_index;         /* Index of the first element in the block +  */\r
+                              /* sequence->first->start_index.              */\r
+    int    count;             /* Number of elements in the block.           */\r
+    schar* data;              /* Pointer to the first element of the block. */\r
+}\r
+CvSeqBlock;\r
+\r
+\r
+#define CV_TREE_NODE_FIELDS(node_type)                               \\r
+    int       flags;             /* Miscellaneous flags.     */      \\r
+    int       header_size;       /* Size of sequence header. */      \\r
+    struct    node_type* h_prev; /* Previous sequence.       */      \\r
+    struct    node_type* h_next; /* Next sequence.           */      \\r
+    struct    node_type* v_prev; /* 2nd previous sequence.   */      \\r
+    struct    node_type* v_next  /* 2nd next sequence.       */\r
+\r
+/*\r
+   Read/Write sequence.\r
+   Elements can be dynamically inserted to or deleted from the sequence.\r
+*/\r
+#define CV_SEQUENCE_FIELDS()                                              \\r
+    CV_TREE_NODE_FIELDS(CvSeq);                                           \\r
+    int       total;          /* Total number of elements.            */  \\r
+    int       elem_size;      /* Size of sequence element in bytes.   */  \\r
+    schar*    block_max;      /* Maximal bound of the last block.     */  \\r
+    schar*    ptr;            /* Current write pointer.               */  \\r
+    int       delta_elems;    /* Grow seq this many at a time.        */  \\r
+    CvMemStorage* storage;    /* Where the seq is stored.             */  \\r
+    CvSeqBlock* free_blocks;  /* Free blocks list.                    */  \\r
+    CvSeqBlock* first;        /* Pointer to the first sequence block. */\r
+\r
+typedef struct CvSeq\r
+{\r
+    CV_SEQUENCE_FIELDS()\r
+}\r
+CvSeq;\r
+\r
+#define CV_TYPE_NAME_SEQ             "opencv-sequence"\r
+#define CV_TYPE_NAME_SEQ_TREE        "opencv-sequence-tree"\r
+\r
+/*************************************** Set ********************************************/\r
+/*\r
+  Set.\r
+  Order is not preserved. There can be gaps between sequence elements.\r
+  After the element has been inserted it stays in the same place all the time.\r
+  The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists.\r
+*/\r
+#define CV_SET_ELEM_FIELDS(elem_type)   \\r
+    int  flags;                         \\r
+    struct elem_type* next_free;\r
+\r
+typedef struct CvSetElem\r
+{\r
+    CV_SET_ELEM_FIELDS(CvSetElem)\r
+}\r
+CvSetElem;\r
+\r
+#define CV_SET_FIELDS()      \\r
+    CV_SEQUENCE_FIELDS()     \\r
+    CvSetElem* free_elems;   \\r
+    int active_count;\r
+\r
+typedef struct CvSet\r
+{\r
+    CV_SET_FIELDS()\r
+}\r
+CvSet;\r
+\r
+\r
+#define CV_SET_ELEM_IDX_MASK   ((1 << 26) - 1)\r
+#define CV_SET_ELEM_FREE_FLAG  (1 << (sizeof(int)*8-1))\r
+\r
+/* Checks whether the element pointed by ptr belongs to a set or not */\r
+#define CV_IS_SET_ELEM( ptr )  (((CvSetElem*)(ptr))->flags >= 0)\r
+\r
+/************************************* Graph ********************************************/\r
+\r
+/*\r
+  We represent a graph as a set of vertices.\r
+  Vertices contain their adjacency lists (more exactly, pointers to first incoming or\r
+  outcoming edge (or 0 if isolated vertex)). Edges are stored in another set.\r
+  There is a singly-linked list of incoming/outcoming edges for each vertex.\r
+\r
+  Each edge consists of\r
+\r
+     o   Two pointers to the starting and ending vertices\r
+         (vtx[0] and vtx[1] respectively).\r
+\r
+        A graph may be oriented or not. In the latter case, edges between\r
+        vertex i to vertex j are not distinguished during search operations.\r
+\r
+     o   Two pointers to next edges for the starting and ending vertices, where\r
+         next[0] points to the next edge in the vtx[0] adjacency list and\r
+         next[1] points to the next edge in the vtx[1] adjacency list.\r
+*/\r
+#define CV_GRAPH_EDGE_FIELDS()      \\r
+    int flags;                      \\r
+    float weight;                   \\r
+    struct CvGraphEdge* next[2];    \\r
+    struct CvGraphVtx* vtx[2];\r
+\r
+\r
+#define CV_GRAPH_VERTEX_FIELDS()    \\r
+    int flags;                      \\r
+    struct CvGraphEdge* first;\r
+\r
+\r
+typedef struct CvGraphEdge\r
+{\r
+    CV_GRAPH_EDGE_FIELDS()\r
+}\r
+CvGraphEdge;\r
+\r
+typedef struct CvGraphVtx\r
+{\r
+    CV_GRAPH_VERTEX_FIELDS()\r
+}\r
+CvGraphVtx;\r
+\r
+typedef struct CvGraphVtx2D\r
+{\r
+    CV_GRAPH_VERTEX_FIELDS()\r
+    CvPoint2D32f* ptr;\r
+}\r
+CvGraphVtx2D;\r
+\r
+/*\r
+   Graph is "derived" from the set (this is set a of vertices)\r
+   and includes another set (edges)\r
+*/\r
+#define  CV_GRAPH_FIELDS()   \\r
+    CV_SET_FIELDS()          \\r
+    CvSet* edges;\r
+\r
+typedef struct CvGraph\r
+{\r
+    CV_GRAPH_FIELDS()\r
+}\r
+CvGraph;\r
+\r
+#define CV_TYPE_NAME_GRAPH "opencv-graph"\r
+\r
+/*********************************** Chain/Countour *************************************/\r
+\r
+typedef struct CvChain\r
+{\r
+    CV_SEQUENCE_FIELDS()\r
+    CvPoint  origin;\r
+}\r
+CvChain;\r
+\r
+#define CV_CONTOUR_FIELDS()  \\r
+    CV_SEQUENCE_FIELDS()     \\r
+    CvRect rect;             \\r
+    int color;               \\r
+    int reserved[3];\r
+\r
+typedef struct CvContour\r
+{\r
+    CV_CONTOUR_FIELDS()\r
+}\r
+CvContour;\r
+\r
+typedef CvContour CvPoint2DSeq;\r
+\r
+/****************************************************************************************\\r
+*                                    Sequence types                                      *\r
+\****************************************************************************************/\r
+\r
+#define CV_SEQ_MAGIC_VAL             0x42990000\r
+\r
+#define CV_IS_SEQ(seq) \\r
+    ((seq) != NULL && (((CvSeq*)(seq))->flags & CV_MAGIC_MASK) == CV_SEQ_MAGIC_VAL)\r
+\r
+#define CV_SET_MAGIC_VAL             0x42980000\r
+#define CV_IS_SET(set) \\r
+    ((set) != NULL && (((CvSeq*)(set))->flags & CV_MAGIC_MASK) == CV_SET_MAGIC_VAL)\r
+\r
+#define CV_SEQ_ELTYPE_BITS           9\r
+#define CV_SEQ_ELTYPE_MASK           ((1 << CV_SEQ_ELTYPE_BITS) - 1)\r
+\r
+#define CV_SEQ_ELTYPE_POINT          CV_32SC2  /* (x,y) */\r
+#define CV_SEQ_ELTYPE_CODE           CV_8UC1   /* freeman code: 0..7 */\r
+#define CV_SEQ_ELTYPE_GENERIC        0\r
+#define CV_SEQ_ELTYPE_PTR            CV_USRTYPE1\r
+#define CV_SEQ_ELTYPE_PPOINT         CV_SEQ_ELTYPE_PTR  /* &(x,y) */\r
+#define CV_SEQ_ELTYPE_INDEX          CV_32SC1  /* #(x,y) */\r
+#define CV_SEQ_ELTYPE_GRAPH_EDGE     0  /* &next_o, &next_d, &vtx_o, &vtx_d */\r
+#define CV_SEQ_ELTYPE_GRAPH_VERTEX   0  /* first_edge, &(x,y) */\r
+#define CV_SEQ_ELTYPE_TRIAN_ATR      0  /* vertex of the binary tree   */\r
+#define CV_SEQ_ELTYPE_CONNECTED_COMP 0  /* connected component  */\r
+#define CV_SEQ_ELTYPE_POINT3D        CV_32FC3  /* (x,y,z)  */\r
+\r
+#define CV_SEQ_KIND_BITS        3\r
+#define CV_SEQ_KIND_MASK        (((1 << CV_SEQ_KIND_BITS) - 1)<<CV_SEQ_ELTYPE_BITS)\r
+\r
+/* types of sequences */\r
+#define CV_SEQ_KIND_GENERIC     (0 << CV_SEQ_ELTYPE_BITS)\r
+#define CV_SEQ_KIND_CURVE       (1 << CV_SEQ_ELTYPE_BITS)\r
+#define CV_SEQ_KIND_BIN_TREE    (2 << CV_SEQ_ELTYPE_BITS)\r
+\r
+/* types of sparse sequences (sets) */\r
+#define CV_SEQ_KIND_GRAPH       (3 << CV_SEQ_ELTYPE_BITS)\r
+#define CV_SEQ_KIND_SUBDIV2D    (4 << CV_SEQ_ELTYPE_BITS)\r
+\r
+#define CV_SEQ_FLAG_SHIFT       (CV_SEQ_KIND_BITS + CV_SEQ_ELTYPE_BITS)\r
+\r
+/* flags for curves */\r
+#define CV_SEQ_FLAG_CLOSED     (1 << CV_SEQ_FLAG_SHIFT)\r
+#define CV_SEQ_FLAG_SIMPLE     (2 << CV_SEQ_FLAG_SHIFT)\r
+#define CV_SEQ_FLAG_CONVEX     (4 << CV_SEQ_FLAG_SHIFT)\r
+#define CV_SEQ_FLAG_HOLE       (8 << CV_SEQ_FLAG_SHIFT)\r
+\r
+/* flags for graphs */\r
+#define CV_GRAPH_FLAG_ORIENTED (1 << CV_SEQ_FLAG_SHIFT)\r
+\r
+#define CV_GRAPH               CV_SEQ_KIND_GRAPH\r
+#define CV_ORIENTED_GRAPH      (CV_SEQ_KIND_GRAPH|CV_GRAPH_FLAG_ORIENTED)\r
+\r
+/* point sets */\r
+#define CV_SEQ_POINT_SET       (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT)\r
+#define CV_SEQ_POINT3D_SET     (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT3D)\r
+#define CV_SEQ_POLYLINE        (CV_SEQ_KIND_CURVE  | CV_SEQ_ELTYPE_POINT)\r
+#define CV_SEQ_POLYGON         (CV_SEQ_FLAG_CLOSED | CV_SEQ_POLYLINE )\r
+#define CV_SEQ_CONTOUR         CV_SEQ_POLYGON\r
+#define CV_SEQ_SIMPLE_POLYGON  (CV_SEQ_FLAG_SIMPLE | CV_SEQ_POLYGON  )\r
+\r
+/* chain-coded curves */\r
+#define CV_SEQ_CHAIN           (CV_SEQ_KIND_CURVE  | CV_SEQ_ELTYPE_CODE)\r
+#define CV_SEQ_CHAIN_CONTOUR   (CV_SEQ_FLAG_CLOSED | CV_SEQ_CHAIN)\r
+\r
+/* binary tree for the contour */\r
+#define CV_SEQ_POLYGON_TREE    (CV_SEQ_KIND_BIN_TREE  | CV_SEQ_ELTYPE_TRIAN_ATR)\r
+\r
+/* sequence of the connected components */\r
+#define CV_SEQ_CONNECTED_COMP  (CV_SEQ_KIND_GENERIC  | CV_SEQ_ELTYPE_CONNECTED_COMP)\r
+\r
+/* sequence of the integer numbers */\r
+#define CV_SEQ_INDEX           (CV_SEQ_KIND_GENERIC  | CV_SEQ_ELTYPE_INDEX)\r
+\r
+#define CV_SEQ_ELTYPE( seq )   ((seq)->flags & CV_SEQ_ELTYPE_MASK)\r
+#define CV_SEQ_KIND( seq )     ((seq)->flags & CV_SEQ_KIND_MASK )\r
+\r
+/* flag checking */\r
+#define CV_IS_SEQ_INDEX( seq )      ((CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_INDEX) && \\r
+                                     (CV_SEQ_KIND(seq) == CV_SEQ_KIND_GENERIC))\r
+\r
+#define CV_IS_SEQ_CURVE( seq )      (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE)\r
+#define CV_IS_SEQ_CLOSED( seq )     (((seq)->flags & CV_SEQ_FLAG_CLOSED) != 0)\r
+#define CV_IS_SEQ_CONVEX( seq )     (((seq)->flags & CV_SEQ_FLAG_CONVEX) != 0)\r
+#define CV_IS_SEQ_HOLE( seq )       (((seq)->flags & CV_SEQ_FLAG_HOLE) != 0)\r
+#define CV_IS_SEQ_SIMPLE( seq )     ((((seq)->flags & CV_SEQ_FLAG_SIMPLE) != 0) || \\r
+                                    CV_IS_SEQ_CONVEX(seq))\r
+\r
+/* type checking macros */\r
+#define CV_IS_SEQ_POINT_SET( seq ) \\r
+    ((CV_SEQ_ELTYPE(seq) == CV_32SC2 || CV_SEQ_ELTYPE(seq) == CV_32FC2))\r
+\r
+#define CV_IS_SEQ_POINT_SUBSET( seq ) \\r
+    (CV_IS_SEQ_INDEX( seq ) || CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_PPOINT)\r
+\r
+#define CV_IS_SEQ_POLYLINE( seq )   \\r
+    (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && CV_IS_SEQ_POINT_SET(seq))\r
+\r
+#define CV_IS_SEQ_POLYGON( seq )   \\r
+    (CV_IS_SEQ_POLYLINE(seq) && CV_IS_SEQ_CLOSED(seq))\r
+\r
+#define CV_IS_SEQ_CHAIN( seq )   \\r
+    (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && (seq)->elem_size == 1)\r
+\r
+#define CV_IS_SEQ_CONTOUR( seq )   \\r
+    (CV_IS_SEQ_CLOSED(seq) && (CV_IS_SEQ_POLYLINE(seq) || CV_IS_SEQ_CHAIN(seq)))\r
+\r
+#define CV_IS_SEQ_CHAIN_CONTOUR( seq ) \\r
+    (CV_IS_SEQ_CHAIN( seq ) && CV_IS_SEQ_CLOSED( seq ))\r
+\r
+#define CV_IS_SEQ_POLYGON_TREE( seq ) \\r
+    (CV_SEQ_ELTYPE (seq) ==  CV_SEQ_ELTYPE_TRIAN_ATR &&    \\r
+    CV_SEQ_KIND( seq ) ==  CV_SEQ_KIND_BIN_TREE )\r
+\r
+#define CV_IS_GRAPH( seq )    \\r
+    (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_GRAPH)\r
+\r
+#define CV_IS_GRAPH_ORIENTED( seq )   \\r
+    (((seq)->flags & CV_GRAPH_FLAG_ORIENTED) != 0)\r
+\r
+#define CV_IS_SUBDIV2D( seq )  \\r
+    (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_SUBDIV2D)\r
+\r
+/****************************************************************************************/\r
+/*                            Sequence writer & reader                                  */\r
+/****************************************************************************************/\r
+\r
+#define CV_SEQ_WRITER_FIELDS()                                     \\r
+    int          header_size;                                      \\r
+    CvSeq*       seq;        /* the sequence written */            \\r
+    CvSeqBlock*  block;      /* current block */                   \\r
+    schar*       ptr;        /* pointer to free space */           \\r
+    schar*       block_min;  /* pointer to the beginning of block*/\\r
+    schar*       block_max;  /* pointer to the end of block */\r
+\r
+typedef struct CvSeqWriter\r
+{\r
+    CV_SEQ_WRITER_FIELDS()\r
+}\r
+CvSeqWriter;\r
+\r
+\r
+#define CV_SEQ_READER_FIELDS()                                      \\r
+    int          header_size;                                       \\r
+    CvSeq*       seq;        /* sequence, beign read */             \\r
+    CvSeqBlock*  block;      /* current block */                    \\r
+    schar*       ptr;        /* pointer to element be read next */  \\r
+    schar*       block_min;  /* pointer to the beginning of block */\\r
+    schar*       block_max;  /* pointer to the end of block */      \\r
+    int          delta_index;/* = seq->first->start_index   */      \\r
+    schar*       prev_elem;  /* pointer to previous element */\r
+\r
+\r
+typedef struct CvSeqReader\r
+{\r
+    CV_SEQ_READER_FIELDS()\r
+}\r
+CvSeqReader;\r
+\r
+/****************************************************************************************/\r
+/*                                Operations on sequences                               */\r
+/****************************************************************************************/\r
+\r
+#define  CV_SEQ_ELEM( seq, elem_type, index )                    \\r
+/* assert gives some guarantee that <seq> parameter is valid */  \\r
+(   assert(sizeof((seq)->first[0]) == sizeof(CvSeqBlock) &&      \\r
+    (seq)->elem_size == sizeof(elem_type)),                      \\r
+    (elem_type*)((seq)->first && (unsigned)index <               \\r
+    (unsigned)((seq)->first->count) ?                            \\r
+    (seq)->first->data + (index) * sizeof(elem_type) :           \\r
+    cvGetSeqElem( (CvSeq*)(seq), (index) )))\r
+#define CV_GET_SEQ_ELEM( elem_type, seq, index ) CV_SEQ_ELEM( (seq), elem_type, (index) )\r
+\r
+/* Add element to sequence: */\r
+#define CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer )     \\r
+{                                                     \\r
+    if( (writer).ptr >= (writer).block_max )          \\r
+    {                                                 \\r
+        cvCreateSeqBlock( &writer);                   \\r
+    }                                                 \\r
+    memcpy((writer).ptr, elem_ptr, (writer).seq->elem_size);\\r
+    (writer).ptr += (writer).seq->elem_size;          \\r
+}\r
+\r
+#define CV_WRITE_SEQ_ELEM( elem, writer )             \\r
+{                                                     \\r
+    assert( (writer).seq->elem_size == sizeof(elem)); \\r
+    if( (writer).ptr >= (writer).block_max )          \\r
+    {                                                 \\r
+        cvCreateSeqBlock( &writer);                   \\r
+    }                                                 \\r
+    assert( (writer).ptr <= (writer).block_max - sizeof(elem));\\r
+    memcpy((writer).ptr, &(elem), sizeof(elem));      \\r
+    (writer).ptr += sizeof(elem);                     \\r
+}\r
+\r
+\r
+/* Move reader position forward: */\r
+#define CV_NEXT_SEQ_ELEM( elem_size, reader )                 \\r
+{                                                             \\r
+    if( ((reader).ptr += (elem_size)) >= (reader).block_max ) \\r
+    {                                                         \\r
+        cvChangeSeqBlock( &(reader), 1 );                     \\r
+    }                                                         \\r
+}\r
+\r
+\r
+/* Move reader position backward: */\r
+#define CV_PREV_SEQ_ELEM( elem_size, reader )                \\r
+{                                                            \\r
+    if( ((reader).ptr -= (elem_size)) < (reader).block_min ) \\r
+    {                                                        \\r
+        cvChangeSeqBlock( &(reader), -1 );                   \\r
+    }                                                        \\r
+}\r
+\r
+/* Read element and move read position forward: */\r
+#define CV_READ_SEQ_ELEM( elem, reader )                       \\r
+{                                                              \\r
+    assert( (reader).seq->elem_size == sizeof(elem));          \\r
+    memcpy( &(elem), (reader).ptr, sizeof((elem)));            \\r
+    CV_NEXT_SEQ_ELEM( sizeof(elem), reader )                   \\r
+}\r
+\r
+/* Read element and move read position backward: */\r
+#define CV_REV_READ_SEQ_ELEM( elem, reader )                     \\r
+{                                                                \\r
+    assert( (reader).seq->elem_size == sizeof(elem));            \\r
+    memcpy(&(elem), (reader).ptr, sizeof((elem)));               \\r
+    CV_PREV_SEQ_ELEM( sizeof(elem), reader )                     \\r
+}\r
+\r
+\r
+#define CV_READ_CHAIN_POINT( _pt, reader )                              \\r
+{                                                                       \\r
+    (_pt) = (reader).pt;                                                \\r
+    if( (reader).ptr )                                                  \\r
+    {                                                                   \\r
+        CV_READ_SEQ_ELEM( (reader).code, (reader));                     \\r
+        assert( ((reader).code & ~7) == 0 );                            \\r
+        (reader).pt.x += (reader).deltas[(int)(reader).code][0];        \\r
+        (reader).pt.y += (reader).deltas[(int)(reader).code][1];        \\r
+    }                                                                   \\r
+}\r
+\r
+#define CV_CURRENT_POINT( reader )  (*((CvPoint*)((reader).ptr)))\r
+#define CV_PREV_POINT( reader )     (*((CvPoint*)((reader).prev_elem)))\r
+\r
+#define CV_READ_EDGE( pt1, pt2, reader )               \\r
+{                                                      \\r
+    assert( sizeof(pt1) == sizeof(CvPoint) &&          \\r
+            sizeof(pt2) == sizeof(CvPoint) &&          \\r
+            reader.seq->elem_size == sizeof(CvPoint)); \\r
+    (pt1) = CV_PREV_POINT( reader );                   \\r
+    (pt2) = CV_CURRENT_POINT( reader );                \\r
+    (reader).prev_elem = (reader).ptr;                 \\r
+    CV_NEXT_SEQ_ELEM( sizeof(CvPoint), (reader));      \\r
+}\r
+\r
+/************ Graph macros ************/\r
+\r
+/* Return next graph edge for given vertex: */\r
+#define  CV_NEXT_GRAPH_EDGE( edge, vertex )                              \\r
+     (assert((edge)->vtx[0] == (vertex) || (edge)->vtx[1] == (vertex)),  \\r
+      (edge)->next[(edge)->vtx[1] == (vertex)])\r
+\r
+\r
+\r
+/****************************************************************************************\\r
+*             Data structures for persistence (a.k.a serialization) functionality        *\r
+\****************************************************************************************/\r
+\r
+/* "black box" file storage */\r
+typedef struct CvFileStorage CvFileStorage;\r
+\r
+/* Storage flags: */\r
+#define CV_STORAGE_READ          0\r
+#define CV_STORAGE_WRITE         1\r
+#define CV_STORAGE_WRITE_TEXT    CV_STORAGE_WRITE\r
+#define CV_STORAGE_WRITE_BINARY  CV_STORAGE_WRITE\r
+#define CV_STORAGE_APPEND        2\r
+\r
+/* List of attributes: */\r
+typedef struct CvAttrList\r
+{\r
+    const char** attr;         /* NULL-terminated array of (attribute_name,attribute_value) pairs. */\r
+    struct CvAttrList* next;   /* Pointer to next chunk of the attributes list.                    */\r
+}\r
+CvAttrList;\r
+\r
+CV_INLINE CvAttrList cvAttrList( const char** attr CV_DEFAULT(NULL),\r
+                                 CvAttrList* next CV_DEFAULT(NULL) )\r
+{\r
+    CvAttrList l;\r
+    l.attr = attr;\r
+    l.next = next;\r
+\r
+    return l;\r
+}\r
+\r
+struct CvTypeInfo;\r
+\r
+#define CV_NODE_NONE        0\r
+#define CV_NODE_INT         1\r
+#define CV_NODE_INTEGER     CV_NODE_INT\r
+#define CV_NODE_REAL        2\r
+#define CV_NODE_FLOAT       CV_NODE_REAL\r
+#define CV_NODE_STR         3\r
+#define CV_NODE_STRING      CV_NODE_STR\r
+#define CV_NODE_REF         4 /* not used */\r
+#define CV_NODE_SEQ         5\r
+#define CV_NODE_MAP         6\r
+#define CV_NODE_TYPE_MASK   7\r
+\r
+#define CV_NODE_TYPE(flags)  ((flags) & CV_NODE_TYPE_MASK)\r
+\r
+/* file node flags */\r
+#define CV_NODE_FLOW        8 /* Used only for writing structures in YAML format. */\r
+#define CV_NODE_USER        16\r
+#define CV_NODE_EMPTY       32\r
+#define CV_NODE_NAMED       64\r
+\r
+#define CV_NODE_IS_INT(flags)        (CV_NODE_TYPE(flags) == CV_NODE_INT)\r
+#define CV_NODE_IS_REAL(flags)       (CV_NODE_TYPE(flags) == CV_NODE_REAL)\r
+#define CV_NODE_IS_STRING(flags)     (CV_NODE_TYPE(flags) == CV_NODE_STRING)\r
+#define CV_NODE_IS_SEQ(flags)        (CV_NODE_TYPE(flags) == CV_NODE_SEQ)\r
+#define CV_NODE_IS_MAP(flags)        (CV_NODE_TYPE(flags) == CV_NODE_MAP)\r
+#define CV_NODE_IS_COLLECTION(flags) (CV_NODE_TYPE(flags) >= CV_NODE_SEQ)\r
+#define CV_NODE_IS_FLOW(flags)       (((flags) & CV_NODE_FLOW) != 0)\r
+#define CV_NODE_IS_EMPTY(flags)      (((flags) & CV_NODE_EMPTY) != 0)\r
+#define CV_NODE_IS_USER(flags)       (((flags) & CV_NODE_USER) != 0)\r
+#define CV_NODE_HAS_NAME(flags)      (((flags) & CV_NODE_NAMED) != 0)\r
+\r
+#define CV_NODE_SEQ_SIMPLE 256\r
+#define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0)\r
+\r
+typedef struct CvString\r
+{\r
+    int len;\r
+    char* ptr;\r
+}\r
+CvString;\r
+\r
+/* All the keys (names) of elements in the readed file storage\r
+   are stored in the hash to speed up the lookup operations: */\r
+typedef struct CvStringHashNode\r
+{\r
+    unsigned hashval;\r
+    CvString str;\r
+    struct CvStringHashNode* next;\r
+}\r
+CvStringHashNode;\r
+\r
+typedef struct CvGenericHash CvFileNodeHash;\r
+\r
+/* Basic element of the file storage - scalar or collection: */\r
+typedef struct CvFileNode\r
+{\r
+    int tag;\r
+    struct CvTypeInfo* info; /* type information\r
+            (only for user-defined object, for others it is 0) */\r
+    union\r
+    {\r
+        double f; /* scalar floating-point number */\r
+        int i;    /* scalar integer number */\r
+        CvString str; /* text string */\r
+        CvSeq* seq; /* sequence (ordered collection of file nodes) */\r
+        CvFileNodeHash* map; /* map (collection of named file nodes) */\r
+    } data;\r
+}\r
+CvFileNode;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr );\r
+typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr );\r
+typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node );\r
+typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name,\r
+                                      const void* struct_ptr, CvAttrList attributes );\r
+typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr );\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+typedef struct CvTypeInfo\r
+{\r
+    int flags;\r
+    int header_size;\r
+    struct CvTypeInfo* prev;\r
+    struct CvTypeInfo* next;\r
+    const char* type_name;\r
+    CvIsInstanceFunc is_instance;\r
+    CvReleaseFunc release;\r
+    CvReadFunc read;\r
+    CvWriteFunc write;\r
+    CvCloneFunc clone;\r
+}\r
+CvTypeInfo;\r
+\r
+\r
+/**** System data types ******/\r
+\r
+typedef struct CvPluginFuncInfo\r
+{\r
+    void** func_addr;\r
+    void* default_func_addr;\r
+    const char* func_names;\r
+    int search_modules;\r
+    int loaded_from;\r
+}\r
+CvPluginFuncInfo;\r
+\r
+typedef struct CvModuleInfo\r
+{\r
+    struct CvModuleInfo* next;\r
+    const char* name;\r
+    const char* version;\r
+    CvPluginFuncInfo* func_tab;\r
+}\r
+CvModuleInfo;\r
+\r
+#endif /*_CXCORE_TYPES_H_*/\r
+\r
+/* End of file. */\r