+++ /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.
-//
-//
-// 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*/
-
-/* ////////////////////////////////////////////////////////////////////
-//
-// CvMat, CvMatND, CvSparceMat and IplImage support functions
-// (creation, deletion, copying, retrieving and setting elements etc.)
-//
-// */
-
-#include "_cxcore.h"
-
-static struct
-{
- Cv_iplCreateImageHeader createHeader;
- Cv_iplAllocateImageData allocateData;
- Cv_iplDeallocate deallocate;
- Cv_iplCreateROI createROI;
- Cv_iplCloneImage cloneImage;
-}
-CvIPL;
-
-// Makes the library use native IPL image allocators
-CV_IMPL void
-cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader,
- Cv_iplAllocateImageData allocateData,
- Cv_iplDeallocate deallocate,
- Cv_iplCreateROI createROI,
- Cv_iplCloneImage cloneImage )
-{
- CV_FUNCNAME( "cvSetIPLAllocators" );
-
- __BEGIN__;
-
- if( !createHeader || !allocateData || !deallocate || !createROI || !cloneImage )
- {
- if( createHeader || allocateData || deallocate || createROI || cloneImage )
- CV_ERROR( CV_StsBadArg, "Either all the pointers should be null or "
- "they all should be non-null" );
- }
-
- CvIPL.createHeader = createHeader;
- CvIPL.allocateData = allocateData;
- CvIPL.deallocate = deallocate;
- CvIPL.createROI = createROI;
- CvIPL.cloneImage = cloneImage;
-
- __END__;
-}
-
-
-/****************************************************************************************\
-* CvMat creation and basic operations *
-\****************************************************************************************/
-
-// Creates CvMat and underlying data
-CV_IMPL CvMat*
-cvCreateMat( int height, int width, int type )
-{
- CvMat* arr = 0;
-
- CV_FUNCNAME( "cvCreateMat" );
-
- __BEGIN__;
-
- CV_CALL( arr = cvCreateMatHeader( height, width, type ));
- CV_CALL( cvCreateData( arr ));
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseMat( &arr );
-
- return arr;
-}
-
-
-static void icvCheckHuge( CvMat* arr )
-{
- if( (int64)arr->step*arr->rows > INT_MAX )
- arr->type &= ~CV_MAT_CONT_FLAG;
-}
-
-// Creates CvMat header only
-CV_IMPL CvMat*
-cvCreateMatHeader( int rows, int cols, int type )
-{
- CvMat* arr = 0;
-
- CV_FUNCNAME( "cvCreateMatHeader" );
-
- __BEGIN__;
-
- int min_step;
- type = CV_MAT_TYPE(type);
-
- if( rows <= 0 || cols <= 0 )
- CV_ERROR( CV_StsBadSize, "Non-positive width or height" );
-
- min_step = CV_ELEM_SIZE(type)*cols;
- if( min_step <= 0 )
- CV_ERROR( CV_StsUnsupportedFormat, "Invalid matrix type" );
-
- CV_CALL( arr = (CvMat*)cvAlloc( sizeof(*arr)));
-
- arr->step = rows == 1 ? 0 : cvAlign(min_step, CV_DEFAULT_MAT_ROW_ALIGN);
- arr->type = CV_MAT_MAGIC_VAL | type |
- (arr->step == 0 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
- arr->rows = rows;
- arr->cols = cols;
- arr->data.ptr = 0;
- arr->refcount = 0;
- arr->hdr_refcount = 1;
-
- icvCheckHuge( arr );
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseMat( &arr );
-
- return arr;
-}
-
-
-// Initializes CvMat header, allocated by the user
-CV_IMPL CvMat*
-cvInitMatHeader( CvMat* arr, int rows, int cols,
- int type, void* data, int step )
-{
- CV_FUNCNAME( "cvInitMatHeader" );
-
- __BEGIN__;
-
- int mask, pix_size, min_step;
-
- if( !arr )
- CV_ERROR_FROM_CODE( CV_StsNullPtr );
-
- if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
- CV_ERROR_FROM_CODE( CV_BadNumChannels );
-
- if( rows <= 0 || cols <= 0 )
- CV_ERROR( CV_StsBadSize, "Non-positive cols or rows" );
-
- type = CV_MAT_TYPE( type );
- arr->type = type | CV_MAT_MAGIC_VAL;
- arr->rows = rows;
- arr->cols = cols;
- arr->data.ptr = (uchar*)data;
- arr->refcount = 0;
- arr->hdr_refcount = 0;
-
- mask = (arr->rows <= 1) - 1;
- pix_size = CV_ELEM_SIZE(type);
- min_step = arr->cols*pix_size & mask;
-
- if( step != CV_AUTOSTEP && step != 0 )
- {
- if( step < min_step )
- CV_ERROR_FROM_CODE( CV_BadStep );
- arr->step = step & mask;
- }
- else
- {
- arr->step = min_step;
- }
-
- arr->type = CV_MAT_MAGIC_VAL | type |
- (arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
-
- icvCheckHuge( arr );
-
- __END__;
-
- return arr;
-}
-
-
-// Deallocates the CvMat structure and underlying data
-CV_IMPL void
-cvReleaseMat( CvMat** array )
-{
- CV_FUNCNAME( "cvReleaseMat" );
-
- __BEGIN__;
-
- if( !array )
- CV_ERROR_FROM_CODE( CV_HeaderIsNull );
-
- if( *array )
- {
- CvMat* arr = *array;
-
- if( !CV_IS_MAT_HDR(arr) && !CV_IS_MATND_HDR(arr) )
- CV_ERROR_FROM_CODE( CV_StsBadFlag );
-
- *array = 0;
-
- cvDecRefData( arr );
- cvFree( &arr );
- }
-
- __END__;
-}
-
-
-// Creates a copy of matrix
-CV_IMPL CvMat*
-cvCloneMat( const CvMat* src )
-{
- CvMat* dst = 0;
- CV_FUNCNAME( "cvCloneMat" );
-
- __BEGIN__;
-
- if( !CV_IS_MAT_HDR( src ))
- CV_ERROR( CV_StsBadArg, "Bad CvMat header" );
-
- CV_CALL( dst = cvCreateMatHeader( src->rows, src->cols, src->type ));
-
- if( src->data.ptr )
- {
- CV_CALL( cvCreateData( dst ));
- CV_CALL( cvCopy( src, dst ));
- }
-
- __END__;
-
- return dst;
-}
-
-
-/****************************************************************************************\
-* CvMatND creation and basic operations *
-\****************************************************************************************/
-
-CV_IMPL CvMatND*
-cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
- int type, void* data )
-{
- CvMatND* result = 0;
-
- CV_FUNCNAME( "cvInitMatNDHeader" );
-
- __BEGIN__;
-
- type = CV_MAT_TYPE(type);
- int i;
- int64 step = CV_ELEM_SIZE(type);
-
- if( !mat )
- CV_ERROR( CV_StsNullPtr, "NULL matrix header pointer" );
-
- if( step == 0 )
- CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
-
- if( !sizes )
- CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
-
- if( dims <= 0 || dims > CV_MAX_DIM )
- CV_ERROR( CV_StsOutOfRange,
- "non-positive or too large number of dimensions" );
-
- for( i = dims - 1; i >= 0; i-- )
- {
- if( sizes[i] <= 0 )
- CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
- mat->dim[i].size = sizes[i];
- if( step > INT_MAX )
- CV_ERROR( CV_StsOutOfRange, "The array is too big" );
- mat->dim[i].step = (int)step;
- step *= sizes[i];
- }
-
- mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
- mat->dims = dims;
- mat->data.ptr = (uchar*)data;
- mat->refcount = 0;
- mat->hdr_refcount = 0;
- result = mat;
-
- __END__;
-
- if( cvGetErrStatus() < 0 && mat )
- {
- mat->type = 0;
- mat->data.ptr = 0;
- }
-
- return result;
-}
-
-
-// Creates CvMatND and underlying data
-CV_IMPL CvMatND*
-cvCreateMatND( int dims, const int* sizes, int type )
-{
- CvMatND* arr = 0;
-
- CV_FUNCNAME( "cvCreateMatND" );
-
- __BEGIN__;
-
- CV_CALL( arr = cvCreateMatNDHeader( dims, sizes, type ));
- CV_CALL( cvCreateData( arr ));
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseMatND( &arr );
-
- return arr;
-}
-
-
-// Creates CvMatND header only
-CV_IMPL CvMatND*
-cvCreateMatNDHeader( int dims, const int* sizes, int type )
-{
- CvMatND* arr = 0;
-
- CV_FUNCNAME( "cvCreateMatNDHeader" );
-
- __BEGIN__;
-
- if( dims <= 0 || dims > CV_MAX_DIM )
- CV_ERROR( CV_StsOutOfRange,
- "non-positive or too large number of dimensions" );
-
- CV_CALL( arr = (CvMatND*)cvAlloc( sizeof(*arr) ));
-
- CV_CALL( cvInitMatNDHeader( arr, dims, sizes, type, 0 ));
- arr->hdr_refcount = 1;
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseMatND( &arr );
-
- return arr;
-}
-
-
-// Creates a copy of nD array
-CV_IMPL CvMatND*
-cvCloneMatND( const CvMatND* src )
-{
- CvMatND* dst = 0;
- CV_FUNCNAME( "cvCloneMatND" );
-
- __BEGIN__;
-
- int i, *sizes;
-
- if( !CV_IS_MATND_HDR( src ))
- CV_ERROR( CV_StsBadArg, "Bad CvMatND header" );
-
- sizes = (int*)alloca( src->dims*sizeof(sizes[0]) );
-
- for( i = 0; i < src->dims; i++ )
- sizes[i] = src->dim[i].size;
-
- CV_CALL( dst = cvCreateMatNDHeader( src->dims, sizes, src->type ));
-
- if( src->data.ptr )
- {
- CV_CALL( cvCreateData( dst ));
- CV_CALL( cvCopy( src, dst ));
- }
-
- __END__;
-
- return dst;
-}
-
-
-static CvMatND*
-cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi )
-{
- CvMatND* result = 0;
-
- CV_FUNCNAME( "cvGetMatND" );
-
- __BEGIN__;
-
- if( coi )
- *coi = 0;
-
- if( !matnd || !arr )
- CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );
-
- if( CV_IS_MATND_HDR(arr))
- {
- if( !((CvMatND*)arr)->data.ptr )
- CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );
-
- result = (CvMatND*)arr;
- }
- else
- {
- CvMat stub, *mat = (CvMat*)arr;
-
- if( CV_IS_IMAGE_HDR( mat ))
- CV_CALL( mat = cvGetMat( mat, &stub, coi ));
-
- if( !CV_IS_MAT_HDR( mat ))
- CV_ERROR( CV_StsBadArg, "Unrecognized or unsupported array type" );
-
- if( !mat->data.ptr )
- CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );
-
- matnd->data.ptr = mat->data.ptr;
- matnd->refcount = 0;
- matnd->hdr_refcount = 0;
- matnd->type = mat->type;
- matnd->dims = 2;
- matnd->dim[0].size = mat->rows;
- matnd->dim[0].step = mat->step;
- matnd->dim[1].size = mat->cols;
- matnd->dim[1].step = CV_ELEM_SIZE(mat->type);
- result = matnd;
- }
-
- __END__;
-
- return result;
-}
-
-
-// returns number of dimensions to iterate.
-/*
-Checks whether <count> arrays have equal type, sizes (mask is optional array
-that needs to have the same size, but 8uC1 or 8sC1 type).
-Returns number of dimensions to iterate through:
-0 means that all arrays are continuous,
-1 means that all arrays are vectors of continuous arrays etc.
-and the size of largest common continuous part of the arrays
-*/
-CV_IMPL int
-cvInitNArrayIterator( int count, CvArr** arrs,
- const CvArr* mask, CvMatND* stubs,
- CvNArrayIterator* iterator, int flags )
-{
- int dims = -1;
-
- CV_FUNCNAME( "cvInitArrayOp" );
-
- __BEGIN__;
-
- int i, j, size, dim0 = -1;
- int64 step;
- CvMatND* hdr0 = 0;
-
- if( count < 1 || count > CV_MAX_ARR )
- CV_ERROR( CV_StsOutOfRange, "Incorrect number of arrays" );
-
- if( !arrs || !stubs )
- CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );
-
- if( !iterator )
- CV_ERROR( CV_StsNullPtr, "Iterator pointer is NULL" );
-
- for( i = 0; i <= count; i++ )
- {
- const CvArr* arr = i < count ? arrs[i] : mask;
- CvMatND* hdr;
-
- if( !arr )
- {
- if( i < count )
- CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );
- break;
- }
-
- if( CV_IS_MATND( arr ))
- hdr = (CvMatND*)arr;
- else
- {
- int coi = 0;
- CV_CALL( hdr = cvGetMatND( arr, stubs + i, &coi ));
- if( coi != 0 )
- CV_ERROR( CV_BadCOI, "COI set is not allowed here" );
- }
-
- iterator->hdr[i] = hdr;
-
- if( i > 0 )
- {
- if( hdr->dims != hdr0->dims )
- CV_ERROR( CV_StsUnmatchedSizes,
- "Number of dimensions is the same for all arrays" );
-
- if( i < count )
- {
- switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK))
- {
- case 0:
- if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))
- CV_ERROR( CV_StsUnmatchedFormats,
- "Data type is not the same for all arrays" );
- break;
- case CV_NO_DEPTH_CHECK:
- if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
- CV_ERROR( CV_StsUnmatchedFormats,
- "Number of channels is not the same for all arrays" );
- break;
- case CV_NO_CN_CHECK:
- if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
- CV_ERROR( CV_StsUnmatchedFormats,
- "Depth is not the same for all arrays" );
- break;
- }
- }
- else
- {
- if( !CV_IS_MASK_ARR( hdr ))
- CV_ERROR( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );
- }
-
- if( !(flags & CV_NO_SIZE_CHECK) )
- {
- for( j = 0; j < hdr->dims; j++ )
- if( hdr->dim[j].size != hdr0->dim[j].size )
- CV_ERROR( CV_StsUnmatchedSizes,
- "Dimension sizes are the same for all arrays" );
- }
- }
- else
- hdr0 = hdr;
-
- step = CV_ELEM_SIZE(hdr->type);
- for( j = hdr->dims - 1; j > dim0; j-- )
- {
- if( step != hdr->dim[j].step )
- break;
- step *= hdr->dim[j].size;
- }
-
- if( j == dim0 && step > INT_MAX )
- j++;
-
- if( j > dim0 )
- dim0 = j;
-
- iterator->hdr[i] = (CvMatND*)hdr;
- iterator->ptr[i] = (uchar*)hdr->data.ptr;
- }
-
- size = 1;
- for( j = hdr0->dims - 1; j > dim0; j-- )
- size *= hdr0->dim[j].size;
-
- dims = dim0 + 1;
- iterator->dims = dims;
- iterator->count = count;
- iterator->size = cvSize(size,1);
-
- for( i = 0; i < dims; i++ )
- iterator->stack[i] = hdr0->dim[i].size;
-
- __END__;
-
- return dims;
-}
-
-
-// returns zero value if iteration is finished, non-zero otherwise
-CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator )
-{
- assert( iterator != 0 );
- int i, dims, size = 0;
-
- for( dims = iterator->dims; dims > 0; dims-- )
- {
- for( i = 0; i < iterator->count; i++ )
- iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;
-
- if( --iterator->stack[dims-1] > 0 )
- break;
-
- size = iterator->hdr[0]->dim[dims-1].size;
-
- for( i = 0; i < iterator->count; i++ )
- iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;
-
- iterator->stack[dims-1] = size;
- }
-
- return dims > 0;
-}
-
-
-/****************************************************************************************\
-* CvSparseMat creation and basic operations *
-\****************************************************************************************/
-
-
-// Creates CvMatND and underlying data
-CV_IMPL CvSparseMat*
-cvCreateSparseMat( int dims, const int* sizes, int type )
-{
- CvSparseMat* arr = 0;
-
- CV_FUNCNAME( "cvCreateSparseMat" );
-
- __BEGIN__;
-
- type = CV_MAT_TYPE( type );
- int pix_size1 = CV_ELEM_SIZE1(type);
- int pix_size = pix_size1*CV_MAT_CN(type);
- int i, size;
- CvMemStorage* storage;
-
- if( pix_size == 0 )
- CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
-
- if( dims <= 0 || dims > CV_MAX_DIM_HEAP )
- CV_ERROR( CV_StsOutOfRange, "bad number of dimensions" );
-
- if( !sizes )
- CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
-
- for( i = 0; i < dims; i++ )
- {
- if( sizes[i] <= 0 )
- CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
- }
-
- CV_CALL( arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])));
-
- arr->type = CV_SPARSE_MAT_MAGIC_VAL | type;
- arr->dims = dims;
- arr->refcount = 0;
- arr->hdr_refcount = 1;
- memcpy( arr->size, sizes, dims*sizeof(sizes[0]));
-
- arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1);
- arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));
- size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));
-
- CV_CALL( storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK ));
- CV_CALL( arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ));
-
- arr->hashsize = CV_SPARSE_HASH_SIZE0;
- size = arr->hashsize*sizeof(arr->hashtable[0]);
-
- CV_CALL( arr->hashtable = (void**)cvAlloc( size ));
- memset( arr->hashtable, 0, size );
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseSparseMat( &arr );
-
- return arr;
-}
-
-
-// Creates CvMatND and underlying data
-CV_IMPL void
-cvReleaseSparseMat( CvSparseMat** array )
-{
- CV_FUNCNAME( "cvReleaseSparseMat" );
-
- __BEGIN__;
-
- if( !array )
- CV_ERROR_FROM_CODE( CV_HeaderIsNull );
-
- if( *array )
- {
- CvSparseMat* arr = *array;
-
- if( !CV_IS_SPARSE_MAT_HDR(arr) )
- CV_ERROR_FROM_CODE( CV_StsBadFlag );
-
- *array = 0;
-
- cvReleaseMemStorage( &arr->heap->storage );
- cvFree( &arr->hashtable );
- cvFree( &arr );
- }
-
- __END__;
-}
-
-
-// Creates CvMatND and underlying data
-CV_IMPL CvSparseMat*
-cvCloneSparseMat( const CvSparseMat* src )
-{
- CvSparseMat* dst = 0;
-
- CV_FUNCNAME( "cvCloneSparseMat" );
-
- __BEGIN__;
-
- if( !CV_IS_SPARSE_MAT_HDR(src) )
- CV_ERROR( CV_StsBadArg, "Invalid sparse array header" );
-
- CV_CALL( dst = cvCreateSparseMat( src->dims, src->size, src->type ));
- CV_CALL( cvCopy( src, dst ));
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseSparseMat( &dst );
-
- return dst;
-}
-
-
-CvSparseNode*
-cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator )
-{
- CvSparseNode* node = 0;
-
- CV_FUNCNAME( "cvInitSparseMatIterator" );
-
- __BEGIN__;
-
- int idx;
-
- if( !CV_IS_SPARSE_MAT( mat ))
- CV_ERROR( CV_StsBadArg, "Invalid sparse matrix header" );
-
- if( !iterator )
- CV_ERROR( CV_StsNullPtr, "NULL iterator pointer" );
-
- iterator->mat = (CvSparseMat*)mat;
- iterator->node = 0;
-
- for( idx = 0; idx < mat->hashsize; idx++ )
- if( mat->hashtable[idx] )
- {
- node = iterator->node = (CvSparseNode*)mat->hashtable[idx];
- break;
- }
-
- iterator->curidx = idx;
-
- __END__;
-
- return node;
-}
-
-#define ICV_SPARSE_MAT_HASH_MULTIPLIER 33
-
-static uchar*
-icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
- int create_node, unsigned* precalc_hashval )
-{
- uchar* ptr = 0;
-
- CV_FUNCNAME( "icvGetNodePtr" );
-
- __BEGIN__;
-
- int i, tabidx;
- unsigned hashval = 0;
- CvSparseNode *node;
- assert( CV_IS_SPARSE_MAT( mat ));
-
- if( !precalc_hashval )
- {
- for( i = 0; i < mat->dims; i++ )
- {
- int t = idx[i];
- if( (unsigned)t >= (unsigned)mat->size[i] )
- CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );
- hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
- }
- }
- else
- {
- hashval = *precalc_hashval;
- }
-
- tabidx = hashval & (mat->hashsize - 1);
- hashval &= INT_MAX;
-
- for( node = (CvSparseNode*)mat->hashtable[tabidx];
- node != 0; node = node->next )
- {
- if( node->hashval == hashval )
- {
- int* nodeidx = CV_NODE_IDX(mat,node);
- for( i = 0; i < mat->dims; i++ )
- if( idx[i] != nodeidx[i] )
- break;
- if( i == mat->dims )
- {
- ptr = (uchar*)CV_NODE_VAL(mat,node);
- break;
- }
- }
- }
-
- if( !ptr && create_node )
- {
- if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO )
- {
- void** newtable;
- int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);
- int newrawsize = newsize*sizeof(newtable[0]);
-
- CvSparseMatIterator iterator;
- assert( (newsize & (newsize - 1)) == 0 );
-
- // resize hash table
- CV_CALL( newtable = (void**)cvAlloc( newrawsize ));
- memset( newtable, 0, newrawsize );
-
- node = cvInitSparseMatIterator( mat, &iterator );
- while( node )
- {
- CvSparseNode* next = cvGetNextSparseNode( &iterator );
- int newidx = node->hashval & (newsize - 1);
- node->next = (CvSparseNode*)newtable[newidx];
- newtable[newidx] = node;
- node = next;
- }
-
- cvFree( &mat->hashtable );
- mat->hashtable = newtable;
- mat->hashsize = newsize;
- tabidx = hashval & (newsize - 1);
- }
-
- node = (CvSparseNode*)cvSetNew( mat->heap );
- node->hashval = hashval;
- node->next = (CvSparseNode*)mat->hashtable[tabidx];
- mat->hashtable[tabidx] = node;
- CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );
- ptr = (uchar*)CV_NODE_VAL(mat,node);
- if( create_node > 0 )
- CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(mat->type));
- }
-
- if( _type )
- *_type = CV_MAT_TYPE(mat->type);
-
- __END__;
-
- return ptr;
-}
-
-
-static void
-icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval )
-{
- CV_FUNCNAME( "icvDeleteNode" );
-
- __BEGIN__;
-
- int i, tabidx;
- unsigned hashval = 0;
- CvSparseNode *node, *prev = 0;
- assert( CV_IS_SPARSE_MAT( mat ));
-
- if( !precalc_hashval )
- {
- for( i = 0; i < mat->dims; i++ )
- {
- int t = idx[i];
- if( (unsigned)t >= (unsigned)mat->size[i] )
- CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );
- hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
- }
- }
- else
- {
- hashval = *precalc_hashval;
- }
-
- tabidx = hashval & (mat->hashsize - 1);
- hashval &= INT_MAX;
-
- for( node = (CvSparseNode*)mat->hashtable[tabidx];
- node != 0; prev = node, node = node->next )
- {
- if( node->hashval == hashval )
- {
- int* nodeidx = CV_NODE_IDX(mat,node);
- for( i = 0; i < mat->dims; i++ )
- if( idx[i] != nodeidx[i] )
- break;
- if( i == mat->dims )
- break;
- }
- }
-
- if( node )
- {
- if( prev )
- prev->next = node->next;
- else
- mat->hashtable[tabidx] = node->next;
- cvSetRemoveByPtr( mat->heap, node );
- }
-
- __END__;
-}
-
-
-
-/****************************************************************************************\
-* Common for multiple array types operations *
-\****************************************************************************************/
-
-// Allocates underlying array data
-CV_IMPL void
-cvCreateData( CvArr* arr )
-{
- CV_FUNCNAME( "cvCreateData" );
-
- __BEGIN__;
-
- if( CV_IS_MAT_HDR( arr ))
- {
- size_t step, total_size;
- CvMat* mat = (CvMat*)arr;
- step = mat->step;
-
- if( mat->data.ptr != 0 )
- CV_ERROR( CV_StsError, "Data is already allocated" );
-
- if( step == 0 )
- step = CV_ELEM_SIZE(mat->type)*mat->cols;
-
- total_size = step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
- CV_CALL( mat->refcount = (int*)cvAlloc( (size_t)total_size ));
- mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
- *mat->refcount = 1;
- }
- else if( CV_IS_IMAGE_HDR(arr))
- {
- IplImage* img = (IplImage*)arr;
-
- if( img->imageData != 0 )
- CV_ERROR( CV_StsError, "Data is already allocated" );
-
- if( !CvIPL.allocateData )
- {
- CV_CALL( img->imageData = img->imageDataOrigin =
- (char*)cvAlloc( (size_t)img->imageSize ));
- }
- else
- {
- int depth = img->depth;
- int width = img->width;
-
- if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 )
- {
- img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
- img->depth = IPL_DEPTH_8U;
- }
-
- CvIPL.allocateData( img, 0, 0 );
-
- img->width = width;
- img->depth = depth;
- }
- }
- else if( CV_IS_MATND_HDR( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
- int i;
- size_t total_size = CV_ELEM_SIZE(mat->type);
-
- if( mat->data.ptr != 0 )
- CV_ERROR( CV_StsError, "Data is already allocated" );
-
- if( CV_IS_MAT_CONT( mat->type ))
- {
- total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
- mat->dim[0].step : total_size);
- }
- else
- {
- for( i = mat->dims - 1; i >= 0; i-- )
- {
- size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;
-
- if( total_size < size )
- total_size = size;
- }
- }
-
- CV_CALL( mat->refcount = (int*)cvAlloc( total_size +
- sizeof(int) + CV_MALLOC_ALIGN ));
- mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
- *mat->refcount = 1;
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-}
-
-
-// Assigns external data to array
-CV_IMPL void
-cvSetData( CvArr* arr, void* data, int step )
-{
- CV_FUNCNAME( "cvSetData" );
-
- __BEGIN__;
-
- int pix_size, min_step;
-
- if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) )
- cvReleaseData( arr );
-
- if( CV_IS_MAT_HDR( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- int type = CV_MAT_TYPE(mat->type);
- pix_size = CV_ELEM_SIZE(type);
- min_step = mat->cols*pix_size & ((mat->rows <= 1) - 1);
-
- if( step != CV_AUTOSTEP )
- {
- if( step < min_step && data != 0 )
- CV_ERROR_FROM_CODE( CV_BadStep );
- mat->step = step & ((mat->rows <= 1) - 1);
- }
- else
- {
- mat->step = min_step;
- }
-
- mat->data.ptr = (uchar*)data;
- mat->type = CV_MAT_MAGIC_VAL | type |
- (mat->step==min_step ? CV_MAT_CONT_FLAG : 0);
- icvCheckHuge( mat );
- }
- else if( CV_IS_IMAGE_HDR( arr ))
- {
- IplImage* img = (IplImage*)arr;
-
- pix_size = ((img->depth & 255) >> 3)*img->nChannels;
- min_step = img->width*pix_size;
-
- if( step != CV_AUTOSTEP && img->height > 1 )
- {
- if( step < min_step && data != 0 )
- CV_ERROR_FROM_CODE( CV_BadStep );
- img->widthStep = step;
- }
- else
- {
- img->widthStep = min_step;
- }
-
- img->imageSize = img->widthStep * img->height;
- img->imageData = img->imageDataOrigin = (char*)data;
-
- if( (((int)(size_t)data | step) & 7) == 0 &&
- cvAlign(img->width * pix_size, 8) == step )
- {
- img->align = 8;
- }
- else
- {
- img->align = 4;
- }
- }
- else if( CV_IS_MATND_HDR( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
- int i;
- int64 cur_step;
-
- if( step != CV_AUTOSTEP )
- CV_ERROR( CV_BadStep,
- "For multidimensional array only CV_AUTOSTEP is allowed here" );
-
- mat->data.ptr = (uchar*)data;
- cur_step = CV_ELEM_SIZE(mat->type);
-
- for( i = mat->dims - 1; i >= 0; i-- )
- {
- if( cur_step > INT_MAX )
- CV_ERROR( CV_StsOutOfRange, "The array is too big" );
- mat->dim[i].step = (int)cur_step;
- cur_step *= mat->dim[i].size;
- }
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-}
-
-
-// Deallocates array's data
-CV_IMPL void
-cvReleaseData( CvArr* arr )
-{
- CV_FUNCNAME( "cvReleaseData" );
-
- __BEGIN__;
-
- if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr ))
- {
- CvMat* mat = (CvMat*)arr;
- cvDecRefData( mat );
- }
- else if( CV_IS_IMAGE_HDR( arr ))
- {
- IplImage* img = (IplImage*)arr;
-
- if( !CvIPL.deallocate )
- {
- char* ptr = img->imageDataOrigin;
- img->imageData = img->imageDataOrigin = 0;
- cvFree( &ptr );
- }
- else
- {
- CvIPL.deallocate( img, IPL_IMAGE_DATA );
- }
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-}
-
-
-// Retrieves essential information about image ROI or CvMat data
-CV_IMPL void
-cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size )
-{
- CV_FUNCNAME( "cvGetRawData" );
-
- __BEGIN__;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat *mat = (CvMat*)arr;
-
- if( step )
- *step = mat->step;
-
- if( data )
- *data = mat->data.ptr;
-
- if( roi_size )
- *roi_size = cvGetMatSize( mat );
- }
- else if( CV_IS_IMAGE( arr ))
- {
- IplImage* img = (IplImage*)arr;
-
- if( step )
- *step = img->widthStep;
-
- if( data )
- CV_CALL( *data = cvPtr2D( img, 0, 0 ));
-
- if( roi_size )
- {
- if( img->roi )
- {
- *roi_size = cvSize( img->roi->width, img->roi->height );
- }
- else
- {
- *roi_size = cvSize( img->width, img->height );
- }
- }
- }
- else if( CV_IS_MATND( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
-
- if( !CV_IS_MAT_CONT( mat->type ))
- CV_ERROR( CV_StsBadArg, "Only continuous nD arrays are supported here" );
-
- if( data )
- *data = mat->data.ptr;
-
- if( roi_size || step )
- {
- int i, size1 = mat->dim[0].size, size2 = 1;
-
- if( mat->dims > 2 )
- for( i = 1; i < mat->dims; i++ )
- size1 *= mat->dim[i].size;
- else
- size2 = mat->dim[1].size;
-
- if( roi_size )
- {
- roi_size->width = size2;
- roi_size->height = size1;
- }
-
- if( step )
- *step = size1 == 1 ? 0 : mat->dim[0].step;
- }
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-}
-
-
-CV_IMPL int
-cvGetElemType( const CvArr* arr )
-{
- int type = -1;
-
- CV_FUNCNAME( "cvGetElemType" );
-
- __BEGIN__;
-
- if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr))
- {
- type = CV_MAT_TYPE( ((CvMat*)arr)->type );
- }
- else if( CV_IS_IMAGE(arr))
- {
- IplImage* img = (IplImage*)arr;
- type = CV_MAKETYPE( icvIplToCvDepth(img->depth), img->nChannels );
- }
- else
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
-
- __END__;
-
- return type;
-}
-
-
-// Returns a number of array dimensions
-CV_IMPL int
-cvGetDims( const CvArr* arr, int* sizes )
-{
- int dims = -1;
- CV_FUNCNAME( "cvGetDims" );
-
- __BEGIN__;
-
- if( CV_IS_MAT_HDR( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- dims = 2;
- if( sizes )
- {
- sizes[0] = mat->rows;
- sizes[1] = mat->cols;
- }
- }
- else if( CV_IS_IMAGE( arr ))
- {
- IplImage* img = (IplImage*)arr;
- dims = 2;
-
- if( sizes )
- {
- sizes[0] = img->height;
- sizes[1] = img->width;
- }
- }
- else if( CV_IS_MATND_HDR( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
- dims = mat->dims;
-
- if( sizes )
- {
- int i;
- for( i = 0; i < dims; i++ )
- sizes[i] = mat->dim[i].size;
- }
- }
- else if( CV_IS_SPARSE_MAT_HDR( arr ))
- {
- CvSparseMat* mat = (CvSparseMat*)arr;
- dims = mat->dims;
-
- if( sizes )
- memcpy( sizes, mat->size, dims*sizeof(sizes[0]));
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-
- return dims;
-}
-
-
-// Returns the size of particular array dimension
-CV_IMPL int
-cvGetDimSize( const CvArr* arr, int index )
-{
- int size = -1;
- CV_FUNCNAME( "cvGetDimSize" );
-
- __BEGIN__;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat *mat = (CvMat*)arr;
-
- switch( index )
- {
- case 0:
- size = mat->rows;
- break;
- case 1:
- size = mat->cols;
- break;
- default:
- CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
- }
- }
- else if( CV_IS_IMAGE( arr ))
- {
- IplImage* img = (IplImage*)arr;
-
- switch( index )
- {
- case 0:
- size = !img->roi ? img->height : img->roi->height;
- break;
- case 1:
- size = !img->roi ? img->width : img->roi->width;
- break;
- default:
- CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
- }
- }
- else if( CV_IS_MATND_HDR( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
-
- if( (unsigned)index >= (unsigned)mat->dims )
- CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
-
- size = mat->dim[index].size;
- }
- else if( CV_IS_SPARSE_MAT_HDR( arr ))
- {
- CvSparseMat* mat = (CvSparseMat*)arr;
-
- if( (unsigned)index >= (unsigned)mat->dims )
- CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
-
- size = mat->size[index];
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-
- return size;
-}
-
-
-// Returns the size of CvMat or IplImage
-CV_IMPL CvSize
-cvGetSize( const CvArr* arr )
-{
- CvSize size = { 0, 0 };
-
- CV_FUNCNAME( "cvGetSize" );
-
- __BEGIN__;
-
- if( CV_IS_MAT_HDR( arr ))
- {
- CvMat *mat = (CvMat*)arr;
-
- size.width = mat->cols;
- size.height = mat->rows;
- }
- else if( CV_IS_IMAGE_HDR( arr ))
- {
- IplImage* img = (IplImage*)arr;
-
- if( img->roi )
- {
- size.width = img->roi->width;
- size.height = img->roi->height;
- }
- else
- {
- size.width = img->width;
- size.height = img->height;
- }
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "Array should be CvMat or IplImage" );
- }
-
- __END__;
-
- return size;
-}
-
-
-// Selects sub-array (no data is copied)
-CV_IMPL CvMat*
-cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
-{
- CvMat* res = 0;
-
- CV_FUNCNAME( "cvGetRect" );
-
- __BEGIN__;
-
- CvMat stub, *mat = (CvMat*)arr;
-
- if( !CV_IS_MAT( mat ))
- CV_CALL( mat = cvGetMat( mat, &stub ));
-
- if( !submat )
- CV_ERROR( CV_StsNullPtr, "" );
-
- if( (rect.x|rect.y|rect.width|rect.height) < 0 )
- CV_ERROR( CV_StsBadSize, "" );
-
- if( rect.x + rect.width > mat->cols ||
- rect.y + rect.height > mat->rows )
- CV_ERROR( CV_StsBadSize, "" );
-
- {
- /*
- int* refcount = mat->refcount;
-
- if( refcount )
- ++*refcount;
-
- cvDecRefData( submat );
- */
- submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
- rect.x*CV_ELEM_SIZE(mat->type);
- submat->step = mat->step & (rect.height > 1 ? -1 : 0);
- submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
- (submat->step == 0 ? CV_MAT_CONT_FLAG : 0);
- submat->rows = rect.height;
- submat->cols = rect.width;
- submat->refcount = 0;
- res = submat;
- }
-
- __END__;
-
- return res;
-}
-
-
-// Selects array's row span.
-CV_IMPL CvMat*
-cvGetRows( const CvArr* arr, CvMat* submat,
- int start_row, int end_row, int delta_row )
-{
- CvMat* res = 0;
-
- CV_FUNCNAME( "cvGetRows" );
-
- __BEGIN__;
-
- CvMat stub, *mat = (CvMat*)arr;
-
- if( !CV_IS_MAT( mat ))
- CV_CALL( mat = cvGetMat( mat, &stub ));
-
- if( !submat )
- CV_ERROR( CV_StsNullPtr, "" );
-
- if( (unsigned)start_row >= (unsigned)mat->rows ||
- (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 )
- CV_ERROR( CV_StsOutOfRange, "" );
-
- {
- /*
- int* refcount = mat->refcount;
-
- if( refcount )
- ++*refcount;
-
- cvDecRefData( submat );
- */
- if( delta_row == 1 )
- {
- submat->rows = end_row - start_row;
- submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
- }
- else
- {
- submat->rows = (end_row - start_row + delta_row - 1)/delta_row;
- submat->step = mat->step * delta_row;
- }
-
- submat->cols = mat->cols;
- submat->step &= submat->rows > 1 ? -1 : 0;
- submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
- submat->type = (mat->type | (submat->step == 0 ? CV_MAT_CONT_FLAG : 0)) &
- (delta_row != 1 ? ~CV_MAT_CONT_FLAG : -1);
- submat->refcount = 0;
- submat->hdr_refcount = 0;
- res = submat;
- }
-
- __END__;
-
- return res;
-}
-
-
-// Selects array's column span.
-CV_IMPL CvMat*
-cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col )
-{
- CvMat* res = 0;
-
- CV_FUNCNAME( "cvGetCols" );
-
- __BEGIN__;
-
- CvMat stub, *mat = (CvMat*)arr;
- int cols;
-
- if( !CV_IS_MAT( mat ))
- CV_CALL( mat = cvGetMat( mat, &stub ));
-
- if( !submat )
- CV_ERROR( CV_StsNullPtr, "" );
-
- cols = mat->cols;
- if( (unsigned)start_col >= (unsigned)cols ||
- (unsigned)end_col > (unsigned)cols )
- CV_ERROR( CV_StsOutOfRange, "" );
-
- {
- /*
- int* refcount = mat->refcount;
-
- if( refcount )
- ++*refcount;
-
- cvDecRefData( submat );
- */
- submat->rows = mat->rows;
- submat->cols = end_col - start_col;
- submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
- submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type);
- submat->type = mat->type & (submat->step && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
- submat->refcount = 0;
- submat->hdr_refcount = 0;
- res = submat;
- }
-
- __END__;
-
- return res;
-}
-
-
-// Selects array diagonal
-CV_IMPL CvMat*
-cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
-{
- CvMat* res = 0;
-
- CV_FUNCNAME( "cvGetDiag" );
-
- __BEGIN__;
-
- CvMat stub, *mat = (CvMat*)arr;
- int len, pix_size;
-
- if( !CV_IS_MAT( mat ))
- CV_CALL( mat = cvGetMat( mat, &stub ));
-
- if( !submat )
- CV_ERROR( CV_StsNullPtr, "" );
-
- pix_size = CV_ELEM_SIZE(mat->type);
-
- /*{
- int* refcount = mat->refcount;
-
- if( refcount )
- ++*refcount;
-
- cvDecRefData( submat );
- }*/
-
- if( diag >= 0 )
- {
- len = mat->cols - diag;
-
- if( len <= 0 )
- CV_ERROR( CV_StsOutOfRange, "" );
-
- len = CV_IMIN( len, mat->rows );
- submat->data.ptr = mat->data.ptr + diag*pix_size;
- }
- else
- {
- len = mat->rows + diag;
-
- if( len <= 0 )
- CV_ERROR( CV_StsOutOfRange, "" );
-
- len = CV_IMIN( len, mat->cols );
- submat->data.ptr = mat->data.ptr - diag*mat->step;
- }
-
- submat->rows = len;
- submat->cols = 1;
- submat->step = (mat->step + pix_size) & (submat->rows > 1 ? -1 : 0);
- submat->type = mat->type;
- if( submat->step )
- submat->type &= ~CV_MAT_CONT_FLAG;
- else
- submat->type |= CV_MAT_CONT_FLAG;
- submat->refcount = 0;
- submat->hdr_refcount = 0;
- res = submat;
-
- __END__;
-
- return res;
-}
-
-
-/****************************************************************************************\
-* Operations on CvScalar and accessing array elements *
-\****************************************************************************************/
-
-// Converts CvScalar to specified type
-CV_IMPL void
-cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 )
-{
- CV_FUNCNAME( "cvScalarToRawData" );
-
- type = CV_MAT_TYPE(type);
-
- __BEGIN__;
-
- int cn = CV_MAT_CN( type );
- int depth = type & CV_MAT_DEPTH_MASK;
-
- assert( scalar && data );
- if( (unsigned)(cn - 1) >= 4 )
- CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
-
- switch( depth )
- {
- case CV_8UC1:
- while( cn-- )
- {
- int t = cvRound( scalar->val[cn] );
- ((uchar*)data)[cn] = CV_CAST_8U(t);
- }
- break;
- case CV_8SC1:
- while( cn-- )
- {
- int t = cvRound( scalar->val[cn] );
- ((char*)data)[cn] = CV_CAST_8S(t);
- }
- break;
- case CV_16UC1:
- while( cn-- )
- {
- int t = cvRound( scalar->val[cn] );
- ((ushort*)data)[cn] = CV_CAST_16U(t);
- }
- break;
- case CV_16SC1:
- while( cn-- )
- {
- int t = cvRound( scalar->val[cn] );
- ((short*)data)[cn] = CV_CAST_16S(t);
- }
- break;
- case CV_32SC1:
- while( cn-- )
- ((int*)data)[cn] = cvRound( scalar->val[cn] );
- break;
- case CV_32FC1:
- while( cn-- )
- ((float*)data)[cn] = (float)(scalar->val[cn]);
- break;
- case CV_64FC1:
- while( cn-- )
- ((double*)data)[cn] = (double)(scalar->val[cn]);
- break;
- default:
- assert(0);
- CV_ERROR_FROM_CODE( CV_BadDepth );
- }
-
- if( extend_to_12 )
- {
- int pix_size = CV_ELEM_SIZE(type);
- int offset = CV_ELEM_SIZE1(depth)*12;
-
- do
- {
- offset -= pix_size;
- CV_MEMCPY_AUTO( (char*)data + offset, data, pix_size );
- }
- while( offset > pix_size );
- }
-
- __END__;
-}
-
-
-// Converts data of specified type to CvScalar
-CV_IMPL void
-cvRawDataToScalar( const void* data, int flags, CvScalar* scalar )
-{
- CV_FUNCNAME( "cvRawDataToScalar" );
-
- __BEGIN__;
-
- int cn = CV_MAT_CN( flags );
-
- assert( scalar && data );
-
- if( (unsigned)(cn - 1) >= 4 )
- CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
-
- memset( scalar->val, 0, sizeof(scalar->val));
-
- switch( CV_MAT_DEPTH( flags ))
- {
- case CV_8U:
- while( cn-- )
- scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]);
- break;
- case CV_8S:
- while( cn-- )
- scalar->val[cn] = CV_8TO32F(((char*)data)[cn]);
- break;
- case CV_16U:
- while( cn-- )
- scalar->val[cn] = ((ushort*)data)[cn];
- break;
- case CV_16S:
- while( cn-- )
- scalar->val[cn] = ((short*)data)[cn];
- break;
- case CV_32S:
- while( cn-- )
- scalar->val[cn] = ((int*)data)[cn];
- break;
- case CV_32F:
- while( cn-- )
- scalar->val[cn] = ((float*)data)[cn];
- break;
- case CV_64F:
- while( cn-- )
- scalar->val[cn] = ((double*)data)[cn];
- break;
- default:
- assert(0);
- CV_ERROR_FROM_CODE( CV_BadDepth );
- }
-
- __END__;
-}
-
-
-static double icvGetReal( const void* data, int type )
-{
- switch( type )
- {
- case CV_8U:
- return *(uchar*)data;
- case CV_8S:
- return *(char*)data;
- case CV_16U:
- return *(ushort*)data;
- case CV_16S:
- return *(short*)data;
- case CV_32S:
- return *(int*)data;
- case CV_32F:
- return *(float*)data;
- case CV_64F:
- return *(double*)data;
- }
-
- return 0;
-}
-
-
-static void icvSetReal( double value, const void* data, int type )
-{
- if( type < CV_32F )
- {
- int ivalue = cvRound(value);
- switch( type )
- {
- case CV_8U:
- *(uchar*)data = CV_CAST_8U(ivalue);
- break;
- case CV_8S:
- *(char*)data = CV_CAST_8S(ivalue);
- break;
- case CV_16U:
- *(ushort*)data = CV_CAST_16U(ivalue);
- break;
- case CV_16S:
- *(short*)data = CV_CAST_16S(ivalue);
- break;
- case CV_32S:
- *(int*)data = CV_CAST_32S(ivalue);
- break;
- }
- }
- else
- {
- switch( type )
- {
- case CV_32F:
- *(float*)data = (float)value;
- break;
- case CV_64F:
- *(double*)data = value;
- break;
- }
- }
-}
-
-
-// Returns pointer to specified element of array (linear index is used)
-CV_IMPL uchar*
-cvPtr1D( const CvArr* arr, int idx, int* _type )
-{
- uchar* ptr = 0;
-
- CV_FUNCNAME( "cvPtr1D" );
-
- __BEGIN__;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- int type = CV_MAT_TYPE(mat->type);
- int pix_size = CV_ELEM_SIZE(type);
-
- if( _type )
- *_type = type;
-
- // the first part is mul-free sufficient check
- // that the index is within the matrix
- if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
- (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- if( CV_IS_MAT_CONT(mat->type))
- {
- ptr = mat->data.ptr + (size_t)idx*pix_size;
- }
- else
- {
- int row, col;
- if( mat->cols == 1 )
- row = idx, col = 0;
- else
- row = idx/mat->cols, col = idx - row*mat->cols;
- ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size;
- }
- }
- else if( CV_IS_IMAGE_HDR( arr ))
- {
- IplImage* img = (IplImage*)arr;
- int width = !img->roi ? img->width : img->roi->width;
- int y = idx/width, x = idx - y*width;
-
- ptr = cvPtr2D( arr, y, x, _type );
- }
- else if( CV_IS_MATND( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
- int j, type = CV_MAT_TYPE(mat->type);
- size_t size = mat->dim[0].size;
-
- if( _type )
- *_type = type;
-
- for( j = 1; j < mat->dims; j++ )
- size *= mat->dim[j].size;
-
- if((unsigned)idx >= (unsigned)size )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- if( CV_IS_MAT_CONT(mat->type))
- {
- int pix_size = CV_ELEM_SIZE(type);
- ptr = mat->data.ptr + (size_t)idx*pix_size;
- }
- else
- {
- ptr = mat->data.ptr;
- for( j = mat->dims - 1; j >= 0; j-- )
- {
- int sz = mat->dim[j].size;
- if( sz )
- {
- int t = idx/sz;
- ptr += (idx - t*sz)*mat->dim[j].step;
- idx = t;
- }
- }
- }
- }
- else if( CV_IS_SPARSE_MAT( arr ))
- {
- CvSparseMat* m = (CvSparseMat*)arr;
- if( m->dims == 1 )
- ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 );
- else
- {
- int i, n = m->dims;
- int* _idx = (int*)cvStackAlloc(n*sizeof(_idx[0]));
-
- for( i = n - 1; i >= 0; i-- )
- {
- int t = idx / m->size[i];
- _idx[i] = idx - t*m->size[i];
- idx = t;
- }
- ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 );
- }
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-
- return ptr;
-}
-
-
-// Returns pointer to specified element of 2d array
-CV_IMPL uchar*
-cvPtr2D( const CvArr* arr, int y, int x, int* _type )
-{
- uchar* ptr = 0;
-
- CV_FUNCNAME( "cvPtr2D" );
-
- __BEGIN__;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat* mat = (CvMat*)arr;
- int type;
-
- if( (unsigned)y >= (unsigned)(mat->rows) ||
- (unsigned)x >= (unsigned)(mat->cols) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- type = CV_MAT_TYPE(mat->type);
- if( _type )
- *_type = type;
-
- ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
- }
- else if( CV_IS_IMAGE( arr ))
- {
- IplImage* img = (IplImage*)arr;
- int pix_size = (img->depth & 255) >> 3;
- int width, height;
- ptr = (uchar*)img->imageData;
-
- if( img->dataOrder == 0 )
- pix_size *= img->nChannels;
-
- if( img->roi )
- {
- width = img->roi->width;
- height = img->roi->height;
-
- ptr += img->roi->yOffset*img->widthStep +
- img->roi->xOffset*pix_size;
-
- if( img->dataOrder )
- {
- int coi = img->roi->coi;
- if( !coi )
- CV_ERROR( CV_BadCOI,
- "COI must be non-null in case of planar images" );
- ptr += (coi - 1)*img->imageSize;
- }
- }
- else
- {
- width = img->width;
- height = img->height;
- }
-
- if( (unsigned)y >= (unsigned)height ||
- (unsigned)x >= (unsigned)width )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr += y*img->widthStep + x*pix_size;
-
- if( _type )
- {
- int type = icvIplToCvDepth(img->depth);
- if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
- CV_ERROR( CV_StsUnsupportedFormat, "" );
-
- *_type = CV_MAKETYPE( type, img->nChannels );
- }
- }
- else if( CV_IS_MATND( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
-
- if( mat->dims != 2 ||
- (unsigned)y >= (unsigned)(mat->dim[0].size) ||
- (unsigned)x >= (unsigned)(mat->dim[1].size) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step;
- if( _type )
- *_type = CV_MAT_TYPE(mat->type);
- }
- else if( CV_IS_SPARSE_MAT( arr ))
- {
- int idx[] = { y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-
- return ptr;
-}
-
-
-// Returns pointer to specified element of 3d array
-CV_IMPL uchar*
-cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type )
-{
- uchar* ptr = 0;
-
- CV_FUNCNAME( "cvPtr3D" );
-
- __BEGIN__;
-
- if( CV_IS_MATND( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
-
- if( mat->dims != 3 ||
- (unsigned)z >= (unsigned)(mat->dim[0].size) ||
- (unsigned)y >= (unsigned)(mat->dim[1].size) ||
- (unsigned)x >= (unsigned)(mat->dim[2].size) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr = mat->data.ptr + (size_t)z*mat->dim[0].step +
- (size_t)y*mat->dim[1].step + x*mat->dim[2].step;
-
- if( _type )
- *_type = CV_MAT_TYPE(mat->type);
- }
- else if( CV_IS_SPARSE_MAT( arr ))
- {
- int idx[] = { z, y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
- }
- else
- {
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
- }
-
- __END__;
-
- return ptr;
-}
-
-
-// Returns pointer to specified element of n-d array
-CV_IMPL uchar*
-cvPtrND( const CvArr* arr, const int* idx, int* _type,
- int create_node, unsigned* precalc_hashval )
-{
- uchar* ptr = 0;
- CV_FUNCNAME( "cvPtrND" );
-
- __BEGIN__;
-
- if( !idx )
- CV_ERROR( CV_StsNullPtr, "NULL pointer to indices" );
-
- if( CV_IS_SPARSE_MAT( arr ))
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx,
- _type, create_node, precalc_hashval );
- else if( CV_IS_MATND( arr ))
- {
- CvMatND* mat = (CvMatND*)arr;
- int i;
- ptr = mat->data.ptr;
-
- for( i = 0; i < mat->dims; i++ )
- {
- if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
- ptr += (size_t)idx[i]*mat->dim[i].step;
- }
-
- if( _type )
- *_type = CV_MAT_TYPE(mat->type);
- }
- else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) )
- ptr = cvPtr2D( arr, idx[0], idx[1], _type );
- else
- CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
-
- __END__;
-
- return ptr;
-}
-
-
-// Returns specifed element of n-D array given linear index
-CV_IMPL CvScalar
-cvGet1D( const CvArr* arr, int idx )
-{
- CvScalar scalar = {{0,0,0,0}};
-
- CV_FUNCNAME( "cvGet1D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
- {
- CvMat* mat = (CvMat*)arr;
-
- type = CV_MAT_TYPE(mat->type);
- int pix_size = CV_ELEM_SIZE(type);
-
- // the first part is mul-free sufficient check
- // that the index is within the matrix
- if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
- (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr = mat->data.ptr + (size_t)idx*pix_size;
- }
- else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
- ptr = cvPtr1D( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
-
- cvRawDataToScalar( ptr, type, &scalar );
-
- __END__;
-
- return scalar;
-}
-
-
-// Returns specifed element of 2D array
-CV_IMPL CvScalar
-cvGet2D( const CvArr* arr, int y, int x )
-{
- CvScalar scalar = {{0,0,0,0}};
-
- CV_FUNCNAME( "cvGet2D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- if( (unsigned)y >= (unsigned)(mat->rows) ||
- (unsigned)x >= (unsigned)(mat->cols) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- type = CV_MAT_TYPE(mat->type);
- ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
- }
- else if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr2D( arr, y, x, &type );
- else
- {
- int idx[] = { y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
- }
-
- cvRawDataToScalar( ptr, type, &scalar );
-
- __END__;
-
- return scalar;
-}
-
-
-// Returns specifed element of 3D array
-CV_IMPL CvScalar
-cvGet3D( const CvArr* arr, int z, int y, int x )
-{
- CvScalar scalar = {{0,0,0,0}};
-
- /*CV_FUNCNAME( "cvGet3D" );*/
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr3D( arr, z, y, x, &type );
- else
- {
- int idx[] = { z, y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
- }
-
- cvRawDataToScalar( ptr, type, &scalar );
-
- __END__;
-
- return scalar;
-}
-
-
-// Returns specifed element of nD array
-CV_IMPL CvScalar
-cvGetND( const CvArr* arr, const int* idx )
-{
- CvScalar scalar = {{0,0,0,0}};
-
- /*CV_FUNCNAME( "cvGetND" );*/
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtrND( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
-
- cvRawDataToScalar( ptr, type, &scalar );
-
- __END__;
-
- return scalar;
-}
-
-
-// Returns specifed element of n-D array given linear index
-CV_IMPL double
-cvGetReal1D( const CvArr* arr, int idx )
-{
- double value = 0;
-
- CV_FUNCNAME( "cvGetReal1D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
- {
- CvMat* mat = (CvMat*)arr;
-
- type = CV_MAT_TYPE(mat->type);
- int pix_size = CV_ELEM_SIZE(type);
-
- // the first part is mul-free sufficient check
- // that the index is within the matrix
- if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
- (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr = mat->data.ptr + (size_t)idx*pix_size;
- }
- else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
- ptr = cvPtr1D( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
-
- if( ptr )
- {
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
-
- value = icvGetReal( ptr, type );
- }
-
- __END__;
-
- return value;
-}
-
-
-// Returns specifed element of 2D array
-CV_IMPL double
-cvGetReal2D( const CvArr* arr, int y, int x )
-{
- double value = 0;
-
- CV_FUNCNAME( "cvGetReal2D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- if( (unsigned)y >= (unsigned)(mat->rows) ||
- (unsigned)x >= (unsigned)(mat->cols) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- type = CV_MAT_TYPE(mat->type);
- ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
- }
- else if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr2D( arr, y, x, &type );
- else
- {
- int idx[] = { y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
- }
-
- if( ptr )
- {
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
-
- value = icvGetReal( ptr, type );
- }
-
- __END__;
-
- return value;
-}
-
-
-// Returns specifed element of 3D array
-CV_IMPL double
-cvGetReal3D( const CvArr* arr, int z, int y, int x )
-{
- double value = 0;
-
- CV_FUNCNAME( "cvGetReal3D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr3D( arr, z, y, x, &type );
- else
- {
- int idx[] = { z, y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
- }
-
- if( ptr )
- {
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
-
- value = icvGetReal( ptr, type );
- }
-
- __END__;
-
- return value;
-}
-
-
-// Returns specifed element of nD array
-CV_IMPL double
-cvGetRealND( const CvArr* arr, const int* idx )
-{
- double value = 0;
-
- CV_FUNCNAME( "cvGetRealND" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtrND( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
-
- if( ptr )
- {
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
-
- value = icvGetReal( ptr, type );
- }
-
- __END__;
-
- return value;
-}
-
-
-// Assigns new value to specifed element of nD array given linear index
-CV_IMPL void
-cvSet1D( CvArr* arr, int idx, CvScalar scalar )
-{
- CV_FUNCNAME( "cvSet1D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
- {
- CvMat* mat = (CvMat*)arr;
-
- type = CV_MAT_TYPE(mat->type);
- int pix_size = CV_ELEM_SIZE(type);
-
- // the first part is mul-free sufficient check
- // that the index is within the matrix
- if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
- (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr = mat->data.ptr + (size_t)idx*pix_size;
- }
- else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
- ptr = cvPtr1D( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
-
- cvScalarToRawData( &scalar, ptr, type );
-
- __END__;
-}
-
-
-// Assigns new value to specifed element of 2D array
-CV_IMPL void
-cvSet2D( CvArr* arr, int y, int x, CvScalar scalar )
-{
- CV_FUNCNAME( "cvSet2D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- if( (unsigned)y >= (unsigned)(mat->rows) ||
- (unsigned)x >= (unsigned)(mat->cols) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- type = CV_MAT_TYPE(mat->type);
- ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
- }
- else if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr2D( arr, y, x, &type );
- else
- {
- int idx[] = { y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
- }
- cvScalarToRawData( &scalar, ptr, type );
-
- __END__;
-}
-
-
-// Assigns new value to specifed element of 3D array
-CV_IMPL void
-cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar )
-{
- /*CV_FUNCNAME( "cvSet3D" );*/
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr3D( arr, z, y, x, &type );
- else
- {
- int idx[] = { z, y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
- }
- cvScalarToRawData( &scalar, ptr, type );
-
- __END__;
-}
-
-
-// Assigns new value to specifed element of nD array
-CV_IMPL void
-cvSetND( CvArr* arr, const int* idx, CvScalar scalar )
-{
- /*CV_FUNCNAME( "cvSetND" );*/
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtrND( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
- cvScalarToRawData( &scalar, ptr, type );
-
- __END__;
-}
-
-
-CV_IMPL void
-cvSetReal1D( CvArr* arr, int idx, double value )
-{
- CV_FUNCNAME( "cvSetReal1D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
- {
- CvMat* mat = (CvMat*)arr;
-
- type = CV_MAT_TYPE(mat->type);
- int pix_size = CV_ELEM_SIZE(type);
-
- // the first part is mul-free sufficient check
- // that the index is within the matrix
- if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
- (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- ptr = mat->data.ptr + (size_t)idx*pix_size;
- }
- else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
- ptr = cvPtr1D( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
-
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
-
- if( ptr )
- icvSetReal( value, ptr, type );
-
- __END__;
-}
-
-
-CV_IMPL void
-cvSetReal2D( CvArr* arr, int y, int x, double value )
-{
- CV_FUNCNAME( "cvSetReal2D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( CV_IS_MAT( arr ))
- {
- CvMat* mat = (CvMat*)arr;
-
- if( (unsigned)y >= (unsigned)(mat->rows) ||
- (unsigned)x >= (unsigned)(mat->cols) )
- CV_ERROR( CV_StsOutOfRange, "index is out of range" );
-
- type = CV_MAT_TYPE(mat->type);
- ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
- }
- else if( !CV_IS_SPARSE_MAT( arr ))
- {
- ptr = cvPtr2D( arr, y, x, &type );
- }
- else
- {
- int idx[] = { y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
- }
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
-
- if( ptr )
- icvSetReal( value, ptr, type );
-
- __END__;
-}
-
-
-CV_IMPL void
-cvSetReal3D( CvArr* arr, int z, int y, int x, double value )
-{
- CV_FUNCNAME( "cvSetReal3D" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtr3D( arr, z, y, x, &type );
- else
- {
- int idx[] = { z, y, x };
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
- }
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
-
- if( ptr )
- icvSetReal( value, ptr, type );
-
- __END__;
-}
-
-
-CV_IMPL void
-cvSetRealND( CvArr* arr, const int* idx, double value )
-{
- CV_FUNCNAME( "cvSetRealND" );
-
- __BEGIN__;
-
- int type = 0;
- uchar* ptr;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- ptr = cvPtrND( arr, idx, &type );
- else
- ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
-
- if( CV_MAT_CN( type ) > 1 )
- CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
-
- if( ptr )
- icvSetReal( value, ptr, type );
-
- __END__;
-}
-
-
-CV_IMPL void
-cvClearND( CvArr* arr, const int* idx )
-{
- /*CV_FUNCNAME( "cvClearND" );*/
-
- __BEGIN__;
-
- if( !CV_IS_SPARSE_MAT( arr ))
- {
- int type;
- uchar* ptr;
- ptr = cvPtrND( arr, idx, &type );
- if( ptr )
- CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(type) );
- }
- else
- {
- icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
- }
-
- __END__;
-}
-
-
-/****************************************************************************************\
-* Conversion to CvMat or IplImage *
-\****************************************************************************************/
-
-// convert array (CvMat or IplImage) to CvMat
-CV_IMPL CvMat*
-cvGetMat( const CvArr* array, CvMat* mat,
- int* pCOI, int allowND )
-{
- CvMat* result = 0;
- CvMat* src = (CvMat*)array;
- int coi = 0;
-
- CV_FUNCNAME( "cvGetMat" );
-
- __BEGIN__;
-
- if( !mat || !src )
- CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );
-
- if( CV_IS_MAT_HDR(src))
- {
- if( !src->data.ptr )
- CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );
-
- result = (CvMat*)src;
- }
- else if( CV_IS_IMAGE_HDR(src) )
- {
- const IplImage* img = (const IplImage*)src;
- int depth, order;
-
- if( img->imageData == 0 )
- CV_ERROR( CV_StsNullPtr, "The image has NULL data pointer" );
-
- depth = icvIplToCvDepth( img->depth );
- if( depth < 0 )
- CV_ERROR_FROM_CODE( CV_BadDepth );
-
- order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
-
- if( img->roi )
- {
- if( order == IPL_DATA_ORDER_PLANE )
- {
- int type = depth;
-
- if( img->roi->coi == 0 )
- CV_ERROR( CV_StsBadFlag,
- "Images with planar data layout should be used with COI selected" );
-
- CV_CALL( cvInitMatHeader( mat, img->roi->height,
- img->roi->width, type,
- img->imageData + (img->roi->coi-1)*img->imageSize +
- img->roi->yOffset*img->widthStep +
- img->roi->xOffset*CV_ELEM_SIZE(type),
- img->widthStep ));
- }
- else /* pixel order */
- {
- int type = CV_MAKETYPE( depth, img->nChannels );
- coi = img->roi->coi;
-
- if( img->nChannels > CV_CN_MAX )
- CV_ERROR( CV_BadNumChannels,
- "The image is interleaved and has over CV_CN_MAX channels" );
-
- CV_CALL( cvInitMatHeader( mat, img->roi->height, img->roi->width,
- type, img->imageData +
- img->roi->yOffset*img->widthStep +
- img->roi->xOffset*CV_ELEM_SIZE(type),
- img->widthStep ));
- }
- }
- else
- {
- int type = CV_MAKETYPE( depth, img->nChannels );
-
- if( order != IPL_DATA_ORDER_PIXEL )
- CV_ERROR( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
-
- CV_CALL( cvInitMatHeader( mat, img->height, img->width, type,
- img->imageData, img->widthStep ));
- }
-
- result = mat;
- }
- else if( allowND && CV_IS_MATND_HDR(src) )
- {
- CvMatND* matnd = (CvMatND*)src;
- int i;
- int size1 = matnd->dim[0].size, size2 = 1;
-
- if( !src->data.ptr )
- CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );
-
- if( !CV_IS_MAT_CONT( matnd->type ))
- CV_ERROR( CV_StsBadArg, "Only continuous nD arrays are supported here" );
-
- if( matnd->dims > 2 )
- for( i = 1; i < matnd->dims; i++ )
- size2 *= matnd->dim[i].size;
- else
- size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
-
- mat->refcount = 0;
- mat->hdr_refcount = 0;
- mat->data.ptr = matnd->data.ptr;
- mat->rows = size1;
- mat->cols = size2;
- mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
- mat->step = size2*CV_ELEM_SIZE(matnd->type);
- mat->step &= size1 > 1 ? -1 : 0;
-
- icvCheckHuge( mat );
- result = mat;
- }
- else
- {
- CV_ERROR( CV_StsBadFlag, "Unrecognized or unsupported array type" );
- }
-
- __END__;
-
- if( pCOI )
- *pCOI = coi;
-
- return result;
-}
-
-
-CV_IMPL CvArr*
-cvReshapeMatND( const CvArr* arr,
- int sizeof_header, CvArr* _header,
- int new_cn, int new_dims, int* new_sizes )
-{
- CvArr* result = 0;
- CV_FUNCNAME( "cvReshapeMatND" );
-
- __BEGIN__;
-
- int dims, coi = 0;
-
- if( !arr || !_header )
- CV_ERROR( CV_StsNullPtr, "NULL pointer to array or destination header" );
-
- if( new_cn == 0 && new_dims == 0 )
- CV_ERROR( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
-
- CV_CALL( dims = cvGetDims( arr ));
-
- if( new_dims == 0 )
- {
- new_sizes = 0;
- new_dims = dims;
- }
- else if( new_dims == 1 )
- {
- new_sizes = 0;
- }
- else
- {
- if( new_dims <= 0 || new_dims > CV_MAX_DIM )
- CV_ERROR( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
- if( !new_sizes )
- CV_ERROR( CV_StsNullPtr, "New dimension sizes are not specified" );
- }
-
- if( new_dims <= 2 )
- {
- CvMat* mat = (CvMat*)arr;
- CvMat* header = (CvMat*)_header;
- int* refcount = 0;
- int hdr_refcount = 0;
- int total_width, new_rows, cn;
-
- if( sizeof_header != sizeof(CvMat))
- CV_ERROR( CV_StsBadArg, "The header should be CvMat" );
-
- if( mat == header )
- {
- refcount = mat->refcount;
- hdr_refcount = mat->hdr_refcount;
- }
- else if( !CV_IS_MAT( mat ))
- CV_CALL( mat = cvGetMat( mat, header, &coi, 1 ));
-
- cn = CV_MAT_CN( mat->type );
- total_width = mat->cols * cn;
-
- if( new_cn == 0 )
- new_cn = cn;
-
- if( new_sizes )
- new_rows = new_sizes[0];
- else if( new_dims == 1 )
- new_rows = total_width*mat->rows/new_cn;
- else
- {
- new_rows = mat->rows;
- if( new_cn > total_width )
- new_rows = mat->rows * total_width / new_cn;
- }
-
- if( new_rows != mat->rows )
- {
- int total_size = total_width * mat->rows;
-
- if( !CV_IS_MAT_CONT( mat->type ))
- CV_ERROR( CV_BadStep,
- "The matrix is not continuous so the number of rows can not be changed" );
-
- total_width = total_size / new_rows;
-
- if( total_width * new_rows != total_size )
- CV_ERROR( CV_StsBadArg, "The total number of matrix elements "
- "is not divisible by the new number of rows" );
- }
-
- header->rows = new_rows;
- header->cols = total_width / new_cn;
-
- if( header->cols * new_cn != total_width ||
- new_sizes && header->cols != new_sizes[1] )
- CV_ERROR( CV_StsBadArg, "The total matrix width is not "
- "divisible by the new number of columns" );
-
- header->type = CV_MAKETYPE( mat->type & ~CV_MAT_CN_MASK, new_cn );
- header->step = header->cols * CV_ELEM_SIZE(mat->type);
- header->step &= new_rows > 1 ? -1 : 0;
- header->refcount = refcount;
- header->hdr_refcount = hdr_refcount;
- }
- else
- {
- CvMatND* header = (CvMatND*)_header;
-
- if( sizeof_header != sizeof(CvMatND))
- CV_ERROR( CV_StsBadSize, "The header should be CvMatND" );
-
- if( !new_sizes )
- {
- if( !CV_IS_MATND( arr ))
- CV_ERROR( CV_StsBadArg, "The source array must be CvMatND" );
-
- {
- CvMatND* mat = (CvMatND*)arr;
- assert( new_cn > 0 );
- int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
- int new_size = last_dim_size/new_cn;
-
- if( new_size*new_cn != last_dim_size )
- CV_ERROR( CV_StsBadArg,
- "The last dimension full size is not divisible by new number of channels");
-
- if( mat != header )
- {
- memcpy( header, mat, sizeof(*header));
- header->refcount = 0;
- header->hdr_refcount = 0;
- }
-
- header->dim[header->dims-1].size = new_size;
- header->type = CV_MAKETYPE( header->type & ~CV_MAT_CN_MASK, new_cn );
- }
- }
- else
- {
- CvMatND stub;
- CvMatND* mat = (CvMatND*)arr;
- int i, size1, size2;
- int step;
-
- if( new_cn != 0 )
- CV_ERROR( CV_StsBadArg,
- "Simultaneous change of shape and number of channels is not supported. "
- "Do it by 2 separate calls" );
-
- if( !CV_IS_MATND( mat ))
- {
- CV_CALL( cvGetMatND( mat, &stub, &coi ));
- mat = &stub;
- }
-
- if( CV_IS_MAT_CONT( mat->type ))
- CV_ERROR( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
-
- size1 = mat->dim[0].size;
- for( i = 1; i < dims; i++ )
- size1 *= mat->dim[i].size;
-
- size2 = 1;
- for( i = 0; i < new_dims; i++ )
- {
- if( new_sizes[i] <= 0 )
- CV_ERROR( CV_StsBadSize,
- "One of new dimension sizes is non-positive" );
- size2 *= new_sizes[i];
- }
-
- if( size1 != size2 )
- CV_ERROR( CV_StsBadSize,
- "Number of elements in the original and reshaped array is different" );
-
- if( header != mat )
- {
- header->refcount = 0;
- header->hdr_refcount = 0;
- }
-
- header->dims = new_dims;
- header->type = mat->type;
- header->data.ptr = mat->data.ptr;
- step = CV_ELEM_SIZE(header->type);
-
- for( i = new_dims - 1; i >= 0; i-- )
- {
- header->dim[i].size = new_sizes[i];
- header->dim[i].step = step;
- step *= new_sizes[i];
- }
- }
- }
-
- if( !coi )
- CV_ERROR( CV_BadCOI, "COI is not supported by this operation" );
-
- result = _header;
-
- __END__;
-
- return result;
-}
-
-
-CV_IMPL CvMat*
-cvReshape( const CvArr* array, CvMat* header,
- int new_cn, int new_rows )
-{
- CvMat* result = 0;
- CV_FUNCNAME( "cvReshape" );
-
- __BEGIN__;
-
- CvMat *mat = (CvMat*)array;
- int total_width, new_width;
-
- if( !header )
- CV_ERROR( CV_StsNullPtr, "" );
-
- if( !CV_IS_MAT( mat ))
- {
- int coi = 0;
- CV_CALL( mat = cvGetMat( mat, header, &coi, 1 ));
- if( coi )
- CV_ERROR( CV_BadCOI, "COI is not supported" );
- }
-
- if( new_cn == 0 )
- new_cn = CV_MAT_CN(mat->type);
- else if( (unsigned)(new_cn - 1) > 3 )
- CV_ERROR( CV_BadNumChannels, "" );
-
- if( mat != header )
- {
- int hdr_refcount = header->hdr_refcount;
- *header = *mat;
- header->refcount = 0;
- header->hdr_refcount = hdr_refcount;
- }
-
- total_width = mat->cols * CV_MAT_CN( mat->type );
-
- if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
- new_rows = mat->rows * total_width / new_cn;
-
- if( new_rows == 0 || new_rows == mat->rows )
- {
- header->rows = mat->rows;
- header->step = mat->step;
- }
- else
- {
- int total_size = total_width * mat->rows;
- if( !CV_IS_MAT_CONT( mat->type ))
- CV_ERROR( CV_BadStep,
- "The matrix is not continuous, thus its number of rows can not be changed" );
-
- if( (unsigned)new_rows > (unsigned)total_size )
- CV_ERROR( CV_StsOutOfRange, "Bad new number of rows" );
-
- total_width = total_size / new_rows;
-
- if( total_width * new_rows != total_size )
- CV_ERROR( CV_StsBadArg, "The total number of matrix elements "
- "is not divisible by the new number of rows" );
-
- header->rows = new_rows;
- header->step = total_width * CV_ELEM_SIZE1(mat->type);
- }
-
- new_width = total_width / new_cn;
-
- if( new_width * new_cn != total_width )
- CV_ERROR( CV_BadNumChannels,
- "The total width is not divisible by the new number of channels" );
-
- header->cols = new_width;
- header->type = CV_MAKETYPE( mat->type & ~CV_MAT_CN_MASK, new_cn );
-
- result = header;
-
- __END__;
-
- return result;
-}
-
-
-// convert array (CvMat or IplImage) to IplImage
-CV_IMPL IplImage*
-cvGetImage( const CvArr* array, IplImage* img )
-{
- IplImage* result = 0;
- const IplImage* src = (const IplImage*)array;
-
- CV_FUNCNAME( "cvGetImage" );
-
- __BEGIN__;
-
- int depth;
-
- if( !img )
- CV_ERROR_FROM_CODE( CV_StsNullPtr );
-
- if( !CV_IS_IMAGE_HDR(src) )
- {
- const CvMat* mat = (const CvMat*)src;
-
- if( !CV_IS_MAT_HDR(mat))
- CV_ERROR_FROM_CODE( CV_StsBadFlag );
-
- if( mat->data.ptr == 0 )
- CV_ERROR_FROM_CODE( CV_StsNullPtr );
-
- depth = cvCvToIplDepth(mat->type);
-
- cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
- depth, CV_MAT_CN(mat->type) );
- cvSetData( img, mat->data.ptr, mat->step );
-
- result = img;
- }
- else
- {
- result = (IplImage*)src;
- }
-
- __END__;
-
- return result;
-}
-
-
-/****************************************************************************************\
-* IplImage-specific functions *
-\****************************************************************************************/
-
-static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height )
-{
- IplROI *roi = 0;
-
- CV_FUNCNAME( "icvCreateROI" );
-
- __BEGIN__;
-
- if( !CvIPL.createROI )
- {
- CV_CALL( roi = (IplROI*)cvAlloc( sizeof(*roi)));
-
- roi->coi = coi;
- roi->xOffset = xOffset;
- roi->yOffset = yOffset;
- roi->width = width;
- roi->height = height;
- }
- else
- {
- roi = CvIPL.createROI( coi, xOffset, yOffset, width, height );
- }
-
- __END__;
-
- return roi;
-}
-
-static void
-icvGetColorModel( int nchannels, char** colorModel, char** channelSeq )
-{
- static char* tab[][2] =
- {
- {"GRAY", "GRAY"},
- {"",""},
- {"RGB","BGR"},
- {"RGB","BGRA"}
- };
-
- nchannels--;
- *colorModel = *channelSeq = "";
-
- if( (unsigned)nchannels <= 3 )
- {
- *colorModel = tab[nchannels][0];
- *channelSeq = tab[nchannels][1];
- }
-}
-
-
-// create IplImage header
-CV_IMPL IplImage *
-cvCreateImageHeader( CvSize size, int depth, int channels )
-{
- IplImage *img = 0;
-
- CV_FUNCNAME( "cvCreateImageHeader" );
-
- __BEGIN__;
-
- if( !CvIPL.createHeader )
- {
- CV_CALL( img = (IplImage *)cvAlloc( sizeof( *img )));
- CV_CALL( cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
- CV_DEFAULT_IMAGE_ROW_ALIGN ));
- }
- else
- {
- char *colorModel;
- char *channelSeq;
-
- icvGetColorModel( channels, &colorModel, &channelSeq );
-
- img = CvIPL.createHeader( channels, 0, depth, colorModel, channelSeq,
- IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
- CV_DEFAULT_IMAGE_ROW_ALIGN,
- size.width, size.height, 0, 0, 0, 0 );
- }
-
- __END__;
-
- if( cvGetErrStatus() < 0 && img )
- cvReleaseImageHeader( &img );
-
- return img;
-}
-
-
-// create IplImage header and allocate underlying data
-CV_IMPL IplImage *
-cvCreateImage( CvSize size, int depth, int channels )
-{
- IplImage *img = 0;
-
- CV_FUNCNAME( "cvCreateImage" );
-
- __BEGIN__;
-
- CV_CALL( img = cvCreateImageHeader( size, depth, channels ));
- assert( img );
- CV_CALL( cvCreateData( img ));
-
- __END__;
-
- if( cvGetErrStatus() < 0 )
- cvReleaseImage( &img );
-
- return img;
-}
-
-
-// initalize IplImage header, allocated by the user
-CV_IMPL IplImage*
-cvInitImageHeader( IplImage * image, CvSize size, int depth,
- int channels, int origin, int align )
-{
- IplImage* result = 0;
-
- CV_FUNCNAME( "cvInitImageHeader" );
-
- __BEGIN__;
-
- char *colorModel, *channelSeq;
-
- if( !image )
- CV_ERROR( CV_HeaderIsNull, "null pointer to header" );
-
- memset( image, 0, sizeof( *image ));
- image->nSize = sizeof( *image );
-
- CV_CALL( icvGetColorModel( channels, &colorModel, &channelSeq ));
- strncpy( image->colorModel, colorModel, 4 );
- strncpy( image->channelSeq, channelSeq, 4 );
-
- if( size.width < 0 || size.height < 0 )
- CV_ERROR( CV_BadROISize, "Bad input roi" );
-
- if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U &&
- depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U &&
- depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S &&
- depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) ||
- channels < 0 )
- CV_ERROR( CV_BadDepth, "Unsupported format" );
- if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL )
- CV_ERROR( CV_BadOrigin, "Bad input origin" );
-
- if( align != 4 && align != 8 )
- CV_ERROR( CV_BadAlign, "Bad input align" );
-
- image->width = size.width;
- image->height = size.height;
-
- if( image->roi )
- {
- image->roi->coi = 0;
- image->roi->xOffset = image->roi->yOffset = 0;
- image->roi->width = size.width;
- image->roi->height = size.height;
- }
-
- image->nChannels = MAX( channels, 1 );
- image->depth = depth;
- image->align = align;
- image->widthStep = (((image->width * image->nChannels *
- (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));
- image->origin = origin;
- image->imageSize = image->widthStep * image->height;
-
- result = image;
-
- __END__;
-
- return result;
-}
-
-
-CV_IMPL void
-cvReleaseImageHeader( IplImage** image )
-{
- CV_FUNCNAME( "cvReleaseImageHeader" );
-
- __BEGIN__;
-
- if( !image )
- CV_ERROR( CV_StsNullPtr, "" );
-
- if( *image )
- {
- IplImage* img = *image;
- *image = 0;
-
- if( !CvIPL.deallocate )
- {
- cvFree( &img->roi );
- cvFree( &img );
- }
- else
- {
- CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
- }
- }
- __END__;
-}
-
-
-CV_IMPL void
-cvReleaseImage( IplImage ** image )
-{
- CV_FUNCNAME( "cvReleaseImage" );
-
- __BEGIN__
-
- if( !image )
- CV_ERROR( CV_StsNullPtr, "" );
-
- if( *image )
- {
- IplImage* img = *image;
- *image = 0;
-
- cvReleaseData( img );
- cvReleaseImageHeader( &img );
- }
-
- __END__;
-}
-
-
-CV_IMPL void
-cvSetImageROI( IplImage* image, CvRect rect )
-{
- CV_FUNCNAME( "cvSetImageROI" );
-
- __BEGIN__;
-
- if( !image )
- CV_ERROR( CV_HeaderIsNull, "" );
-
- if( rect.x > image->width || rect.y > image->height )
- CV_ERROR( CV_BadROISize, "" );
-
- if( rect.x + rect.width < 0 || rect.y + rect.height < 0 )
- CV_ERROR( CV_BadROISize, "" );
-
- if( rect.x < 0 )
- {
- rect.width += rect.x;
- rect.x = 0;
- }
-
- if( rect.y < 0 )
- {
- rect.height += rect.y;
- rect.y = 0;
- }
-
- if( rect.x + rect.width > image->width )
- rect.width = image->width - rect.x;
-
- if( rect.y + rect.height > image->height )
- rect.height = image->height - rect.y;
-
- if( image->roi )
- {
- image->roi->xOffset = rect.x;
- image->roi->yOffset = rect.y;
- image->roi->width = rect.width;
- image->roi->height = rect.height;
- }
- else
- {
- CV_CALL( image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height ));
- }
-
- __END__;
-}
-
-
-CV_IMPL void
-cvResetImageROI( IplImage* image )
-{
- CV_FUNCNAME( "cvResetImageROI" );
-
- __BEGIN__;
-
- if( !image )
- CV_ERROR( CV_HeaderIsNull, "" );
-
- if( image->roi )
- {
- if( !CvIPL.deallocate )
- {
- cvFree( &image->roi );
- }
- else
- {
- CvIPL.deallocate( image, IPL_IMAGE_ROI );
- image->roi = 0;
- }
- }
-
- __END__;
-}
-
-
-CV_IMPL CvRect
-cvGetImageROI( const IplImage* img )
-{
- CvRect rect = { 0, 0, 0, 0 };
-
- CV_FUNCNAME( "cvGetImageROI" );
-
- __BEGIN__;
-
- if( !img )
- CV_ERROR( CV_StsNullPtr, "Null pointer to image" );
-
- if( img->roi )
- rect = cvRect( img->roi->xOffset, img->roi->yOffset,
- img->roi->width, img->roi->height );
- else
- rect = cvRect( 0, 0, img->width, img->height );
-
- __END__;
-
- return rect;
-}
-
-
-CV_IMPL void
-cvSetImageCOI( IplImage* image, int coi )
-{
- CV_FUNCNAME( "cvSetImageCOI" );
-
- __BEGIN__;
-
- if( !image )
- CV_ERROR( CV_HeaderIsNull, "" );
-
- if( (unsigned)coi > (unsigned)(image->nChannels) )
- CV_ERROR( CV_BadCOI, "" );
-
- if( image->roi || coi != 0 )
- {
- if( image->roi )
- {
- image->roi->coi = coi;
- }
- else
- {
- CV_CALL( image->roi = icvCreateROI( coi, 0, 0, image->width, image->height ));
- }
- }
-
- __END__;
-}
-
-
-CV_IMPL int
-cvGetImageCOI( const IplImage* image )
-{
- int coi = -1;
- CV_FUNCNAME( "cvGetImageCOI" );
-
- __BEGIN__;
-
- if( !image )
- CV_ERROR( CV_HeaderIsNull, "" );
-
- coi = image->roi ? image->roi->coi : 0;
-
- __END__;
-
- return coi;
-}
-
-
-CV_IMPL IplImage*
-cvCloneImage( const IplImage* src )
-{
- IplImage* dst = 0;
- CV_FUNCNAME( "cvCloneImage" );
-
- __BEGIN__;
-
- if( !CV_IS_IMAGE_HDR( src ))
- CV_ERROR( CV_StsBadArg, "Bad image header" );
-
- if( !CvIPL.cloneImage )
- {
- CV_CALL( dst = (IplImage*)cvAlloc( sizeof(*dst)));
-
- memcpy( dst, src, sizeof(*src));
- dst->imageData = dst->imageDataOrigin = 0;
- dst->roi = 0;
-
- if( src->roi )
- {
- dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset,
- src->roi->yOffset, src->roi->width, src->roi->height );
- }
-
- if( src->imageData )
- {
- int size = src->imageSize;
- cvCreateData( dst );
- memcpy( dst->imageData, src->imageData, size );
- }
- }
- else
- {
- dst = CvIPL.cloneImage( src );
- }
-
- __END__;
-
- return dst;
-}
-
-
-/****************************************************************************************\
-* Additional operations on CvTermCriteria *
-\****************************************************************************************/
-
-CV_IMPL CvTermCriteria
-cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
- int default_max_iters )
-{
- CV_FUNCNAME( "cvCheckTermCriteria" );
-
- CvTermCriteria crit;
-
- crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
- crit.max_iter = default_max_iters;
- crit.epsilon = (float)default_eps;
-
- __BEGIN__;
-
- if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 )
- CV_ERROR( CV_StsBadArg,
- "Unknown type of term criteria" );
-
- if( (criteria.type & CV_TERMCRIT_ITER) != 0 )
- {
- if( criteria.max_iter <= 0 )
- CV_ERROR( CV_StsBadArg,
- "Iterations flag is set and maximum number of iterations is <= 0" );
- crit.max_iter = criteria.max_iter;
- }
-
- if( (criteria.type & CV_TERMCRIT_EPS) != 0 )
- {
- if( criteria.epsilon < 0 )
- CV_ERROR( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" );
-
- crit.epsilon = criteria.epsilon;
- }
-
- if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 )
- CV_ERROR( CV_StsBadArg,
- "Neither accuracy nor maximum iterations "
- "number flags are set in criteria type" );
-
- __END__;
-
- crit.epsilon = (float)MAX( 0, crit.epsilon );
- crit.max_iter = MAX( 1, crit.max_iter );
-
- return crit;
-}
-
-
-/* End of file. */