1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 /* ////////////////////////////////////////////////////////////////////
44 // CvMat, CvMatND, CvSparceMat and IplImage support functions
45 // (creation, deletion, copying, retrieving and setting elements etc.)
53 Cv_iplCreateImageHeader createHeader;
54 Cv_iplAllocateImageData allocateData;
55 Cv_iplDeallocate deallocate;
56 Cv_iplCreateROI createROI;
57 Cv_iplCloneImage cloneImage;
61 // Makes the library use native IPL image allocators
63 cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader,
64 Cv_iplAllocateImageData allocateData,
65 Cv_iplDeallocate deallocate,
66 Cv_iplCreateROI createROI,
67 Cv_iplCloneImage cloneImage )
69 CV_FUNCNAME( "cvSetIPLAllocators" );
73 if( !createHeader || !allocateData || !deallocate || !createROI || !cloneImage )
75 if( createHeader || allocateData || deallocate || createROI || cloneImage )
76 CV_ERROR( CV_StsBadArg, "Either all the pointers should be null or "
77 "they all should be non-null" );
80 CvIPL.createHeader = createHeader;
81 CvIPL.allocateData = allocateData;
82 CvIPL.deallocate = deallocate;
83 CvIPL.createROI = createROI;
84 CvIPL.cloneImage = cloneImage;
90 /****************************************************************************************\
91 * CvMat creation and basic operations *
92 \****************************************************************************************/
94 // Creates CvMat and underlying data
96 cvCreateMat( int height, int width, int type )
100 CV_FUNCNAME( "cvCreateMat" );
104 CV_CALL( arr = cvCreateMatHeader( height, width, type ));
105 CV_CALL( cvCreateData( arr ));
109 if( cvGetErrStatus() < 0 )
110 cvReleaseMat( &arr );
116 static void icvCheckHuge( CvMat* arr )
118 if( (int64)arr->step*arr->rows > INT_MAX )
119 arr->type &= ~CV_MAT_CONT_FLAG;
122 // Creates CvMat header only
124 cvCreateMatHeader( int rows, int cols, int type )
128 CV_FUNCNAME( "cvCreateMatHeader" );
133 type = CV_MAT_TYPE(type);
135 if( rows <= 0 || cols <= 0 )
136 CV_ERROR( CV_StsBadSize, "Non-positive width or height" );
138 min_step = icvPixSize[type]*cols;
140 CV_ERROR( CV_StsUnsupportedFormat, "Invalid matrix type" );
142 CV_CALL( arr = (CvMat*)cvAlloc( sizeof(*arr)));
144 arr->step = rows == 1 ? 0 : cvAlign(min_step, CV_DEFAULT_MAT_ROW_ALIGN);
145 arr->type = CV_MAT_MAGIC_VAL | type |
146 (arr->step == 0 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
156 if( cvGetErrStatus() < 0 )
157 cvReleaseMat( &arr );
163 // Initializes CvMat header, allocated by the user
165 cvInitMatHeader( CvMat* arr, int rows, int cols,
166 int type, void* data, int step )
168 CV_FUNCNAME( "cvInitMatHeader" );
172 int mask, pix_size, min_step;
175 CV_ERROR_FROM_CODE( CV_StsNullPtr );
177 if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
178 CV_ERROR_FROM_CODE( CV_BadNumChannels );
180 if( rows <= 0 || cols <= 0 )
181 CV_ERROR( CV_StsBadSize, "Non-positive cols or rows" );
183 type = CV_MAT_TYPE( type );
184 arr->type = type | CV_MAT_MAGIC_VAL;
187 arr->data.ptr = (uchar*)data;
190 mask = (arr->rows <= 1) - 1;
191 pix_size = icvPixSize[type];
192 min_step = arr->cols*pix_size & mask;
194 if( step != CV_AUTOSTEP && step != 0 )
196 if( step < min_step )
197 CV_ERROR_FROM_CODE( CV_BadStep );
198 arr->step = step & mask;
202 arr->step = min_step;
205 arr->type = CV_MAT_MAGIC_VAL | type |
206 (arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
216 // Deallocates the CvMat structure and underlying data
218 cvReleaseMat( CvMat** array )
220 CV_FUNCNAME( "cvReleaseMat" );
225 CV_ERROR_FROM_CODE( CV_HeaderIsNull );
231 if( !CV_IS_MAT_HDR(arr) && !CV_IS_MATND_HDR(arr) )
232 CV_ERROR_FROM_CODE( CV_StsBadFlag );
237 cvFree( (void**)&arr );
244 // Creates a copy of matrix
246 cvCloneMat( const CvMat* src )
249 CV_FUNCNAME( "cvCloneMat" );
253 if( !CV_IS_MAT_HDR( src ))
254 CV_ERROR( CV_StsBadArg, "Bad CvMat header" );
256 CV_CALL( dst = cvCreateMatHeader( src->rows, src->cols, src->type ));
260 CV_CALL( cvCreateData( dst ));
261 CV_CALL( cvCopy( src, dst ));
270 /****************************************************************************************\
271 * CvMatND creation and basic operations *
272 \****************************************************************************************/
275 cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
276 int type, void* data )
280 CV_FUNCNAME( "cvInitMatNDHeader" );
284 type = CV_MAT_TYPE(type);
286 int64 step = icvPixSize[type];
289 CV_ERROR( CV_StsNullPtr, "NULL matrix header pointer" );
292 CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
295 CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
297 if( dims <= 0 || dims > CV_MAX_DIM )
298 CV_ERROR( CV_StsOutOfRange,
299 "non-positive or too large number of dimensions" );
301 for( i = dims - 1; i >= 0; i-- )
304 CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
305 mat->dim[i].size = sizes[i];
307 CV_ERROR( CV_StsOutOfRange, "The array is too big" );
308 mat->dim[i].step = (int)step;
312 mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
314 mat->data.ptr = (uchar*)data;
320 if( cvGetErrStatus() < 0 && mat )
330 // Creates CvMatND and underlying data
332 cvCreateMatND( int dims, const int* sizes, int type )
336 CV_FUNCNAME( "cvCreateMatND" );
340 CV_CALL( arr = cvCreateMatNDHeader( dims, sizes, type ));
341 CV_CALL( cvCreateData( arr ));
345 if( cvGetErrStatus() < 0 )
346 cvReleaseMatND( &arr );
352 // Creates CvMatND header only
354 cvCreateMatNDHeader( int dims, const int* sizes, int type )
358 CV_FUNCNAME( "cvCreateMatNDHeader" );
362 if( dims <= 0 || dims > CV_MAX_DIM )
363 CV_ERROR( CV_StsOutOfRange,
364 "non-positive or too large number of dimensions" );
366 CV_CALL( arr = (CvMatND*)cvAlloc( sizeof(*arr) ));
368 CV_CALL( cvInitMatNDHeader( arr, dims, sizes, type, 0 ));
372 if( cvGetErrStatus() < 0 )
373 cvReleaseMatND( &arr );
379 // Creates a copy of nD array
381 cvCloneMatND( const CvMatND* src )
384 CV_FUNCNAME( "cvCloneMatND" );
390 if( !CV_IS_MATND_HDR( src ))
391 CV_ERROR( CV_StsBadArg, "Bad CvMatND header" );
393 sizes = (int*)alloca( src->dims*sizeof(sizes[0]) );
395 for( i = 0; i < src->dims; i++ )
396 sizes[i] = src->dim[i].size;
398 CV_CALL( dst = cvCreateMatNDHeader( src->dims, sizes, src->type ));
402 CV_CALL( cvCreateData( dst ));
403 CV_CALL( cvCopy( src, dst ));
413 cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi )
417 CV_FUNCNAME( "cvGetMat" );
425 CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );
427 if( CV_IS_MATND_HDR(arr))
429 if( !((CvMatND*)arr)->data.ptr )
430 CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );
432 result = (CvMatND*)arr;
436 CvMat stub, *mat = (CvMat*)arr;
438 if( CV_IS_IMAGE_HDR( mat ))
439 CV_CALL( mat = cvGetMat( mat, &stub, coi ));
441 if( !CV_IS_MAT_HDR( mat ))
442 CV_ERROR( CV_StsBadArg, "Unrecognized or unsupported array type" );
445 CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );
447 matnd->data.ptr = mat->data.ptr;
449 matnd->type = mat->type;
451 matnd->dim[0].size = mat->rows;
452 matnd->dim[0].step = mat->step;
453 matnd->dim[1].size = mat->cols;
454 matnd->dim[1].step = icvPixSize[CV_MAT_TYPE(mat->type)];
464 // returns number of dimensions to iterate.
466 Checks whether <count> arrays have equal type, sizes (mask is optional array
467 that needs to have the same size, but 8uC1 or 8sC1 type).
468 Returns number of dimensions to iterate through:
469 0 means that all arrays are continuous,
470 1 means that all arrays are vectors of continuous arrays etc.
471 and the size of largest common continuous part of the arrays
474 cvInitNArrayIterator( int count, CvArr** arrs,
475 const CvArr* mask, CvMatND* stubs,
476 CvNArrayIterator* iterator, int flags )
480 CV_FUNCNAME( "cvInitArrayOp" );
484 int i, j, size, dim0 = -1;
488 if( count < 1 || count > CV_MAX_ARR )
489 CV_ERROR( CV_StsOutOfRange, "Incorrect number of arrays" );
491 if( !arrs || !stubs )
492 CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );
495 CV_ERROR( CV_StsNullPtr, "Iterator pointer is NULL" );
497 for( i = 0; i <= count; i++ )
499 const CvArr* arr = i < count ? arrs[i] : mask;
505 CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );
509 if( CV_IS_MATND( arr ))
514 CV_CALL( hdr = cvGetMatND( arr, stubs + i, &coi ));
516 CV_ERROR( CV_BadCOI, "COI set is not allowed here" );
519 iterator->hdr[i] = hdr;
523 if( hdr->dims != hdr0->dims )
524 CV_ERROR( CV_StsUnmatchedSizes,
525 "Number of dimensions is the same for all arrays" );
529 switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK))
532 if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))
533 CV_ERROR( CV_StsUnmatchedFormats,
534 "Data type is not the same for all arrays" );
536 case CV_NO_DEPTH_CHECK:
537 if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
538 CV_ERROR( CV_StsUnmatchedFormats,
539 "Number of channels is not the same for all arrays" );
542 if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
543 CV_ERROR( CV_StsUnmatchedFormats,
544 "Depth is not the same for all arrays" );
550 if( !CV_IS_MASK_ARR( hdr ))
551 CV_ERROR( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );
554 if( !(flags & CV_NO_SIZE_CHECK) )
556 for( j = 0; j < hdr->dims; j++ )
557 if( hdr->dim[j].size != hdr0->dim[j].size )
558 CV_ERROR( CV_StsUnmatchedSizes,
559 "Dimension sizes are the same for all arrays" );
565 step = icvPixSize[CV_MAT_TYPE(hdr->type)];
566 for( j = hdr->dims - 1; j > dim0; j-- )
568 if( step != hdr->dim[j].step )
570 step *= hdr->dim[j].size;
573 if( j == dim0 && step > INT_MAX )
579 iterator->hdr[i] = (CvMatND*)hdr;
580 iterator->ptr[i] = (uchar*)hdr->data.ptr;
584 for( j = hdr0->dims - 1; j > dim0; j-- )
585 size *= hdr0->dim[j].size;
588 iterator->dims = dims;
589 iterator->count = count;
590 iterator->size = cvSize(size,1);
592 for( i = 0; i < dims; i++ )
593 iterator->stack[i] = hdr0->dim[i].size;
601 // returns zero value if iteration is finished, non-zero otherwise
602 CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator )
604 assert( iterator != 0 );
605 int i, dims, size = 0;
607 for( dims = iterator->dims; dims > 0; dims-- )
609 for( i = 0; i < iterator->count; i++ )
610 iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;
612 if( --iterator->stack[dims-1] > 0 )
615 size = iterator->hdr[0]->dim[dims-1].size;
617 for( i = 0; i < iterator->count; i++ )
618 iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;
620 iterator->stack[dims-1] = size;
627 /****************************************************************************************\
628 * CvSparseMat creation and basic operations *
629 \****************************************************************************************/
632 // Creates CvMatND and underlying data
634 cvCreateSparseMat( int dims, const int* sizes, int type )
636 CvSparseMat* arr = 0;
638 CV_FUNCNAME( "cvCreateSparseMat" );
642 type = CV_MAT_TYPE( type );
643 int pix_size = icvPixSize[type];
644 int pix_size1 = icvPixSize[type & -CV_MAT_CN_MASK];
646 CvMemStorage* storage;
649 CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
651 if( dims <= 0 || dims > CV_MAX_DIM_HEAP )
652 CV_ERROR( CV_StsOutOfRange, "bad number of dimensions" );
655 CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
657 for( i = 0; i < dims; i++ )
660 CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
663 CV_CALL( arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])));
665 arr->type = CV_SPARSE_MAT_MAGIC_VAL | type;
668 memcpy( arr->size, sizes, dims*sizeof(sizes[0]));
670 arr->valoffset = (int)cvAlign(sizeof(void*) + sizeof(int), pix_size1 );
671 arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));
672 size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));
674 CV_CALL( storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK ));
675 CV_CALL( arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ));
677 arr->hashsize = CV_SPARSE_HASH_SIZE0;
678 size = arr->hashsize*sizeof(arr->hashtable[0]);
680 CV_CALL( arr->hashtable = (void**)cvAlloc( size ));
681 memset( arr->hashtable, 0, size );
685 if( cvGetErrStatus() < 0 )
686 cvReleaseSparseMat( &arr );
692 // Creates CvMatND and underlying data
694 cvReleaseSparseMat( CvSparseMat** array )
696 CV_FUNCNAME( "cvReleaseSparseMat" );
701 CV_ERROR_FROM_CODE( CV_HeaderIsNull );
705 CvSparseMat* arr = *array;
707 if( !CV_IS_SPARSE_MAT_HDR(arr) )
708 CV_ERROR_FROM_CODE( CV_StsBadFlag );
712 cvReleaseMemStorage( &arr->heap->storage );
713 cvFree( (void**)(&arr->hashtable) );
714 cvFree( (void**)&arr );
721 // Creates CvMatND and underlying data
723 cvCloneSparseMat( const CvSparseMat* src )
725 CvSparseMat* dst = 0;
727 CV_FUNCNAME( "cvCloneSparseMat" );
731 if( !CV_IS_SPARSE_MAT_HDR(src) )
732 CV_ERROR( CV_StsBadArg, "Invalid sparse array header" );
734 CV_CALL( dst = cvCreateSparseMat( src->dims, src->size, src->type ));
735 CV_CALL( cvCopy( src, dst ));
739 if( cvGetErrStatus() < 0 )
740 cvReleaseSparseMat( &dst );
747 cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator )
749 CvSparseNode* node = 0;
751 CV_FUNCNAME( "cvInitSparseMatIterator" );
757 if( !CV_IS_SPARSE_MAT( mat ))
758 CV_ERROR( CV_StsBadArg, "Invalid sparse matrix header" );
761 CV_ERROR( CV_StsNullPtr, "NULL iterator pointer" );
763 iterator->mat = (CvSparseMat*)mat;
766 for( idx = 0; idx < mat->hashsize; idx++ )
767 if( mat->hashtable[idx] )
769 node = iterator->node = (CvSparseNode*)mat->hashtable[idx];
773 iterator->curidx = idx;
780 #define ICV_SPARSE_MAT_HASH_MULTIPLIER 33
783 icvGetNodePtr( CvSparseMat* mat, int* idx, int* _type,
784 int create_node, unsigned* precalc_hashval )
788 CV_FUNCNAME( "icvGetNodePtr" );
793 unsigned hashval = 0;
795 assert( CV_IS_SPARSE_MAT( mat ));
797 if( !precalc_hashval )
799 for( i = 0; i < mat->dims; i++ )
802 if( (unsigned)t >= (unsigned)mat->size[i] )
803 CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );
804 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
809 hashval = *precalc_hashval;
812 tabidx = hashval & (mat->hashsize - 1);
815 for( node = (CvSparseNode*)mat->hashtable[tabidx];
816 node != 0; node = node->next )
818 if( node->hashval == hashval )
820 int* nodeidx = CV_NODE_IDX(mat,node);
821 for( i = 0; i < mat->dims; i++ )
822 if( idx[i] != nodeidx[i] )
826 ptr = (uchar*)CV_NODE_VAL(mat,node);
832 if( !ptr && create_node )
836 if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO )
839 int newsize = CV_MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);
840 int newrawsize = newsize*sizeof(newtable[0]);
842 CvSparseMatIterator iterator;
843 assert( (newsize & (newsize - 1)) == 0 );
846 CV_CALL( newtable = (void**)cvAlloc( newrawsize ));
847 memset( newtable, 0, newrawsize );
849 node = cvInitSparseMatIterator( mat, &iterator );
852 CvSparseNode* next = cvGetNextSparseNode( &iterator );
853 int newidx = node->hashval & (newsize - 1);
854 node->next = (CvSparseNode*)newtable[newidx];
855 newtable[newidx] = node;
859 CV_CALL( cvFree( (void**)&mat->hashtable ));
860 mat->hashtable = newtable;
861 mat->hashsize = newsize;
862 tabidx = hashval & (newsize - 1);
865 node = (CvSparseNode*)cvSetNew( mat->heap );
866 node->hashval = hashval;
867 node->next = (CvSparseNode*)mat->hashtable[tabidx];
868 mat->hashtable[tabidx] = node;
869 CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );
870 ptr = (uchar*)CV_NODE_VAL(mat,node);
871 if( create_node > 0 )
872 CV_ZERO_CHAR( ptr, icvPixSize[CV_MAT_TYPE(mat->type)]);
876 *_type = CV_MAT_TYPE(mat->type);
885 icvDeleteNode( CvSparseMat* mat, int* idx, unsigned* precalc_hashval )
887 CV_FUNCNAME( "icvDeleteNode" );
892 unsigned hashval = 0;
893 CvSparseNode *node, *prev = 0;
894 assert( CV_IS_SPARSE_MAT( mat ));
896 if( !precalc_hashval )
898 for( i = 0; i < mat->dims; i++ )
901 if( (unsigned)t >= (unsigned)mat->size[i] )
902 CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );
903 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
908 hashval = *precalc_hashval;
911 tabidx = hashval & (mat->hashsize - 1);
914 for( node = (CvSparseNode*)mat->hashtable[tabidx];
915 node != 0; prev = node, node = node->next )
917 if( node->hashval == hashval )
919 int* nodeidx = CV_NODE_IDX(mat,node);
920 for( i = 0; i < mat->dims; i++ )
921 if( idx[i] != nodeidx[i] )
931 prev->next = node->next;
933 mat->hashtable[tabidx] = node->next;
934 cvSetRemoveByPtr( mat->heap, node );
942 /****************************************************************************************\
943 * Common for multiple array types operations *
944 \****************************************************************************************/
946 // Allocates underlying array data
948 cvCreateData( CvArr* arr )
950 CV_FUNCNAME( "cvCreateData" );
954 if( CV_IS_MAT_HDR( arr ))
956 int64 step, total_size;
957 CvMat* mat = (CvMat*)arr;
960 if( mat->data.ptr != 0 )
961 CV_ERROR( CV_StsError, "Data is already allocated" );
964 step = icvPixSize[CV_MAT_TYPE(mat->type)]*mat->cols;
966 total_size = step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
967 CV_CALL( mat->refcount = (int*)cvAlloc( (size_t)total_size ));
968 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
971 else if( CV_IS_IMAGE_HDR(arr))
973 IplImage* img = (IplImage*)arr;
975 if( img->imageData != 0 )
976 CV_ERROR( CV_StsError, "Data is already allocated" );
978 if( !CvIPL.allocateData )
980 CV_CALL( img->imageData = img->imageDataOrigin =
981 (char*)cvAlloc( (size_t)img->imageSize ));
985 int depth = img->depth;
986 int width = img->width;
988 if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 )
990 img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
991 img->depth = IPL_DEPTH_8U;
994 CvIPL.allocateData( img, 0, 0 );
1000 else if( CV_IS_MATND_HDR( arr ))
1002 CvMatND* mat = (CvMatND*)arr;
1004 int64 total_size = icvPixSize[CV_MAT_TYPE(mat->type)];
1006 if( mat->data.ptr != 0 )
1007 CV_ERROR( CV_StsError, "Data is already allocated" );
1009 if( CV_IS_MAT_CONT( mat->type ))
1011 total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
1012 mat->dim[0].step : total_size);
1016 for( i = mat->dims - 1; i >= 0; i-- )
1018 int64 size = (int64)mat->dim[i].step*mat->dim[i].size;
1020 if( total_size < size )
1025 assert( total_size >= 0 );
1026 CV_CALL( mat->refcount = (int*)cvAlloc( (size_t)total_size +
1027 sizeof(int) + CV_MALLOC_ALIGN ));
1028 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
1033 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1040 // Assigns external data to array
1042 cvSetData( CvArr* arr, void* data, int step )
1044 CV_FUNCNAME( "cvSetData" );
1048 int pix_size, min_step;
1050 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) )
1051 cvReleaseData( arr );
1055 if( CV_IS_MAT_HDR( arr ))
1057 CvMat* mat = (CvMat*)arr;
1059 int type = CV_MAT_TYPE(mat->type);
1060 pix_size = icvPixSize[type];
1061 min_step = mat->cols*pix_size & ((mat->rows <= 1) - 1);
1063 if( step != CV_AUTOSTEP )
1065 if( step < min_step && data != 0 )
1066 CV_ERROR_FROM_CODE( CV_BadStep );
1067 mat->step = step & ((mat->rows <= 1) - 1);
1071 mat->step = min_step;
1074 mat->data.ptr = (uchar*)data;
1075 mat->type = CV_MAT_MAGIC_VAL | type |
1076 (mat->step==min_step ? CV_MAT_CONT_FLAG : 0);
1077 icvCheckHuge( mat );
1079 else if( CV_IS_IMAGE_HDR( arr ))
1081 IplImage* img = (IplImage*)arr;
1083 pix_size = ((img->depth & 255) >> 3)*img->nChannels;
1084 min_step = img->width*pix_size;
1086 if( step != CV_AUTOSTEP && img->height > 1 )
1088 if( step < min_step && data != 0 )
1089 CV_ERROR_FROM_CODE( CV_BadStep );
1090 img->widthStep = step;
1094 img->widthStep = min_step;
1097 img->imageSize = img->widthStep * img->height;
1098 img->imageData = img->imageDataOrigin = (char*)data;
1100 if( (((int)(size_t)data | step) & 7) == 0 &&
1101 cvAlign(img->width * pix_size, 8) == (size_t)step )
1110 else if( CV_IS_MATND_HDR( arr ))
1112 CvMatND* mat = (CvMatND*)arr;
1116 if( step != CV_AUTOSTEP )
1117 CV_ERROR( CV_BadStep,
1118 "For multidimensional array only CV_AUTOSTEP is allowed here" );
1120 mat->data.ptr = (uchar*)data;
1121 cur_step = icvPixSize[CV_MAT_TYPE(mat->type)];
1123 for( i = mat->dims - 1; i >= 0; i-- )
1125 if( cur_step > INT_MAX )
1126 CV_ERROR( CV_StsOutOfRange, "The array is too big" );
1127 mat->dim[i].step = (int)cur_step;
1128 cur_step *= mat->dim[i].size;
1133 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1141 // Deallocates array's data
1143 cvReleaseData( CvArr* arr )
1145 CV_FUNCNAME( "cvReleaseData" );
1149 if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr ))
1151 CvMat* mat = (CvMat*)arr;
1152 cvDecRefData( mat );
1154 else if( CV_IS_IMAGE_HDR( arr ))
1156 IplImage* img = (IplImage*)arr;
1158 if( !CvIPL.deallocate )
1160 char* ptr = img->imageData;
1161 img->imageData = img->imageDataOrigin = 0;
1162 cvFree( (void**)&ptr );
1166 CvIPL.deallocate( img, IPL_IMAGE_DATA );
1171 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1178 // Retrieves essential information about image ROI or CvMat data
1180 cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size )
1182 CV_FUNCNAME( "cvGetRawData" );
1186 if( CV_IS_MAT( arr ))
1188 CvMat *mat = (CvMat*)arr;
1194 *data = mat->data.ptr;
1197 *roi_size = cvGetMatSize( mat );
1199 else if( CV_IS_IMAGE( arr ))
1201 IplImage* img = (IplImage*)arr;
1204 *step = img->widthStep;
1207 CV_CALL( *data = cvPtr2D( img, 0, 0 ));
1213 *roi_size = cvSize( img->roi->width, img->roi->height );
1217 *roi_size = cvSize( img->width, img->height );
1221 else if( CV_IS_MATND( arr ))
1223 CvMatND* mat = (CvMatND*)arr;
1225 if( !CV_IS_MAT_CONT( mat->type ))
1226 CV_ERROR( CV_StsBadArg, "Only continuous nD arrays are supported here" );
1229 *data = mat->data.ptr;
1231 if( roi_size || step )
1233 int i, size1 = mat->dim[0].size, size2 = 1;
1236 for( i = 1; i < mat->dims; i++ )
1237 size1 *= mat->dim[i].size;
1239 size2 = mat->dim[1].size;
1243 roi_size->width = size2;
1244 roi_size->height = size1;
1248 *step = size1 == 1 ? 0 : mat->dim[0].step;
1253 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1261 cvGetElemType( const CvArr* arr )
1265 CV_FUNCNAME( "cvGetElemType" );
1269 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr))
1271 type = CV_MAT_TYPE( ((CvMat*)arr)->type );
1273 else if( CV_IS_IMAGE(arr))
1275 IplImage* img = (IplImage*)arr;
1277 if( img->nChannels > 4 )
1278 CV_ERROR( CV_BadNumChannels, "The image has more than 4 channels" );
1280 type = CV_MAKETYPE( icvIplToCvDepth(img->depth), img->nChannels );
1284 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1293 // Returns a number of array dimensions
1295 cvGetDims( const CvArr* arr, int* sizes )
1298 CV_FUNCNAME( "cvGetDims" );
1302 if( CV_IS_MAT_HDR( arr ))
1304 CvMat* mat = (CvMat*)arr;
1309 sizes[0] = mat->rows;
1310 sizes[1] = mat->cols;
1313 else if( CV_IS_IMAGE( arr ))
1315 IplImage* img = (IplImage*)arr;
1320 sizes[0] = img->height;
1321 sizes[1] = img->width;
1324 else if( CV_IS_MATND_HDR( arr ))
1326 CvMatND* mat = (CvMatND*)arr;
1332 for( i = 0; i < dims; i++ )
1333 sizes[i] = mat->dim[i].size;
1336 else if( CV_IS_SPARSE_MAT_HDR( arr ))
1338 CvSparseMat* mat = (CvSparseMat*)arr;
1342 memcpy( sizes, mat->size, dims*sizeof(sizes[0]));
1346 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1355 // Returns the size of particular array dimension
1357 cvGetDimSize( const CvArr* arr, int index )
1360 CV_FUNCNAME( "cvGetDimSize" );
1364 if( CV_IS_MAT( arr ))
1366 CvMat *mat = (CvMat*)arr;
1377 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1380 else if( CV_IS_IMAGE( arr ))
1382 IplImage* img = (IplImage*)arr;
1387 size = !img->roi ? img->height : img->roi->height;
1390 size = !img->roi ? img->width : img->roi->width;
1393 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1396 else if( CV_IS_MATND_HDR( arr ))
1398 CvMatND* mat = (CvMatND*)arr;
1400 if( (unsigned)index >= (unsigned)mat->dims )
1401 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1403 size = mat->dim[index].size;
1405 else if( CV_IS_SPARSE_MAT_HDR( arr ))
1407 CvSparseMat* mat = (CvSparseMat*)arr;
1409 if( (unsigned)index >= (unsigned)mat->dims )
1410 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1412 size = mat->size[index];
1416 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1425 // Returns the size of CvMat or IplImage
1427 cvGetSize( const CvArr* arr )
1429 CvSize size = { 0, 0 };
1431 CV_FUNCNAME( "cvGetSize" );
1435 if( CV_IS_MAT_HDR( arr ))
1437 CvMat *mat = (CvMat*)arr;
1439 size.width = mat->cols;
1440 size.height = mat->rows;
1442 else if( CV_IS_IMAGE_HDR( arr ))
1444 IplImage* img = (IplImage*)arr;
1448 size.width = img->roi->width;
1449 size.height = img->roi->height;
1453 size.width = img->width;
1454 size.height = img->height;
1459 CV_ERROR( CV_StsBadArg, "Array should be CvMat or IplImage" );
1468 // Selects sub-array (no data is copied)
1470 cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
1474 CV_FUNCNAME( "cvGetRect" );
1478 CvMat stub, *mat = (CvMat*)arr;
1480 if( !CV_IS_MAT( mat ))
1481 CV_CALL( mat = cvGetMat( mat, &stub ));
1484 CV_ERROR( CV_StsNullPtr, "" );
1486 if( (rect.x|rect.y|rect.width|rect.height) < 0 )
1487 CV_ERROR( CV_StsBadSize, "" );
1489 if( rect.x + rect.width > mat->cols ||
1490 rect.y + rect.height > mat->rows )
1491 CV_ERROR( CV_StsBadSize, "" );
1495 int* refcount = mat->refcount;
1500 cvDecRefData( submat );
1502 submat->rows = rect.height;
1503 submat->cols = rect.width;
1504 submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
1505 submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
1506 rect.x*icvPixSize[CV_MAT_TYPE(mat->type)];
1507 submat->type = (mat->type & (submat->cols < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
1508 (submat->step == 0 ? CV_MAT_CONT_FLAG : 0);
1509 submat->refcount = 0;
1519 // Selects array's row span.
1521 cvGetRows( const CvArr* arr, CvMat* submat,
1522 int start_row, int end_row, int delta_row )
1526 CV_FUNCNAME( "cvGetRows" );
1530 CvMat stub, *mat = (CvMat*)arr;
1532 if( !CV_IS_MAT( mat ))
1533 CV_CALL( mat = cvGetMat( mat, &stub ));
1536 CV_ERROR( CV_StsNullPtr, "" );
1538 if( (unsigned)start_row >= (unsigned)mat->rows ||
1539 (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 )
1540 CV_ERROR( CV_StsOutOfRange, "" );
1544 int* refcount = mat->refcount;
1549 cvDecRefData( submat );
1551 if( delta_row == 1 )
1553 submat->rows = end_row - start_row;
1554 submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
1558 submat->rows = (end_row - start_row + delta_row - 1)/delta_row;
1559 submat->step = mat->step * delta_row;
1562 submat->cols = mat->cols;
1563 submat->step &= submat->rows > 1 ? -1 : 0;
1564 submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
1565 submat->type = (mat->type | (submat->step == 0 ? CV_MAT_CONT_FLAG : 0)) &
1566 (delta_row != 1 ? ~CV_MAT_CONT_FLAG : -1);
1567 submat->refcount = 0;
1577 // Selects array's column span.
1579 cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col )
1583 CV_FUNCNAME( "cvGetCols" );
1587 CvMat stub, *mat = (CvMat*)arr;
1589 if( !CV_IS_MAT( mat ))
1590 CV_CALL( mat = cvGetMat( mat, &stub ));
1593 CV_ERROR( CV_StsNullPtr, "" );
1595 if( (unsigned)start_col >= (unsigned)mat->cols ||
1596 (unsigned)end_col > (unsigned)mat->cols )
1597 CV_ERROR( CV_StsOutOfRange, "" );
1601 int* refcount = mat->refcount;
1606 cvDecRefData( submat );
1608 submat->rows = mat->rows;
1609 submat->cols = end_col - start_col;
1610 submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
1611 submat->data.ptr = mat->data.ptr + (size_t)start_col*icvPixSize[CV_MAT_TYPE(mat->type)];
1612 submat->type = mat->type & (submat->step && submat->cols < mat->cols ?
1613 ~CV_MAT_CONT_FLAG : -1);
1614 submat->refcount = 0;
1624 // Selects array diagonal
1626 cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
1630 CV_FUNCNAME( "cvGetDiag" );
1634 CvMat stub, *mat = (CvMat*)arr;
1637 if( !CV_IS_MAT( mat ))
1638 CV_CALL( mat = cvGetMat( mat, &stub ));
1641 CV_ERROR( CV_StsNullPtr, "" );
1643 pix_size = CV_ELEM_SIZE(mat->type);
1646 int* refcount = mat->refcount;
1651 cvDecRefData( submat );
1656 len = mat->cols - diag;
1659 CV_ERROR( CV_StsOutOfRange, "" );
1661 len = CV_IMIN( len, mat->rows );
1662 submat->data.ptr = mat->data.ptr + diag*pix_size;
1666 len = mat->rows + diag;
1669 CV_ERROR( CV_StsOutOfRange, "" );
1671 len = CV_IMIN( len, mat->cols );
1672 submat->data.ptr = mat->data.ptr - diag*mat->step;
1677 submat->step = (mat->step + pix_size) & (submat->rows > 1 ? -1 : 0);
1678 submat->type = mat->type;
1680 submat->type &= ~CV_MAT_CONT_FLAG;
1682 submat->type |= CV_MAT_CONT_FLAG;
1683 submat->refcount = 0;
1692 /****************************************************************************************\
1693 * Operations on CvScalar and accessing array elements *
1694 \****************************************************************************************/
1696 // Converts CvScalar to specified type
1698 cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 )
1700 CV_FUNCNAME( "cvScalarToRawData" );
1702 type = CV_MAT_TYPE(type);
1706 int cn = CV_MAT_CN( type );
1707 int depth = type & CV_MAT_DEPTH_MASK;
1709 assert( scalar && data );
1710 assert( (unsigned)(cn - 1) < 4 );
1717 int t = cvRound( scalar->val[cn] );
1718 ((uchar*)data)[cn] = CV_CAST_8U(t);
1724 int t = cvRound( scalar->val[cn] );
1725 ((char*)data)[cn] = CV_CAST_8S(t);
1731 int t = cvRound( scalar->val[cn] );
1732 ((ushort*)data)[cn] = CV_CAST_16U(t);
1738 int t = cvRound( scalar->val[cn] );
1739 ((short*)data)[cn] = CV_CAST_16S(t);
1744 ((int*)data)[cn] = cvRound( scalar->val[cn] );
1748 ((float*)data)[cn] = (float)(scalar->val[cn]);
1752 ((double*)data)[cn] = (double)(scalar->val[cn]);
1756 CV_ERROR_FROM_CODE( CV_BadDepth );
1761 int pix_size = icvPixSize[type];
1762 int offset = icvPixSize[depth]*12;
1767 CV_MEMCPY_AUTO( (char*)data + offset, data, pix_size );
1769 while( offset > pix_size );
1776 // Converts data of specified type to CvScalar
1778 cvRawDataToScalar( const void* data, int flags, CvScalar* scalar )
1780 CV_FUNCNAME( "cvRawDataToScalar" );
1784 int cn = CV_MAT_CN( flags );
1786 assert( scalar && data );
1787 assert( (unsigned)(cn - 1) < 4 );
1789 memset( scalar->val, 0, sizeof(scalar->val));
1791 switch( CV_MAT_DEPTH( flags ))
1795 scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]);
1799 scalar->val[cn] = CV_8TO32F(((char*)data)[cn]);
1803 scalar->val[cn] = ((ushort*)data)[cn];
1807 scalar->val[cn] = ((short*)data)[cn];
1811 scalar->val[cn] = ((int*)data)[cn];
1815 scalar->val[cn] = ((float*)data)[cn];
1819 scalar->val[cn] = ((double*)data)[cn];
1823 CV_ERROR_FROM_CODE( CV_BadDepth );
1830 static double icvGetReal( const void* data, int type )
1835 return *(uchar*)data;
1837 return *(char*)data;
1839 return *(ushort*)data;
1841 return *(short*)data;
1845 return *(float*)data;
1847 return *(double*)data;
1854 static void icvSetReal( double value, const void* data, int type )
1858 int ivalue = cvRound(value);
1862 *(uchar*)data = CV_CAST_8U(ivalue);
1865 *(char*)data = CV_CAST_8S(ivalue);
1868 *(ushort*)data = CV_CAST_16U(ivalue);
1871 *(short*)data = CV_CAST_16S(ivalue);
1874 *(int*)data = CV_CAST_32S(ivalue);
1883 *(float*)data = (float)value;
1886 *(double*)data = value;
1893 // Returns pointer to specified element of array (linear index is used)
1895 cvPtr1D( const CvArr* arr, int idx, int* _type )
1899 CV_FUNCNAME( "cvPtr1D" );
1903 if( CV_IS_MAT( arr ))
1905 CvMat* mat = (CvMat*)arr;
1907 int type = CV_MAT_TYPE(mat->type);
1908 int pix_size = icvPixSize[type];
1913 // the first part is mul-free sufficient check
1914 // that the index is within the matrix
1915 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
1916 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
1917 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
1919 if( CV_IS_MAT_CONT(mat->type))
1921 ptr = mat->data.ptr + (size_t)idx*pix_size;
1926 if( mat->cols == 1 )
1929 row = idx/mat->cols, col = idx - row*mat->cols;
1930 ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size;
1933 else if( CV_IS_IMAGE_HDR( arr ))
1935 IplImage* img = (IplImage*)arr;
1936 int width = !img->roi ? img->width : img->roi->width;
1937 int y = idx/width, x = idx - y*width;
1939 ptr = cvPtr2D( arr, y, x, _type );
1941 else if( CV_IS_MATND( arr ))
1943 CvMatND* mat = (CvMatND*)arr;
1944 int j, type = CV_MAT_TYPE(mat->type);
1945 size_t size = mat->dim[0].size;
1950 for( j = 1; j < mat->dims; j++ )
1951 size *= mat->dim[j].size;
1953 if((unsigned)idx >= (unsigned)size )
1954 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
1956 if( CV_IS_MAT_CONT(mat->type))
1958 int pix_size = icvPixSize[type];
1959 ptr = mat->data.ptr + (size_t)idx*pix_size;
1963 ptr = mat->data.ptr;
1964 for( j = mat->dims - 1; j >= 0; j-- )
1966 int sz = mat->dim[j].size;
1970 ptr += (idx - t*sz)*mat->dim[j].step;
1976 else if( CV_IS_SPARSE_MAT( arr ))
1978 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 );
1982 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1991 // Returns pointer to specified element of 2d array
1993 cvPtr2D( const CvArr* arr, int y, int x, int* _type )
1997 CV_FUNCNAME( "cvPtr2D" );
2001 if( CV_IS_MAT( arr ))
2003 CvMat* mat = (CvMat*)arr;
2006 if( (unsigned)y >= (unsigned)(mat->rows) ||
2007 (unsigned)x >= (unsigned)(mat->cols) )
2008 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2010 type = CV_MAT_TYPE(mat->type);
2014 ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type];
2016 else if( CV_IS_IMAGE( arr ))
2018 IplImage* img = (IplImage*)arr;
2019 int pix_size = (img->depth & 255) >> 3;
2021 ptr = (uchar*)img->imageData;
2023 if( img->dataOrder == 0 )
2024 pix_size *= img->nChannels;
2028 width = img->roi->width;
2029 height = img->roi->height;
2031 ptr += img->roi->yOffset*img->widthStep +
2032 img->roi->xOffset*pix_size;
2034 if( img->dataOrder )
2036 int coi = img->roi->coi;
2038 CV_ERROR( CV_BadCOI,
2039 "COI must be non-null in case of planar images" );
2040 ptr += (coi - 1)*img->imageSize;
2046 height = img->height;
2049 if( (unsigned)y >= (unsigned)height ||
2050 (unsigned)x >= (unsigned)width )
2051 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2053 ptr += y*img->widthStep + x*pix_size;
2057 int type = icvIplToCvDepth(img->depth);
2058 if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
2059 CV_ERROR( CV_StsUnsupportedFormat, "" );
2061 *_type = CV_MAKETYPE( type, img->nChannels );
2064 else if( CV_IS_MATND( arr ))
2066 CvMatND* mat = (CvMatND*)arr;
2068 if( mat->dims != 2 ||
2069 (unsigned)y >= (unsigned)(mat->dim[0].size) ||
2070 (unsigned)x >= (unsigned)(mat->dim[1].size) )
2071 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2073 ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step;
2075 *_type = CV_MAT_TYPE(mat->type);
2077 else if( CV_IS_SPARSE_MAT( arr ))
2079 int idx[] = { y, x };
2080 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
2084 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2093 // Returns pointer to specified element of 3d array
2095 cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type )
2099 CV_FUNCNAME( "cvPtr3D" );
2103 if( CV_IS_MATND( arr ))
2105 CvMatND* mat = (CvMatND*)arr;
2107 if( mat->dims != 3 ||
2108 (unsigned)z >= (unsigned)(mat->dim[0].size) ||
2109 (unsigned)y >= (unsigned)(mat->dim[1].size) ||
2110 (unsigned)x >= (unsigned)(mat->dim[2].size) )
2111 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2113 ptr = mat->data.ptr + (size_t)z*mat->dim[0].step +
2114 (size_t)y*mat->dim[1].step + x*mat->dim[2].step;
2117 *_type = CV_MAT_TYPE(mat->type);
2119 else if( CV_IS_SPARSE_MAT( arr ))
2121 int idx[] = { z, y, x };
2122 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
2126 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2135 // Returns pointer to specified element of n-d array
2137 cvPtrND( const CvArr* arr, int* idx, int* _type,
2138 int create_node, unsigned* precalc_hashval )
2141 CV_FUNCNAME( "cvPtrND" );
2146 CV_ERROR( CV_StsNullPtr, "NULL pointer to indices" );
2148 if( CV_IS_SPARSE_MAT( arr ))
2149 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx,
2150 _type, create_node, precalc_hashval );
2151 else if( CV_IS_MATND( arr ))
2153 CvMatND* mat = (CvMatND*)arr;
2155 ptr = mat->data.ptr;
2157 for( i = 0; i < mat->dims; i++ )
2159 if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) )
2160 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2161 ptr += (size_t)idx[i]*mat->dim[i].step;
2165 *_type = CV_MAT_TYPE(mat->type);
2167 else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) )
2168 ptr = cvPtr2D( arr, idx[0], idx[1], _type );
2170 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2178 // Returns specifed element of n-D array given linear index
2180 cvGet1D( const CvArr* arr, int idx )
2182 CvScalar scalar = {0,0,0,0};
2184 CV_FUNCNAME( "cvGet1D" );
2191 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2193 CvMat* mat = (CvMat*)arr;
2195 type = CV_MAT_TYPE(mat->type);
2196 int pix_size = icvPixSize[type];
2198 // the first part is mul-free sufficient check
2199 // that the index is within the matrix
2200 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2201 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2202 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2204 ptr = mat->data.ptr + (size_t)idx*pix_size;
2206 else if( !CV_IS_SPARSE_MAT( arr ))
2207 ptr = cvPtr1D( arr, idx, &type );
2209 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
2211 cvRawDataToScalar( ptr, type, &scalar );
2219 // Returns specifed element of 2D array
2221 cvGet2D( const CvArr* arr, int y, int x )
2223 CvScalar scalar = {0,0,0,0};
2225 CV_FUNCNAME( "cvGet2D" );
2232 if( CV_IS_MAT( arr ))
2234 CvMat* mat = (CvMat*)arr;
2236 if( (unsigned)y >= (unsigned)(mat->rows) ||
2237 (unsigned)x >= (unsigned)(mat->cols) )
2238 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2240 type = CV_MAT_TYPE(mat->type);
2241 ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type];
2243 else if( !CV_IS_SPARSE_MAT( arr ))
2244 ptr = cvPtr2D( arr, y, x, &type );
2247 int idx[] = { y, x };
2248 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2251 cvRawDataToScalar( ptr, type, &scalar );
2259 // Returns specifed element of 3D array
2261 cvGet3D( const CvArr* arr, int z, int y, int x )
2263 CvScalar scalar = {0,0,0,0};
2265 /*CV_FUNCNAME( "cvGet3D" );*/
2272 if( !CV_IS_SPARSE_MAT( arr ))
2273 ptr = cvPtr3D( arr, z, y, x, &type );
2276 int idx[] = { z, y, x };
2277 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2280 cvRawDataToScalar( ptr, type, &scalar );
2288 // Returns specifed element of nD array
2290 cvGetND( const CvArr* arr, int* idx )
2292 CvScalar scalar = {0,0,0,0};
2294 /*CV_FUNCNAME( "cvGetND" );*/
2301 if( !CV_IS_SPARSE_MAT( arr ))
2302 ptr = cvPtrND( arr, idx, &type );
2304 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2306 cvRawDataToScalar( ptr, type, &scalar );
2314 // Returns specifed element of n-D array given linear index
2316 cvGetReal1D( const CvArr* arr, int idx )
2320 CV_FUNCNAME( "cvGetReal1D" );
2327 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2329 CvMat* mat = (CvMat*)arr;
2331 type = CV_MAT_TYPE(mat->type);
2332 int pix_size = icvPixSize[type];
2334 // the first part is mul-free sufficient check
2335 // that the index is within the matrix
2336 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2337 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2338 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2340 ptr = mat->data.ptr + (size_t)idx*pix_size;
2342 else if( !CV_IS_SPARSE_MAT( arr ))
2343 ptr = cvPtr1D( arr, idx, &type );
2345 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
2349 if( CV_MAT_CN( type ) > 1 )
2350 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2352 value = icvGetReal( ptr, type );
2361 // Returns specifed element of 2D array
2363 cvGetReal2D( const CvArr* arr, int y, int x )
2367 CV_FUNCNAME( "cvGetReal2D" );
2374 if( CV_IS_MAT( arr ))
2376 CvMat* mat = (CvMat*)arr;
2378 if( (unsigned)y >= (unsigned)(mat->rows) ||
2379 (unsigned)x >= (unsigned)(mat->cols) )
2380 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2382 type = CV_MAT_TYPE(mat->type);
2383 ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type];
2385 else if( !CV_IS_SPARSE_MAT( arr ))
2386 ptr = cvPtr2D( arr, y, x, &type );
2389 int idx[] = { y, x };
2391 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2396 if( CV_MAT_CN( type ) > 1 )
2397 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2399 value = icvGetReal( ptr, type );
2408 // Returns specifed element of 3D array
2410 cvGetReal3D( const CvArr* arr, int z, int y, int x )
2414 CV_FUNCNAME( "cvGetReal3D" );
2421 if( !CV_IS_SPARSE_MAT( arr ))
2422 ptr = cvPtr3D( arr, z, y, x, &type );
2425 int idx[] = { z, y, x };
2426 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2431 if( CV_MAT_CN( type ) > 1 )
2432 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2434 value = icvGetReal( ptr, type );
2443 // Returns specifed element of nD array
2445 cvGetRealND( const CvArr* arr, int* idx )
2449 CV_FUNCNAME( "cvGetRealND" );
2456 if( !CV_IS_SPARSE_MAT( arr ))
2457 ptr = cvPtrND( arr, idx, &type );
2459 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2463 if( CV_MAT_CN( type ) > 1 )
2464 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2466 value = icvGetReal( ptr, type );
2475 // Assigns new value to specifed element of nD array given linear index
2477 cvSet1D( CvArr* arr, int idx, CvScalar scalar )
2479 CV_FUNCNAME( "cvSet1D" );
2486 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2488 CvMat* mat = (CvMat*)arr;
2490 type = CV_MAT_TYPE(mat->type);
2491 int pix_size = icvPixSize[type];
2493 // the first part is mul-free sufficient check
2494 // that the index is within the matrix
2495 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2496 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2497 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2499 ptr = mat->data.ptr + (size_t)idx*pix_size;
2501 else if( !CV_IS_SPARSE_MAT( arr ))
2502 ptr = cvPtr1D( arr, idx, &type );
2504 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2506 cvScalarToRawData( &scalar, ptr, type );
2512 // Assigns new value to specifed element of 2D array
2514 cvSet2D( CvArr* arr, int y, int x, CvScalar scalar )
2516 CV_FUNCNAME( "cvSet2D" );
2523 if( CV_IS_MAT( arr ))
2525 CvMat* mat = (CvMat*)arr;
2527 if( (unsigned)y >= (unsigned)(mat->rows) ||
2528 (unsigned)x >= (unsigned)(mat->cols) )
2529 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2531 type = CV_MAT_TYPE(mat->type);
2532 ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type];
2534 else if( !CV_IS_SPARSE_MAT( arr ))
2535 ptr = cvPtr2D( arr, y, x, &type );
2538 int idx[] = { y, x };
2539 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2541 cvScalarToRawData( &scalar, ptr, type );
2547 // Assigns new value to specifed element of 3D array
2549 cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar )
2551 /*CV_FUNCNAME( "cvSet3D" );*/
2558 if( !CV_IS_SPARSE_MAT( arr ))
2559 ptr = cvPtr3D( arr, z, y, x, &type );
2562 int idx[] = { z, y, x };
2563 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2565 cvScalarToRawData( &scalar, ptr, type );
2571 // Assigns new value to specifed element of nD array
2573 cvSetND( CvArr* arr, int* idx, CvScalar scalar )
2575 /*CV_FUNCNAME( "cvSetND" );*/
2582 if( !CV_IS_SPARSE_MAT( arr ))
2583 ptr = cvPtrND( arr, idx, &type );
2585 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2586 cvScalarToRawData( &scalar, ptr, type );
2593 cvSetReal1D( CvArr* arr, int idx, double value )
2595 CV_FUNCNAME( "cvSetReal1D" );
2602 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2604 CvMat* mat = (CvMat*)arr;
2606 type = CV_MAT_TYPE(mat->type);
2607 int pix_size = icvPixSize[type];
2609 // the first part is mul-free sufficient check
2610 // that the index is within the matrix
2611 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2612 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2613 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2615 ptr = mat->data.ptr + (size_t)idx*pix_size;
2617 else if( !CV_IS_SPARSE_MAT( arr ))
2618 ptr = cvPtr1D( arr, idx, &type );
2620 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2622 if( CV_MAT_CN( type ) > 1 )
2623 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2626 icvSetReal( value, ptr, type );
2633 cvSetReal2D( CvArr* arr, int y, int x, double value )
2635 CV_FUNCNAME( "cvSetReal2D" );
2642 if( CV_IS_MAT( arr ))
2644 CvMat* mat = (CvMat*)arr;
2646 if( (unsigned)y >= (unsigned)(mat->rows) ||
2647 (unsigned)x >= (unsigned)(mat->cols) )
2648 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2650 type = CV_MAT_TYPE(mat->type);
2651 ptr = mat->data.ptr + (size_t)y*mat->step + x*icvPixSize[type];
2653 else if( !CV_IS_SPARSE_MAT( arr ))
2655 ptr = cvPtr2D( arr, y, x, &type );
2659 int idx[] = { y, x };
2660 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2662 if( CV_MAT_CN( type ) > 1 )
2663 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2666 icvSetReal( value, ptr, type );
2673 cvSetReal3D( CvArr* arr, int z, int y, int x, double value )
2675 CV_FUNCNAME( "cvSetReal3D" );
2682 if( !CV_IS_SPARSE_MAT( arr ))
2683 ptr = cvPtr3D( arr, z, y, x, &type );
2686 int idx[] = { z, y, x };
2687 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2689 if( CV_MAT_CN( type ) > 1 )
2690 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2693 icvSetReal( value, ptr, type );
2700 cvSetRealND( CvArr* arr, int* idx, double value )
2702 CV_FUNCNAME( "cvSetRealND" );
2709 if( !CV_IS_SPARSE_MAT( arr ))
2710 ptr = cvPtrND( arr, idx, &type );
2712 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2714 if( CV_MAT_CN( type ) > 1 )
2715 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2718 icvSetReal( value, ptr, type );
2725 cvClearND( CvArr* arr, int* idx )
2727 /*CV_FUNCNAME( "cvClearND" );*/
2731 if( !CV_IS_SPARSE_MAT( arr ))
2735 ptr = cvPtrND( arr, idx, &type );
2737 CV_ZERO_CHAR( ptr, icvPixSize[type] );
2741 icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
2748 /****************************************************************************************\
2749 * Conversion to CvMat or IplImage *
2750 \****************************************************************************************/
2752 // convert array (CvMat or IplImage) to CvMat
2754 cvGetMat( const CvArr* array, CvMat* mat,
2755 int* pCOI, int allowND )
2758 CvMat* src = (CvMat*)array;
2761 CV_FUNCNAME( "cvGetMat" );
2766 CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );
2768 if( CV_IS_MAT_HDR(src))
2770 if( !src->data.ptr )
2771 CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );
2773 result = (CvMat*)src;
2775 else if( CV_IS_IMAGE_HDR(src) )
2777 const IplImage* img = (const IplImage*)src;
2780 if( img->imageData == 0 )
2781 CV_ERROR( CV_StsNullPtr, "The image has NULL data pointer" );
2783 depth = icvIplToCvDepth( img->depth );
2785 CV_ERROR_FROM_CODE( CV_BadDepth );
2787 order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
2791 if( order == IPL_DATA_ORDER_PLANE )
2795 if( img->roi->coi == 0 )
2796 CV_ERROR( CV_StsBadFlag,
2797 "Images with planar data layout should be used with COI selected" );
2799 CV_CALL( cvInitMatHeader( mat, img->roi->height,
2800 img->roi->width, type,
2801 img->imageData + (img->roi->coi-1)*img->imageSize +
2802 img->roi->yOffset*img->widthStep +
2803 img->roi->xOffset*icvPixSize[type],
2806 else /* pixel order */
2808 int type = CV_MAKETYPE( depth, img->nChannels );
2809 coi = img->roi->coi;
2811 if( img->nChannels > 4 )
2812 CV_ERROR( CV_BadNumChannels,
2813 "The image is interleaved and has more than 4 channels" );
2815 CV_CALL( cvInitMatHeader( mat, img->roi->height, img->roi->width,
2816 type, img->imageData +
2817 img->roi->yOffset*img->widthStep +
2818 img->roi->xOffset*icvPixSize[type],
2824 int type = CV_MAKETYPE( depth, img->nChannels );
2826 if( order != IPL_DATA_ORDER_PIXEL )
2827 CV_ERROR( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
2829 CV_CALL( cvInitMatHeader( mat, img->height, img->width, type,
2830 img->imageData, img->widthStep ));
2835 else if( allowND && CV_IS_MATND_HDR(src) )
2837 CvMatND* matnd = (CvMatND*)src;
2839 int size1 = matnd->dim[0].size, size2 = 1;
2841 if( !src->data.ptr )
2842 CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );
2844 if( !CV_IS_MAT_CONT( matnd->type ))
2845 CV_ERROR( CV_StsBadArg, "Only continuous nD arrays are supported here" );
2847 if( matnd->dims > 2 )
2848 for( i = 1; i < matnd->dims; i++ )
2849 size2 *= matnd->dim[i].size;
2851 size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
2854 mat->data.ptr = matnd->data.ptr;
2857 mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
2858 mat->step = size2*icvPixSize[CV_MAT_TYPE(matnd->type)];
2859 mat->step &= size1 > 1 ? -1 : 0;
2861 icvCheckHuge( mat );
2866 CV_ERROR( CV_StsBadFlag, "Unrecognized or unsupported array type" );
2879 cvReshapeMatND( const CvArr* arr,
2880 int sizeof_header, CvArr* _header,
2881 int new_cn, int new_dims, int* new_sizes )
2884 CV_FUNCNAME( "cvReshapeMatND" );
2890 if( !arr || !_header )
2891 CV_ERROR( CV_StsNullPtr, "NULL pointer to array or destination header" );
2893 if( new_cn == 0 && new_dims == 0 )
2894 CV_ERROR( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
2896 if( (unsigned)new_cn > 4 )
2897 CV_ERROR( CV_BadNumChannels,
2898 "Number of channels should be 0 (not changed) or 1..4" );
2900 CV_CALL( dims = cvGetDims( arr ));
2907 else if( new_dims == 1 )
2913 if( new_dims <= 0 || new_dims > CV_MAX_DIM )
2914 CV_ERROR( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
2916 CV_ERROR( CV_StsNullPtr, "New dimension sizes are not specified" );
2921 CvMat* mat = (CvMat*)arr;
2922 CvMat* header = (CvMat*)_header;
2924 int total_width, new_rows, cn;
2926 if( sizeof_header != sizeof(CvMat))
2927 CV_ERROR( CV_StsBadArg, "The header should be CvMat" );
2930 refcount = mat->refcount;
2931 else if( !CV_IS_MAT( mat ))
2932 CV_CALL( mat = cvGetMat( mat, header, &coi, 1 ));
2934 cn = CV_MAT_CN( mat->type );
2935 total_width = mat->cols * cn;
2941 new_rows = new_sizes[0];
2942 else if( new_dims == 1 )
2943 new_rows = total_width*mat->rows/new_cn;
2946 new_rows = mat->rows;
2947 if( new_cn > total_width )
2948 new_rows = mat->rows * total_width / new_cn;
2951 if( new_rows != mat->rows )
2953 int total_size = total_width * mat->rows;
2955 if( !CV_IS_MAT_CONT( mat->type ))
2956 CV_ERROR( CV_BadStep,
2957 "The matrix is not continuous so the number of rows can not be changed" );
2959 total_width = total_size / new_rows;
2961 if( total_width * new_rows != total_size )
2962 CV_ERROR( CV_StsBadArg, "The total number of matrix elements "
2963 "is not divisible by the new number of rows" );
2966 header->rows = new_rows;
2967 header->cols = total_width / new_cn;
2969 if( header->cols * new_cn != total_width ||
2970 new_sizes && header->cols != new_sizes[1] )
2971 CV_ERROR( CV_StsBadArg, "The total matrix width is not "
2972 "divisible by the new number of columns" );
2974 header->type = CV_MAKETYPE( mat->type & ~CV_MAT_CN_MASK, new_cn );
2975 header->step = header->cols * icvPixSize[CV_MAT_TYPE(mat->type)];
2976 header->step &= new_rows > 1 ? -1 : 0;
2977 header->refcount = refcount;
2981 CvMatND* header = (CvMatND*)_header;
2983 if( sizeof_header != sizeof(CvMatND))
2984 CV_ERROR( CV_StsBadSize, "The header should be CvMatND" );
2988 if( !CV_IS_MATND( arr ))
2989 CV_ERROR( CV_StsBadArg, "The source array must be CvMatND" );
2992 CvMatND* mat = (CvMatND*)arr;
2993 assert( new_cn > 0 );
2994 int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
2995 int new_size = last_dim_size/new_cn;
2997 if( new_size*new_cn != last_dim_size )
2998 CV_ERROR( CV_StsBadArg,
2999 "The last dimension full size is not divisible by new number of channels");
3003 memcpy( header, mat, sizeof(*header));
3004 header->refcount = 0;
3007 header->dim[header->dims-1].size = new_size;
3008 header->type = CV_MAKETYPE( header->type & ~CV_MAT_CN_MASK, new_cn );
3014 CvMatND* mat = (CvMatND*)arr;
3015 int i, size1, size2;
3019 CV_ERROR( CV_StsBadArg,
3020 "Simultaneous change of shape and number of channels is not supported. "
3021 "Do it by 2 separate calls" );
3023 if( !CV_IS_MATND( mat ))
3025 CV_CALL( cvGetMatND( mat, &stub, &coi ));
3029 if( CV_IS_MAT_CONT( mat->type ))
3030 CV_ERROR( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
3032 size1 = mat->dim[0].size;
3033 for( i = 1; i < dims; i++ )
3034 size1 *= mat->dim[i].size;
3037 for( i = 0; i < new_dims; i++ )
3039 if( new_sizes[i] <= 0 )
3040 CV_ERROR( CV_StsBadSize,
3041 "One of new dimension sizes is non-positive" );
3042 size2 *= new_sizes[i];
3045 if( size1 != size2 )
3046 CV_ERROR( CV_StsBadSize,
3047 "Number of elements in the original and reshaped array is different" );
3050 header->refcount = 0;
3052 header->dims = new_dims;
3053 header->type = mat->type;
3054 header->data.ptr = mat->data.ptr;
3055 step = icvPixSize[CV_MAT_TYPE(header->type)];
3057 for( i = new_dims - 1; i >= 0; i-- )
3059 header->dim[i].size = new_sizes[i];
3060 header->dim[i].step = step;
3061 step *= new_sizes[i];
3067 CV_ERROR( CV_BadCOI, "COI is not supported by this operation" );
3078 cvReshape( const CvArr* array, CvMat* header,
3079 int new_cn, int new_rows )
3082 CV_FUNCNAME( "cvReshape" );
3086 CvMat *mat = (CvMat*)array;
3087 int total_width, new_width;
3090 CV_ERROR( CV_StsNullPtr, "" );
3092 if( !CV_IS_MAT( mat ))
3095 CV_CALL( mat = cvGetMat( mat, header, &coi, 1 ));
3097 CV_ERROR( CV_BadCOI, "COI is not supported" );
3101 new_cn = CV_MAT_CN(mat->type);
3102 else if( (unsigned)(new_cn - 1) > 3 )
3103 CV_ERROR( CV_BadNumChannels, "" );
3108 header->refcount = 0;
3111 total_width = mat->cols * CV_MAT_CN( mat->type );
3113 if( new_cn > total_width )
3114 new_rows = mat->rows * total_width / new_cn;
3118 int total_size = total_width * mat->rows;
3120 if( !CV_IS_MAT_CONT( mat->type ))
3121 CV_ERROR( CV_BadStep,
3122 "The matrix is not continuous, thus its number of rows can not be changed" );
3124 if( (unsigned)new_rows > (unsigned)total_size )
3125 CV_ERROR( CV_StsOutOfRange, "Bad new number of rows" );
3127 total_width = total_size / new_rows;
3129 if( total_width * new_rows != total_size )
3130 CV_ERROR( CV_StsBadArg, "The total number of matrix elements "
3131 "is not divisible by the new number of rows" );
3133 header->rows = new_rows;
3134 header->step = total_width * icvPixSize[mat->type & CV_MAT_DEPTH_MASK];
3137 new_width = total_width / new_cn;
3139 if( new_width * new_cn != total_width )
3140 CV_ERROR( CV_BadNumChannels,
3141 "The total width is not divisible by the new number of channels" );
3143 header->cols = new_width;
3144 header->type = CV_MAKETYPE( mat->type & ~CV_MAT_CN_MASK, new_cn );
3154 // convert array (CvMat or IplImage) to IplImage
3156 cvGetImage( const CvArr* array, IplImage* img )
3158 IplImage* result = 0;
3159 const IplImage* src = (const IplImage*)array;
3161 CV_FUNCNAME( "cvGetImage" );
3168 CV_ERROR_FROM_CODE( CV_StsNullPtr );
3170 if( !CV_IS_IMAGE_HDR(src) )
3172 const CvMat* mat = (const CvMat*)src;
3174 if( !CV_IS_MAT_HDR(mat))
3175 CV_ERROR_FROM_CODE( CV_StsBadFlag );
3177 if( mat->data.ptr == 0 )
3178 CV_ERROR_FROM_CODE( CV_StsNullPtr );
3180 depth = cvCvToIplDepth(mat->type);
3182 cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
3183 depth, CV_MAT_CN(mat->type) );
3184 cvSetData( img, mat->data.ptr, mat->step );
3190 result = (IplImage*)src;
3199 /****************************************************************************************\
3200 * IplImage-specific functions *
3201 \****************************************************************************************/
3203 static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height )
3207 CV_FUNCNAME( "icvCreateROI" );
3211 if( !CvIPL.createROI )
3213 CV_CALL( roi = (IplROI*)cvAlloc( sizeof(*roi)));
3216 roi->xOffset = xOffset;
3217 roi->yOffset = yOffset;
3219 roi->height = height;
3223 roi = CvIPL.createROI( coi, xOffset, yOffset, width, height );
3232 icvGetColorModel( int nchannels, char** colorModel, char** channelSeq )
3234 static char* tab[][2] =
3243 *colorModel = *channelSeq = "";
3245 if( (unsigned)nchannels <= 3 )
3247 *colorModel = tab[nchannels][0];
3248 *channelSeq = tab[nchannels][1];
3253 // create IplImage header
3255 cvCreateImageHeader( CvSize size, int depth, int channels )
3259 CV_FUNCNAME( "cvCreateImageHeader" );
3263 if( !CvIPL.createHeader )
3265 CV_CALL( img = (IplImage *)cvAlloc( sizeof( *img )));
3266 CV_CALL( cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
3267 CV_DEFAULT_IMAGE_ROW_ALIGN ));
3274 icvGetColorModel( channels, &colorModel, &channelSeq );
3276 img = CvIPL.createHeader( channels, 0, depth, colorModel, channelSeq,
3277 IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
3278 CV_DEFAULT_IMAGE_ROW_ALIGN,
3279 size.width, size.height, 0, 0, 0, 0 );
3284 if( cvGetErrStatus() < 0 && img )
3285 cvReleaseImageHeader( &img );
3291 // create IplImage header and allocate underlying data
3293 cvCreateImage( CvSize size, int depth, int channels )
3297 CV_FUNCNAME( "cvCreateImage" );
3301 CV_CALL( img = cvCreateImageHeader( size, depth, channels ));
3303 CV_CALL( cvCreateData( img ));
3307 if( cvGetErrStatus() < 0 )
3308 cvReleaseImage( &img );
3314 // initalize IplImage header, allocated by the user
3316 cvInitImageHeader( IplImage * image, CvSize size, int depth,
3317 int channels, int origin, int align )
3319 IplImage* result = 0;
3321 CV_FUNCNAME( "cvInitImageHeader" );
3325 char *colorModel, *channelSeq;
3328 CV_ERROR( CV_HeaderIsNull, "null pointer to header" );
3330 memset( image, 0, sizeof( *image ));
3331 image->nSize = sizeof( *image );
3333 CV_CALL( icvGetColorModel( channels, &colorModel, &channelSeq ));
3334 strncpy( image->colorModel, colorModel, 4 );
3335 strncpy( image->channelSeq, channelSeq, 4 );
3337 if( size.width < 0 || size.height < 0 )
3338 CV_ERROR( CV_BadROISize, "Bad input roi" );
3340 if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U &&
3341 depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U &&
3342 depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S &&
3343 depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) ||
3345 CV_ERROR( CV_BadDepth, "Unsupported format" );
3346 if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL )
3347 CV_ERROR( CV_BadOrigin, "Bad input origin" );
3349 if( align != 4 && align != 8 )
3350 CV_ERROR( CV_BadAlign, "Bad input align" );
3352 image->width = size.width;
3353 image->height = size.height;
3357 image->roi->coi = 0;
3358 image->roi->xOffset = image->roi->yOffset = 0;
3359 image->roi->width = size.width;
3360 image->roi->height = size.height;
3363 image->nChannels = MAX( channels, 1 );
3364 image->depth = depth;
3365 image->align = align;
3366 image->widthStep = (((image->width * image->nChannels *
3367 (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));
3368 image->origin = origin;
3369 image->imageSize = image->widthStep * image->height;
3380 cvReleaseImageHeader( IplImage** image )
3382 CV_FUNCNAME( "cvReleaseImageHeader" );
3387 CV_ERROR( CV_StsNullPtr, "" );
3391 IplImage* img = *image;
3394 if( !CvIPL.deallocate )
3396 cvFree( (void**)&(img->roi) );
3397 cvFree( (void**)&img );
3401 CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
3409 cvReleaseImage( IplImage ** image )
3411 CV_FUNCNAME( "cvReleaseImage" );
3416 CV_ERROR( CV_StsNullPtr, "" );
3420 IplImage* img = *image;
3423 cvReleaseData( img );
3424 cvReleaseImageHeader( &img );
3432 cvSetImageROI( IplImage* image, CvRect rect )
3434 CV_FUNCNAME( "cvSetImageROI" );
3439 CV_ERROR( CV_HeaderIsNull, "" );
3441 if( rect.x > image->width || rect.y > image->height )
3442 CV_ERROR( CV_BadROISize, "" );
3444 if( rect.x + rect.width < 0 || rect.y + rect.height < 0 )
3445 CV_ERROR( CV_BadROISize, "" );
3449 rect.width += rect.x;
3455 rect.height += rect.y;
3459 if( rect.x + rect.width > image->width )
3460 rect.width = image->width - rect.x;
3462 if( rect.y + rect.height > image->height )
3463 rect.height = image->height - rect.y;
3467 image->roi->xOffset = rect.x;
3468 image->roi->yOffset = rect.y;
3469 image->roi->width = rect.width;
3470 image->roi->height = rect.height;
3474 CV_CALL( image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height ));
3482 cvResetImageROI( IplImage* image )
3484 CV_FUNCNAME( "cvResetImageROI" );
3489 CV_ERROR( CV_HeaderIsNull, "" );
3493 if( !CvIPL.deallocate )
3495 CV_CALL( cvFree( (void**)&(image->roi) ));
3499 CvIPL.deallocate( image, IPL_IMAGE_ROI );
3509 cvGetImageROI( const IplImage* img )
3511 CvRect rect = { 0, 0, 0, 0 };
3513 CV_FUNCNAME( "cvGetImageROI" );
3518 CV_ERROR( CV_StsNullPtr, "Null pointer to image" );
3521 rect = cvRect( img->roi->xOffset, img->roi->yOffset,
3522 img->roi->width, img->roi->height );
3524 rect = cvRect( 0, 0, img->width, img->height );
3533 cvSetImageCOI( IplImage* image, int coi )
3535 CV_FUNCNAME( "cvSetImageCOI" );
3540 CV_ERROR( CV_HeaderIsNull, "" );
3542 if( (unsigned)coi > (unsigned)(image->nChannels) )
3543 CV_ERROR( CV_BadCOI, "" );
3545 if( image->roi || coi != 0 )
3549 image->roi->coi = coi;
3553 CV_CALL( image->roi = icvCreateROI( coi, 0, 0, image->width, image->height ));
3562 cvGetImageCOI( const IplImage* image )
3565 CV_FUNCNAME( "cvGetImageCOI" );
3570 CV_ERROR( CV_HeaderIsNull, "" );
3572 coi = image->roi ? image->roi->coi : 0;
3581 cvCloneImage( const IplImage* src )
3584 CV_FUNCNAME( "cvCloneImage" );
3588 if( !CV_IS_IMAGE_HDR( src ))
3589 CV_ERROR( CV_StsBadArg, "Bad image header" );
3591 if( !CvIPL.cloneImage )
3593 CV_CALL( dst = (IplImage*)cvAlloc( sizeof(*dst)));
3595 memcpy( dst, src, sizeof(*src));
3596 dst->imageData = dst->imageDataOrigin = 0;
3601 dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset,
3602 src->roi->yOffset, src->roi->width, src->roi->height );
3605 if( src->imageData )
3607 int size = src->imageSize;
3608 cvCreateData( dst );
3609 memcpy( dst->imageData, src->imageData, size );
3614 dst = CvIPL.cloneImage( src );
3623 /****************************************************************************************\
3624 * Additional operations on CvTermCriteria *
3625 \****************************************************************************************/
3627 CV_IMPL CvTermCriteria
3628 cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
3629 int default_max_iters )
3631 CV_FUNCNAME( "cvCheckTermCriteria" );
3633 CvTermCriteria crit;
3635 crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
3636 crit.max_iter = default_max_iters;
3637 crit.epsilon = (float)default_eps;
3641 if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 )
3642 CV_ERROR( CV_StsBadArg,
3643 "Unknown type of term criteria" );
3645 if( (criteria.type & CV_TERMCRIT_ITER) != 0 )
3647 if( criteria.max_iter <= 0 )
3648 CV_ERROR( CV_StsBadArg,
3649 "Iterations flag is set and maximum number of iterations is <= 0" );
3650 crit.max_iter = criteria.max_iter;
3653 if( (criteria.type & CV_TERMCRIT_EPS) != 0 )
3655 if( criteria.epsilon < 0 )
3656 CV_ERROR( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" );
3658 crit.epsilon = criteria.epsilon;
3661 if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 )
3662 CV_ERROR( CV_StsBadArg,
3663 "Neither accuracy nor maximum iterations "
3664 "number flags are set in criteria type" );
3668 crit.epsilon = (float)MAX( 0, crit.epsilon );
3669 crit.max_iter = MAX( 1, crit.max_iter );