--- /dev/null
+/*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_*/
-/*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
// 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,
// 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_*/
#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 ********************************/
-/*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
--- /dev/null
+/*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
-/*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