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 = CV_ELEM_SIZE(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);
151 arr->hdr_refcount = 1;
157 if( cvGetErrStatus() < 0 )
158 cvReleaseMat( &arr );
164 // Initializes CvMat header, allocated by the user
166 cvInitMatHeader( CvMat* arr, int rows, int cols,
167 int type, void* data, int step )
169 CV_FUNCNAME( "cvInitMatHeader" );
173 int mask, pix_size, min_step;
176 CV_ERROR_FROM_CODE( CV_StsNullPtr );
178 if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
179 CV_ERROR_FROM_CODE( CV_BadNumChannels );
181 if( rows <= 0 || cols <= 0 )
182 CV_ERROR( CV_StsBadSize, "Non-positive cols or rows" );
184 type = CV_MAT_TYPE( type );
185 arr->type = type | CV_MAT_MAGIC_VAL;
188 arr->data.ptr = (uchar*)data;
190 arr->hdr_refcount = 0;
192 mask = (arr->rows <= 1) - 1;
193 pix_size = CV_ELEM_SIZE(type);
194 min_step = arr->cols*pix_size & mask;
196 if( step != CV_AUTOSTEP && step != 0 )
198 if( step < min_step )
199 CV_ERROR_FROM_CODE( CV_BadStep );
200 arr->step = step & mask;
204 arr->step = min_step;
207 arr->type = CV_MAT_MAGIC_VAL | type |
208 (arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
218 // Deallocates the CvMat structure and underlying data
220 cvReleaseMat( CvMat** array )
222 CV_FUNCNAME( "cvReleaseMat" );
227 CV_ERROR_FROM_CODE( CV_HeaderIsNull );
233 if( !CV_IS_MAT_HDR(arr) && !CV_IS_MATND_HDR(arr) )
234 CV_ERROR_FROM_CODE( CV_StsBadFlag );
246 // Creates a copy of matrix
248 cvCloneMat( const CvMat* src )
251 CV_FUNCNAME( "cvCloneMat" );
255 if( !CV_IS_MAT_HDR( src ))
256 CV_ERROR( CV_StsBadArg, "Bad CvMat header" );
258 CV_CALL( dst = cvCreateMatHeader( src->rows, src->cols, src->type ));
262 CV_CALL( cvCreateData( dst ));
263 CV_CALL( cvCopy( src, dst ));
272 /****************************************************************************************\
273 * CvMatND creation and basic operations *
274 \****************************************************************************************/
277 cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
278 int type, void* data )
282 CV_FUNCNAME( "cvInitMatNDHeader" );
286 type = CV_MAT_TYPE(type);
288 int64 step = CV_ELEM_SIZE(type);
291 CV_ERROR( CV_StsNullPtr, "NULL matrix header pointer" );
294 CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
297 CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
299 if( dims <= 0 || dims > CV_MAX_DIM )
300 CV_ERROR( CV_StsOutOfRange,
301 "non-positive or too large number of dimensions" );
303 for( i = dims - 1; i >= 0; i-- )
306 CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
307 mat->dim[i].size = sizes[i];
309 CV_ERROR( CV_StsOutOfRange, "The array is too big" );
310 mat->dim[i].step = (int)step;
314 mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
316 mat->data.ptr = (uchar*)data;
318 mat->hdr_refcount = 0;
323 if( cvGetErrStatus() < 0 && mat )
333 // Creates CvMatND and underlying data
335 cvCreateMatND( int dims, const int* sizes, int type )
339 CV_FUNCNAME( "cvCreateMatND" );
343 CV_CALL( arr = cvCreateMatNDHeader( dims, sizes, type ));
344 CV_CALL( cvCreateData( arr ));
348 if( cvGetErrStatus() < 0 )
349 cvReleaseMatND( &arr );
355 // Creates CvMatND header only
357 cvCreateMatNDHeader( int dims, const int* sizes, int type )
361 CV_FUNCNAME( "cvCreateMatNDHeader" );
365 if( dims <= 0 || dims > CV_MAX_DIM )
366 CV_ERROR( CV_StsOutOfRange,
367 "non-positive or too large number of dimensions" );
369 CV_CALL( arr = (CvMatND*)cvAlloc( sizeof(*arr) ));
371 CV_CALL( cvInitMatNDHeader( arr, dims, sizes, type, 0 ));
372 arr->hdr_refcount = 1;
376 if( cvGetErrStatus() < 0 )
377 cvReleaseMatND( &arr );
383 // Creates a copy of nD array
385 cvCloneMatND( const CvMatND* src )
388 CV_FUNCNAME( "cvCloneMatND" );
394 if( !CV_IS_MATND_HDR( src ))
395 CV_ERROR( CV_StsBadArg, "Bad CvMatND header" );
397 sizes = (int*)alloca( src->dims*sizeof(sizes[0]) );
399 for( i = 0; i < src->dims; i++ )
400 sizes[i] = src->dim[i].size;
402 CV_CALL( dst = cvCreateMatNDHeader( src->dims, sizes, src->type ));
406 CV_CALL( cvCreateData( dst ));
407 CV_CALL( cvCopy( src, dst ));
417 cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi )
421 CV_FUNCNAME( "cvGetMatND" );
429 CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );
431 if( CV_IS_MATND_HDR(arr))
433 if( !((CvMatND*)arr)->data.ptr )
434 CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );
436 result = (CvMatND*)arr;
440 CvMat stub, *mat = (CvMat*)arr;
442 if( CV_IS_IMAGE_HDR( mat ))
443 CV_CALL( mat = cvGetMat( mat, &stub, coi ));
445 if( !CV_IS_MAT_HDR( mat ))
446 CV_ERROR( CV_StsBadArg, "Unrecognized or unsupported array type" );
449 CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );
451 matnd->data.ptr = mat->data.ptr;
453 matnd->hdr_refcount = 0;
454 matnd->type = mat->type;
456 matnd->dim[0].size = mat->rows;
457 matnd->dim[0].step = mat->step;
458 matnd->dim[1].size = mat->cols;
459 matnd->dim[1].step = CV_ELEM_SIZE(mat->type);
469 // returns number of dimensions to iterate.
471 Checks whether <count> arrays have equal type, sizes (mask is optional array
472 that needs to have the same size, but 8uC1 or 8sC1 type).
473 Returns number of dimensions to iterate through:
474 0 means that all arrays are continuous,
475 1 means that all arrays are vectors of continuous arrays etc.
476 and the size of largest common continuous part of the arrays
479 cvInitNArrayIterator( int count, CvArr** arrs,
480 const CvArr* mask, CvMatND* stubs,
481 CvNArrayIterator* iterator, int flags )
485 CV_FUNCNAME( "cvInitArrayOp" );
489 int i, j, size, dim0 = -1;
493 if( count < 1 || count > CV_MAX_ARR )
494 CV_ERROR( CV_StsOutOfRange, "Incorrect number of arrays" );
496 if( !arrs || !stubs )
497 CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );
500 CV_ERROR( CV_StsNullPtr, "Iterator pointer is NULL" );
502 for( i = 0; i <= count; i++ )
504 const CvArr* arr = i < count ? arrs[i] : mask;
510 CV_ERROR( CV_StsNullPtr, "Some of required array pointers is NULL" );
514 if( CV_IS_MATND( arr ))
519 CV_CALL( hdr = cvGetMatND( arr, stubs + i, &coi ));
521 CV_ERROR( CV_BadCOI, "COI set is not allowed here" );
524 iterator->hdr[i] = hdr;
528 if( hdr->dims != hdr0->dims )
529 CV_ERROR( CV_StsUnmatchedSizes,
530 "Number of dimensions is the same for all arrays" );
534 switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK))
537 if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))
538 CV_ERROR( CV_StsUnmatchedFormats,
539 "Data type is not the same for all arrays" );
541 case CV_NO_DEPTH_CHECK:
542 if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
543 CV_ERROR( CV_StsUnmatchedFormats,
544 "Number of channels is not the same for all arrays" );
547 if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
548 CV_ERROR( CV_StsUnmatchedFormats,
549 "Depth is not the same for all arrays" );
555 if( !CV_IS_MASK_ARR( hdr ))
556 CV_ERROR( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );
559 if( !(flags & CV_NO_SIZE_CHECK) )
561 for( j = 0; j < hdr->dims; j++ )
562 if( hdr->dim[j].size != hdr0->dim[j].size )
563 CV_ERROR( CV_StsUnmatchedSizes,
564 "Dimension sizes are the same for all arrays" );
570 step = CV_ELEM_SIZE(hdr->type);
571 for( j = hdr->dims - 1; j > dim0; j-- )
573 if( step != hdr->dim[j].step )
575 step *= hdr->dim[j].size;
578 if( j == dim0 && step > INT_MAX )
584 iterator->hdr[i] = (CvMatND*)hdr;
585 iterator->ptr[i] = (uchar*)hdr->data.ptr;
589 for( j = hdr0->dims - 1; j > dim0; j-- )
590 size *= hdr0->dim[j].size;
593 iterator->dims = dims;
594 iterator->count = count;
595 iterator->size = cvSize(size,1);
597 for( i = 0; i < dims; i++ )
598 iterator->stack[i] = hdr0->dim[i].size;
606 // returns zero value if iteration is finished, non-zero otherwise
607 CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator )
609 assert( iterator != 0 );
610 int i, dims, size = 0;
612 for( dims = iterator->dims; dims > 0; dims-- )
614 for( i = 0; i < iterator->count; i++ )
615 iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;
617 if( --iterator->stack[dims-1] > 0 )
620 size = iterator->hdr[0]->dim[dims-1].size;
622 for( i = 0; i < iterator->count; i++ )
623 iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;
625 iterator->stack[dims-1] = size;
632 /****************************************************************************************\
633 * CvSparseMat creation and basic operations *
634 \****************************************************************************************/
637 // Creates CvMatND and underlying data
639 cvCreateSparseMat( int dims, const int* sizes, int type )
641 CvSparseMat* arr = 0;
643 CV_FUNCNAME( "cvCreateSparseMat" );
647 type = CV_MAT_TYPE( type );
648 int pix_size1 = CV_ELEM_SIZE1(type);
649 int pix_size = pix_size1*CV_MAT_CN(type);
651 CvMemStorage* storage;
654 CV_ERROR( CV_StsUnsupportedFormat, "invalid array data type" );
656 if( dims <= 0 || dims > CV_MAX_DIM_HEAP )
657 CV_ERROR( CV_StsOutOfRange, "bad number of dimensions" );
660 CV_ERROR( CV_StsNullPtr, "NULL <sizes> pointer" );
662 for( i = 0; i < dims; i++ )
665 CV_ERROR( CV_StsBadSize, "one of dimesion sizes is non-positive" );
668 CV_CALL( arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])));
670 arr->type = CV_SPARSE_MAT_MAGIC_VAL | type;
673 arr->hdr_refcount = 1;
674 memcpy( arr->size, sizes, dims*sizeof(sizes[0]));
676 arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1);
677 arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));
678 size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));
680 CV_CALL( storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK ));
681 CV_CALL( arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ));
683 arr->hashsize = CV_SPARSE_HASH_SIZE0;
684 size = arr->hashsize*sizeof(arr->hashtable[0]);
686 CV_CALL( arr->hashtable = (void**)cvAlloc( size ));
687 memset( arr->hashtable, 0, size );
691 if( cvGetErrStatus() < 0 )
692 cvReleaseSparseMat( &arr );
698 // Creates CvMatND and underlying data
700 cvReleaseSparseMat( CvSparseMat** array )
702 CV_FUNCNAME( "cvReleaseSparseMat" );
707 CV_ERROR_FROM_CODE( CV_HeaderIsNull );
711 CvSparseMat* arr = *array;
713 if( !CV_IS_SPARSE_MAT_HDR(arr) )
714 CV_ERROR_FROM_CODE( CV_StsBadFlag );
718 cvReleaseMemStorage( &arr->heap->storage );
719 cvFree( &arr->hashtable );
727 // Creates CvMatND and underlying data
729 cvCloneSparseMat( const CvSparseMat* src )
731 CvSparseMat* dst = 0;
733 CV_FUNCNAME( "cvCloneSparseMat" );
737 if( !CV_IS_SPARSE_MAT_HDR(src) )
738 CV_ERROR( CV_StsBadArg, "Invalid sparse array header" );
740 CV_CALL( dst = cvCreateSparseMat( src->dims, src->size, src->type ));
741 CV_CALL( cvCopy( src, dst ));
745 if( cvGetErrStatus() < 0 )
746 cvReleaseSparseMat( &dst );
753 cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator )
755 CvSparseNode* node = 0;
757 CV_FUNCNAME( "cvInitSparseMatIterator" );
763 if( !CV_IS_SPARSE_MAT( mat ))
764 CV_ERROR( CV_StsBadArg, "Invalid sparse matrix header" );
767 CV_ERROR( CV_StsNullPtr, "NULL iterator pointer" );
769 iterator->mat = (CvSparseMat*)mat;
772 for( idx = 0; idx < mat->hashsize; idx++ )
773 if( mat->hashtable[idx] )
775 node = iterator->node = (CvSparseNode*)mat->hashtable[idx];
779 iterator->curidx = idx;
786 #define ICV_SPARSE_MAT_HASH_MULTIPLIER 33
789 icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
790 int create_node, unsigned* precalc_hashval )
794 CV_FUNCNAME( "icvGetNodePtr" );
799 unsigned hashval = 0;
801 assert( CV_IS_SPARSE_MAT( mat ));
803 if( !precalc_hashval )
805 for( i = 0; i < mat->dims; i++ )
808 if( (unsigned)t >= (unsigned)mat->size[i] )
809 CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );
810 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
815 hashval = *precalc_hashval;
818 tabidx = hashval & (mat->hashsize - 1);
821 for( node = (CvSparseNode*)mat->hashtable[tabidx];
822 node != 0; node = node->next )
824 if( node->hashval == hashval )
826 int* nodeidx = CV_NODE_IDX(mat,node);
827 for( i = 0; i < mat->dims; i++ )
828 if( idx[i] != nodeidx[i] )
832 ptr = (uchar*)CV_NODE_VAL(mat,node);
838 if( !ptr && create_node )
840 if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO )
843 int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);
844 int newrawsize = newsize*sizeof(newtable[0]);
846 CvSparseMatIterator iterator;
847 assert( (newsize & (newsize - 1)) == 0 );
850 CV_CALL( newtable = (void**)cvAlloc( newrawsize ));
851 memset( newtable, 0, newrawsize );
853 node = cvInitSparseMatIterator( mat, &iterator );
856 CvSparseNode* next = cvGetNextSparseNode( &iterator );
857 int newidx = node->hashval & (newsize - 1);
858 node->next = (CvSparseNode*)newtable[newidx];
859 newtable[newidx] = node;
863 cvFree( &mat->hashtable );
864 mat->hashtable = newtable;
865 mat->hashsize = newsize;
866 tabidx = hashval & (newsize - 1);
869 node = (CvSparseNode*)cvSetNew( mat->heap );
870 node->hashval = hashval;
871 node->next = (CvSparseNode*)mat->hashtable[tabidx];
872 mat->hashtable[tabidx] = node;
873 CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );
874 ptr = (uchar*)CV_NODE_VAL(mat,node);
875 if( create_node > 0 )
876 CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(mat->type));
880 *_type = CV_MAT_TYPE(mat->type);
889 icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval )
891 CV_FUNCNAME( "icvDeleteNode" );
896 unsigned hashval = 0;
897 CvSparseNode *node, *prev = 0;
898 assert( CV_IS_SPARSE_MAT( mat ));
900 if( !precalc_hashval )
902 for( i = 0; i < mat->dims; i++ )
905 if( (unsigned)t >= (unsigned)mat->size[i] )
906 CV_ERROR( CV_StsOutOfRange, "One of indices is out of range" );
907 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
912 hashval = *precalc_hashval;
915 tabidx = hashval & (mat->hashsize - 1);
918 for( node = (CvSparseNode*)mat->hashtable[tabidx];
919 node != 0; prev = node, node = node->next )
921 if( node->hashval == hashval )
923 int* nodeidx = CV_NODE_IDX(mat,node);
924 for( i = 0; i < mat->dims; i++ )
925 if( idx[i] != nodeidx[i] )
935 prev->next = node->next;
937 mat->hashtable[tabidx] = node->next;
938 cvSetRemoveByPtr( mat->heap, node );
946 /****************************************************************************************\
947 * Common for multiple array types operations *
948 \****************************************************************************************/
950 // Allocates underlying array data
952 cvCreateData( CvArr* arr )
954 CV_FUNCNAME( "cvCreateData" );
958 if( CV_IS_MAT_HDR( arr ))
960 size_t step, total_size;
961 CvMat* mat = (CvMat*)arr;
964 if( mat->data.ptr != 0 )
965 CV_ERROR( CV_StsError, "Data is already allocated" );
968 step = CV_ELEM_SIZE(mat->type)*mat->cols;
970 total_size = step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
971 CV_CALL( mat->refcount = (int*)cvAlloc( (size_t)total_size ));
972 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
975 else if( CV_IS_IMAGE_HDR(arr))
977 IplImage* img = (IplImage*)arr;
979 if( img->imageData != 0 )
980 CV_ERROR( CV_StsError, "Data is already allocated" );
982 if( !CvIPL.allocateData )
984 CV_CALL( img->imageData = img->imageDataOrigin =
985 (char*)cvAlloc( (size_t)img->imageSize ));
989 int depth = img->depth;
990 int width = img->width;
992 if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 )
994 img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
995 img->depth = IPL_DEPTH_8U;
998 CvIPL.allocateData( img, 0, 0 );
1004 else if( CV_IS_MATND_HDR( arr ))
1006 CvMatND* mat = (CvMatND*)arr;
1008 size_t total_size = CV_ELEM_SIZE(mat->type);
1010 if( mat->data.ptr != 0 )
1011 CV_ERROR( CV_StsError, "Data is already allocated" );
1013 if( CV_IS_MAT_CONT( mat->type ))
1015 total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
1016 mat->dim[0].step : total_size);
1020 for( i = mat->dims - 1; i >= 0; i-- )
1022 size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;
1024 if( total_size < size )
1029 CV_CALL( mat->refcount = (int*)cvAlloc( total_size +
1030 sizeof(int) + CV_MALLOC_ALIGN ));
1031 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
1036 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1043 // Assigns external data to array
1045 cvSetData( CvArr* arr, void* data, int step )
1047 CV_FUNCNAME( "cvSetData" );
1051 int pix_size, min_step;
1053 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) )
1054 cvReleaseData( arr );
1056 if( CV_IS_MAT_HDR( arr ))
1058 CvMat* mat = (CvMat*)arr;
1060 int type = CV_MAT_TYPE(mat->type);
1061 pix_size = CV_ELEM_SIZE(type);
1062 min_step = mat->cols*pix_size & ((mat->rows <= 1) - 1);
1064 if( step != CV_AUTOSTEP )
1066 if( step < min_step && data != 0 )
1067 CV_ERROR_FROM_CODE( CV_BadStep );
1068 mat->step = step & ((mat->rows <= 1) - 1);
1072 mat->step = min_step;
1075 mat->data.ptr = (uchar*)data;
1076 mat->type = CV_MAT_MAGIC_VAL | type |
1077 (mat->step==min_step ? CV_MAT_CONT_FLAG : 0);
1078 icvCheckHuge( mat );
1080 else if( CV_IS_IMAGE_HDR( arr ))
1082 IplImage* img = (IplImage*)arr;
1084 pix_size = ((img->depth & 255) >> 3)*img->nChannels;
1085 min_step = img->width*pix_size;
1087 if( step != CV_AUTOSTEP && img->height > 1 )
1089 if( step < min_step && data != 0 )
1090 CV_ERROR_FROM_CODE( CV_BadStep );
1091 img->widthStep = step;
1095 img->widthStep = min_step;
1098 img->imageSize = img->widthStep * img->height;
1099 img->imageData = img->imageDataOrigin = (char*)data;
1101 if( (((int)(size_t)data | step) & 7) == 0 &&
1102 cvAlign(img->width * pix_size, 8) == step )
1111 else if( CV_IS_MATND_HDR( arr ))
1113 CvMatND* mat = (CvMatND*)arr;
1117 if( step != CV_AUTOSTEP )
1118 CV_ERROR( CV_BadStep,
1119 "For multidimensional array only CV_AUTOSTEP is allowed here" );
1121 mat->data.ptr = (uchar*)data;
1122 cur_step = CV_ELEM_SIZE(mat->type);
1124 for( i = mat->dims - 1; i >= 0; i-- )
1126 if( cur_step > INT_MAX )
1127 CV_ERROR( CV_StsOutOfRange, "The array is too big" );
1128 mat->dim[i].step = (int)cur_step;
1129 cur_step *= mat->dim[i].size;
1134 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->imageDataOrigin;
1161 img->imageData = img->imageDataOrigin = 0;
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;
1276 type = CV_MAKETYPE( icvIplToCvDepth(img->depth), img->nChannels );
1279 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1287 // Returns a number of array dimensions
1289 cvGetDims( const CvArr* arr, int* sizes )
1292 CV_FUNCNAME( "cvGetDims" );
1296 if( CV_IS_MAT_HDR( arr ))
1298 CvMat* mat = (CvMat*)arr;
1303 sizes[0] = mat->rows;
1304 sizes[1] = mat->cols;
1307 else if( CV_IS_IMAGE( arr ))
1309 IplImage* img = (IplImage*)arr;
1314 sizes[0] = img->height;
1315 sizes[1] = img->width;
1318 else if( CV_IS_MATND_HDR( arr ))
1320 CvMatND* mat = (CvMatND*)arr;
1326 for( i = 0; i < dims; i++ )
1327 sizes[i] = mat->dim[i].size;
1330 else if( CV_IS_SPARSE_MAT_HDR( arr ))
1332 CvSparseMat* mat = (CvSparseMat*)arr;
1336 memcpy( sizes, mat->size, dims*sizeof(sizes[0]));
1340 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1349 // Returns the size of particular array dimension
1351 cvGetDimSize( const CvArr* arr, int index )
1354 CV_FUNCNAME( "cvGetDimSize" );
1358 if( CV_IS_MAT( arr ))
1360 CvMat *mat = (CvMat*)arr;
1371 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1374 else if( CV_IS_IMAGE( arr ))
1376 IplImage* img = (IplImage*)arr;
1381 size = !img->roi ? img->height : img->roi->height;
1384 size = !img->roi ? img->width : img->roi->width;
1387 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1390 else if( CV_IS_MATND_HDR( arr ))
1392 CvMatND* mat = (CvMatND*)arr;
1394 if( (unsigned)index >= (unsigned)mat->dims )
1395 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1397 size = mat->dim[index].size;
1399 else if( CV_IS_SPARSE_MAT_HDR( arr ))
1401 CvSparseMat* mat = (CvSparseMat*)arr;
1403 if( (unsigned)index >= (unsigned)mat->dims )
1404 CV_ERROR( CV_StsOutOfRange, "bad dimension index" );
1406 size = mat->size[index];
1410 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
1419 // Returns the size of CvMat or IplImage
1421 cvGetSize( const CvArr* arr )
1423 CvSize size = { 0, 0 };
1425 CV_FUNCNAME( "cvGetSize" );
1429 if( CV_IS_MAT_HDR( arr ))
1431 CvMat *mat = (CvMat*)arr;
1433 size.width = mat->cols;
1434 size.height = mat->rows;
1436 else if( CV_IS_IMAGE_HDR( arr ))
1438 IplImage* img = (IplImage*)arr;
1442 size.width = img->roi->width;
1443 size.height = img->roi->height;
1447 size.width = img->width;
1448 size.height = img->height;
1453 CV_ERROR( CV_StsBadArg, "Array should be CvMat or IplImage" );
1462 // Selects sub-array (no data is copied)
1464 cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
1468 CV_FUNCNAME( "cvGetRect" );
1472 CvMat stub, *mat = (CvMat*)arr;
1474 if( !CV_IS_MAT( mat ))
1475 CV_CALL( mat = cvGetMat( mat, &stub ));
1478 CV_ERROR( CV_StsNullPtr, "" );
1480 if( (rect.x|rect.y|rect.width|rect.height) < 0 )
1481 CV_ERROR( CV_StsBadSize, "" );
1483 if( rect.x + rect.width > mat->cols ||
1484 rect.y + rect.height > mat->rows )
1485 CV_ERROR( CV_StsBadSize, "" );
1489 int* refcount = mat->refcount;
1494 cvDecRefData( submat );
1496 submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
1497 rect.x*CV_ELEM_SIZE(mat->type);
1498 submat->step = mat->step & (rect.height > 1 ? -1 : 0);
1499 submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
1500 (submat->step == 0 ? CV_MAT_CONT_FLAG : 0);
1501 submat->rows = rect.height;
1502 submat->cols = rect.width;
1503 submat->refcount = 0;
1513 // Selects array's row span.
1515 cvGetRows( const CvArr* arr, CvMat* submat,
1516 int start_row, int end_row, int delta_row )
1520 CV_FUNCNAME( "cvGetRows" );
1524 CvMat stub, *mat = (CvMat*)arr;
1526 if( !CV_IS_MAT( mat ))
1527 CV_CALL( mat = cvGetMat( mat, &stub ));
1530 CV_ERROR( CV_StsNullPtr, "" );
1532 if( (unsigned)start_row >= (unsigned)mat->rows ||
1533 (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 )
1534 CV_ERROR( CV_StsOutOfRange, "" );
1538 int* refcount = mat->refcount;
1543 cvDecRefData( submat );
1545 if( delta_row == 1 )
1547 submat->rows = end_row - start_row;
1548 submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
1552 submat->rows = (end_row - start_row + delta_row - 1)/delta_row;
1553 submat->step = mat->step * delta_row;
1556 submat->cols = mat->cols;
1557 submat->step &= submat->rows > 1 ? -1 : 0;
1558 submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
1559 submat->type = (mat->type | (submat->step == 0 ? CV_MAT_CONT_FLAG : 0)) &
1560 (delta_row != 1 ? ~CV_MAT_CONT_FLAG : -1);
1561 submat->refcount = 0;
1562 submat->hdr_refcount = 0;
1572 // Selects array's column span.
1574 cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col )
1578 CV_FUNCNAME( "cvGetCols" );
1582 CvMat stub, *mat = (CvMat*)arr;
1585 if( !CV_IS_MAT( mat ))
1586 CV_CALL( mat = cvGetMat( mat, &stub ));
1589 CV_ERROR( CV_StsNullPtr, "" );
1592 if( (unsigned)start_col >= (unsigned)cols ||
1593 (unsigned)end_col > (unsigned)cols )
1594 CV_ERROR( CV_StsOutOfRange, "" );
1598 int* refcount = mat->refcount;
1603 cvDecRefData( submat );
1605 submat->rows = mat->rows;
1606 submat->cols = end_col - start_col;
1607 submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
1608 submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type);
1609 submat->type = mat->type & (submat->step && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
1610 submat->refcount = 0;
1611 submat->hdr_refcount = 0;
1621 // Selects array diagonal
1623 cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
1627 CV_FUNCNAME( "cvGetDiag" );
1631 CvMat stub, *mat = (CvMat*)arr;
1634 if( !CV_IS_MAT( mat ))
1635 CV_CALL( mat = cvGetMat( mat, &stub ));
1638 CV_ERROR( CV_StsNullPtr, "" );
1640 pix_size = CV_ELEM_SIZE(mat->type);
1643 int* refcount = mat->refcount;
1648 cvDecRefData( submat );
1653 len = mat->cols - diag;
1656 CV_ERROR( CV_StsOutOfRange, "" );
1658 len = CV_IMIN( len, mat->rows );
1659 submat->data.ptr = mat->data.ptr + diag*pix_size;
1663 len = mat->rows + diag;
1666 CV_ERROR( CV_StsOutOfRange, "" );
1668 len = CV_IMIN( len, mat->cols );
1669 submat->data.ptr = mat->data.ptr - diag*mat->step;
1674 submat->step = (mat->step + pix_size) & (submat->rows > 1 ? -1 : 0);
1675 submat->type = mat->type;
1677 submat->type &= ~CV_MAT_CONT_FLAG;
1679 submat->type |= CV_MAT_CONT_FLAG;
1680 submat->refcount = 0;
1681 submat->hdr_refcount = 0;
1690 /****************************************************************************************\
1691 * Operations on CvScalar and accessing array elements *
1692 \****************************************************************************************/
1694 // Converts CvScalar to specified type
1696 cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 )
1698 CV_FUNCNAME( "cvScalarToRawData" );
1700 type = CV_MAT_TYPE(type);
1704 int cn = CV_MAT_CN( type );
1705 int depth = type & CV_MAT_DEPTH_MASK;
1707 assert( scalar && data );
1708 if( (unsigned)(cn - 1) >= 4 )
1709 CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
1716 int t = cvRound( scalar->val[cn] );
1717 ((uchar*)data)[cn] = CV_CAST_8U(t);
1723 int t = cvRound( scalar->val[cn] );
1724 ((char*)data)[cn] = CV_CAST_8S(t);
1730 int t = cvRound( scalar->val[cn] );
1731 ((ushort*)data)[cn] = CV_CAST_16U(t);
1737 int t = cvRound( scalar->val[cn] );
1738 ((short*)data)[cn] = CV_CAST_16S(t);
1743 ((int*)data)[cn] = cvRound( scalar->val[cn] );
1747 ((float*)data)[cn] = (float)(scalar->val[cn]);
1751 ((double*)data)[cn] = (double)(scalar->val[cn]);
1755 CV_ERROR_FROM_CODE( CV_BadDepth );
1760 int pix_size = CV_ELEM_SIZE(type);
1761 int offset = CV_ELEM_SIZE1(depth)*12;
1766 CV_MEMCPY_AUTO( (char*)data + offset, data, pix_size );
1768 while( offset > pix_size );
1775 // Converts data of specified type to CvScalar
1777 cvRawDataToScalar( const void* data, int flags, CvScalar* scalar )
1779 CV_FUNCNAME( "cvRawDataToScalar" );
1783 int cn = CV_MAT_CN( flags );
1785 assert( scalar && data );
1787 if( (unsigned)(cn - 1) >= 4 )
1788 CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
1790 memset( scalar->val, 0, sizeof(scalar->val));
1792 switch( CV_MAT_DEPTH( flags ))
1796 scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]);
1800 scalar->val[cn] = CV_8TO32F(((char*)data)[cn]);
1804 scalar->val[cn] = ((ushort*)data)[cn];
1808 scalar->val[cn] = ((short*)data)[cn];
1812 scalar->val[cn] = ((int*)data)[cn];
1816 scalar->val[cn] = ((float*)data)[cn];
1820 scalar->val[cn] = ((double*)data)[cn];
1824 CV_ERROR_FROM_CODE( CV_BadDepth );
1831 static double icvGetReal( const void* data, int type )
1836 return *(uchar*)data;
1838 return *(char*)data;
1840 return *(ushort*)data;
1842 return *(short*)data;
1846 return *(float*)data;
1848 return *(double*)data;
1855 static void icvSetReal( double value, const void* data, int type )
1859 int ivalue = cvRound(value);
1863 *(uchar*)data = CV_CAST_8U(ivalue);
1866 *(char*)data = CV_CAST_8S(ivalue);
1869 *(ushort*)data = CV_CAST_16U(ivalue);
1872 *(short*)data = CV_CAST_16S(ivalue);
1875 *(int*)data = CV_CAST_32S(ivalue);
1884 *(float*)data = (float)value;
1887 *(double*)data = value;
1894 // Returns pointer to specified element of array (linear index is used)
1896 cvPtr1D( const CvArr* arr, int idx, int* _type )
1900 CV_FUNCNAME( "cvPtr1D" );
1904 if( CV_IS_MAT( arr ))
1906 CvMat* mat = (CvMat*)arr;
1908 int type = CV_MAT_TYPE(mat->type);
1909 int pix_size = CV_ELEM_SIZE(type);
1914 // the first part is mul-free sufficient check
1915 // that the index is within the matrix
1916 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
1917 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
1918 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
1920 if( CV_IS_MAT_CONT(mat->type))
1922 ptr = mat->data.ptr + (size_t)idx*pix_size;
1927 if( mat->cols == 1 )
1930 row = idx/mat->cols, col = idx - row*mat->cols;
1931 ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size;
1934 else if( CV_IS_IMAGE_HDR( arr ))
1936 IplImage* img = (IplImage*)arr;
1937 int width = !img->roi ? img->width : img->roi->width;
1938 int y = idx/width, x = idx - y*width;
1940 ptr = cvPtr2D( arr, y, x, _type );
1942 else if( CV_IS_MATND( arr ))
1944 CvMatND* mat = (CvMatND*)arr;
1945 int j, type = CV_MAT_TYPE(mat->type);
1946 size_t size = mat->dim[0].size;
1951 for( j = 1; j < mat->dims; j++ )
1952 size *= mat->dim[j].size;
1954 if((unsigned)idx >= (unsigned)size )
1955 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
1957 if( CV_IS_MAT_CONT(mat->type))
1959 int pix_size = CV_ELEM_SIZE(type);
1960 ptr = mat->data.ptr + (size_t)idx*pix_size;
1964 ptr = mat->data.ptr;
1965 for( j = mat->dims - 1; j >= 0; j-- )
1967 int sz = mat->dim[j].size;
1971 ptr += (idx - t*sz)*mat->dim[j].step;
1977 else if( CV_IS_SPARSE_MAT( arr ))
1979 CvSparseMat* m = (CvSparseMat*)arr;
1981 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 );
1985 int* _idx = (int*)cvStackAlloc(n*sizeof(_idx[0]));
1987 for( i = n - 1; i >= 0; i-- )
1989 int t = idx / m->size[i];
1990 _idx[i] = idx - t*m->size[i];
1993 ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 );
1998 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2007 // Returns pointer to specified element of 2d array
2009 cvPtr2D( const CvArr* arr, int y, int x, int* _type )
2013 CV_FUNCNAME( "cvPtr2D" );
2017 if( CV_IS_MAT( arr ))
2019 CvMat* mat = (CvMat*)arr;
2022 if( (unsigned)y >= (unsigned)(mat->rows) ||
2023 (unsigned)x >= (unsigned)(mat->cols) )
2024 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2026 type = CV_MAT_TYPE(mat->type);
2030 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2032 else if( CV_IS_IMAGE( arr ))
2034 IplImage* img = (IplImage*)arr;
2035 int pix_size = (img->depth & 255) >> 3;
2037 ptr = (uchar*)img->imageData;
2039 if( img->dataOrder == 0 )
2040 pix_size *= img->nChannels;
2044 width = img->roi->width;
2045 height = img->roi->height;
2047 ptr += img->roi->yOffset*img->widthStep +
2048 img->roi->xOffset*pix_size;
2050 if( img->dataOrder )
2052 int coi = img->roi->coi;
2054 CV_ERROR( CV_BadCOI,
2055 "COI must be non-null in case of planar images" );
2056 ptr += (coi - 1)*img->imageSize;
2062 height = img->height;
2065 if( (unsigned)y >= (unsigned)height ||
2066 (unsigned)x >= (unsigned)width )
2067 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2069 ptr += y*img->widthStep + x*pix_size;
2073 int type = icvIplToCvDepth(img->depth);
2074 if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
2075 CV_ERROR( CV_StsUnsupportedFormat, "" );
2077 *_type = CV_MAKETYPE( type, img->nChannels );
2080 else if( CV_IS_MATND( arr ))
2082 CvMatND* mat = (CvMatND*)arr;
2084 if( mat->dims != 2 ||
2085 (unsigned)y >= (unsigned)(mat->dim[0].size) ||
2086 (unsigned)x >= (unsigned)(mat->dim[1].size) )
2087 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2089 ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step;
2091 *_type = CV_MAT_TYPE(mat->type);
2093 else if( CV_IS_SPARSE_MAT( arr ))
2095 int idx[] = { y, x };
2096 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
2100 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2109 // Returns pointer to specified element of 3d array
2111 cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type )
2115 CV_FUNCNAME( "cvPtr3D" );
2119 if( CV_IS_MATND( arr ))
2121 CvMatND* mat = (CvMatND*)arr;
2123 if( mat->dims != 3 ||
2124 (unsigned)z >= (unsigned)(mat->dim[0].size) ||
2125 (unsigned)y >= (unsigned)(mat->dim[1].size) ||
2126 (unsigned)x >= (unsigned)(mat->dim[2].size) )
2127 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2129 ptr = mat->data.ptr + (size_t)z*mat->dim[0].step +
2130 (size_t)y*mat->dim[1].step + x*mat->dim[2].step;
2133 *_type = CV_MAT_TYPE(mat->type);
2135 else if( CV_IS_SPARSE_MAT( arr ))
2137 int idx[] = { z, y, x };
2138 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
2142 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2151 // Returns pointer to specified element of n-d array
2153 cvPtrND( const CvArr* arr, const int* idx, int* _type,
2154 int create_node, unsigned* precalc_hashval )
2157 CV_FUNCNAME( "cvPtrND" );
2162 CV_ERROR( CV_StsNullPtr, "NULL pointer to indices" );
2164 if( CV_IS_SPARSE_MAT( arr ))
2165 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx,
2166 _type, create_node, precalc_hashval );
2167 else if( CV_IS_MATND( arr ))
2169 CvMatND* mat = (CvMatND*)arr;
2171 ptr = mat->data.ptr;
2173 for( i = 0; i < mat->dims; i++ )
2175 if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) )
2176 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2177 ptr += (size_t)idx[i]*mat->dim[i].step;
2181 *_type = CV_MAT_TYPE(mat->type);
2183 else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) )
2184 ptr = cvPtr2D( arr, idx[0], idx[1], _type );
2186 CV_ERROR( CV_StsBadArg, "unrecognized or unsupported array type" );
2194 // Returns specifed element of n-D array given linear index
2196 cvGet1D( const CvArr* arr, int idx )
2198 CvScalar scalar = {{0,0,0,0}};
2200 CV_FUNCNAME( "cvGet1D" );
2207 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2209 CvMat* mat = (CvMat*)arr;
2211 type = CV_MAT_TYPE(mat->type);
2212 int pix_size = CV_ELEM_SIZE(type);
2214 // the first part is mul-free sufficient check
2215 // that the index is within the matrix
2216 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2217 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2218 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2220 ptr = mat->data.ptr + (size_t)idx*pix_size;
2222 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2223 ptr = cvPtr1D( arr, idx, &type );
2225 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
2227 cvRawDataToScalar( ptr, type, &scalar );
2235 // Returns specifed element of 2D array
2237 cvGet2D( const CvArr* arr, int y, int x )
2239 CvScalar scalar = {{0,0,0,0}};
2241 CV_FUNCNAME( "cvGet2D" );
2248 if( CV_IS_MAT( arr ))
2250 CvMat* mat = (CvMat*)arr;
2252 if( (unsigned)y >= (unsigned)(mat->rows) ||
2253 (unsigned)x >= (unsigned)(mat->cols) )
2254 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2256 type = CV_MAT_TYPE(mat->type);
2257 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2259 else if( !CV_IS_SPARSE_MAT( arr ))
2260 ptr = cvPtr2D( arr, y, x, &type );
2263 int idx[] = { y, x };
2264 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2267 cvRawDataToScalar( ptr, type, &scalar );
2275 // Returns specifed element of 3D array
2277 cvGet3D( const CvArr* arr, int z, int y, int x )
2279 CvScalar scalar = {{0,0,0,0}};
2281 /*CV_FUNCNAME( "cvGet3D" );*/
2288 if( !CV_IS_SPARSE_MAT( arr ))
2289 ptr = cvPtr3D( arr, z, y, x, &type );
2292 int idx[] = { z, y, x };
2293 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2296 cvRawDataToScalar( ptr, type, &scalar );
2304 // Returns specifed element of nD array
2306 cvGetND( const CvArr* arr, const int* idx )
2308 CvScalar scalar = {{0,0,0,0}};
2310 /*CV_FUNCNAME( "cvGetND" );*/
2317 if( !CV_IS_SPARSE_MAT( arr ))
2318 ptr = cvPtrND( arr, idx, &type );
2320 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2322 cvRawDataToScalar( ptr, type, &scalar );
2330 // Returns specifed element of n-D array given linear index
2332 cvGetReal1D( const CvArr* arr, int idx )
2336 CV_FUNCNAME( "cvGetReal1D" );
2343 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2345 CvMat* mat = (CvMat*)arr;
2347 type = CV_MAT_TYPE(mat->type);
2348 int pix_size = CV_ELEM_SIZE(type);
2350 // the first part is mul-free sufficient check
2351 // that the index is within the matrix
2352 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2353 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2354 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2356 ptr = mat->data.ptr + (size_t)idx*pix_size;
2358 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2359 ptr = cvPtr1D( arr, idx, &type );
2361 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
2365 if( CV_MAT_CN( type ) > 1 )
2366 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2368 value = icvGetReal( ptr, type );
2377 // Returns specifed element of 2D array
2379 cvGetReal2D( const CvArr* arr, int y, int x )
2383 CV_FUNCNAME( "cvGetReal2D" );
2390 if( CV_IS_MAT( arr ))
2392 CvMat* mat = (CvMat*)arr;
2394 if( (unsigned)y >= (unsigned)(mat->rows) ||
2395 (unsigned)x >= (unsigned)(mat->cols) )
2396 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2398 type = CV_MAT_TYPE(mat->type);
2399 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2401 else if( !CV_IS_SPARSE_MAT( arr ))
2402 ptr = cvPtr2D( arr, y, x, &type );
2405 int idx[] = { y, x };
2406 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2411 if( CV_MAT_CN( type ) > 1 )
2412 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2414 value = icvGetReal( ptr, type );
2423 // Returns specifed element of 3D array
2425 cvGetReal3D( const CvArr* arr, int z, int y, int x )
2429 CV_FUNCNAME( "cvGetReal3D" );
2436 if( !CV_IS_SPARSE_MAT( arr ))
2437 ptr = cvPtr3D( arr, z, y, x, &type );
2440 int idx[] = { z, y, x };
2441 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2446 if( CV_MAT_CN( type ) > 1 )
2447 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2449 value = icvGetReal( ptr, type );
2458 // Returns specifed element of nD array
2460 cvGetRealND( const CvArr* arr, const int* idx )
2464 CV_FUNCNAME( "cvGetRealND" );
2471 if( !CV_IS_SPARSE_MAT( arr ))
2472 ptr = cvPtrND( arr, idx, &type );
2474 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2478 if( CV_MAT_CN( type ) > 1 )
2479 CV_ERROR( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2481 value = icvGetReal( ptr, type );
2490 // Assigns new value to specifed element of nD array given linear index
2492 cvSet1D( CvArr* arr, int idx, CvScalar scalar )
2494 CV_FUNCNAME( "cvSet1D" );
2501 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2503 CvMat* mat = (CvMat*)arr;
2505 type = CV_MAT_TYPE(mat->type);
2506 int pix_size = CV_ELEM_SIZE(type);
2508 // the first part is mul-free sufficient check
2509 // that the index is within the matrix
2510 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2511 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2512 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2514 ptr = mat->data.ptr + (size_t)idx*pix_size;
2516 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2517 ptr = cvPtr1D( arr, idx, &type );
2519 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2521 cvScalarToRawData( &scalar, ptr, type );
2527 // Assigns new value to specifed element of 2D array
2529 cvSet2D( CvArr* arr, int y, int x, CvScalar scalar )
2531 CV_FUNCNAME( "cvSet2D" );
2538 if( CV_IS_MAT( arr ))
2540 CvMat* mat = (CvMat*)arr;
2542 if( (unsigned)y >= (unsigned)(mat->rows) ||
2543 (unsigned)x >= (unsigned)(mat->cols) )
2544 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2546 type = CV_MAT_TYPE(mat->type);
2547 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2549 else if( !CV_IS_SPARSE_MAT( arr ))
2550 ptr = cvPtr2D( arr, y, x, &type );
2553 int idx[] = { y, x };
2554 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2556 cvScalarToRawData( &scalar, ptr, type );
2562 // Assigns new value to specifed element of 3D array
2564 cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar )
2566 /*CV_FUNCNAME( "cvSet3D" );*/
2573 if( !CV_IS_SPARSE_MAT( arr ))
2574 ptr = cvPtr3D( arr, z, y, x, &type );
2577 int idx[] = { z, y, x };
2578 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2580 cvScalarToRawData( &scalar, ptr, type );
2586 // Assigns new value to specifed element of nD array
2588 cvSetND( CvArr* arr, const int* idx, CvScalar scalar )
2590 /*CV_FUNCNAME( "cvSetND" );*/
2597 if( !CV_IS_SPARSE_MAT( arr ))
2598 ptr = cvPtrND( arr, idx, &type );
2600 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2601 cvScalarToRawData( &scalar, ptr, type );
2608 cvSetReal1D( CvArr* arr, int idx, double value )
2610 CV_FUNCNAME( "cvSetReal1D" );
2617 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2619 CvMat* mat = (CvMat*)arr;
2621 type = CV_MAT_TYPE(mat->type);
2622 int pix_size = CV_ELEM_SIZE(type);
2624 // the first part is mul-free sufficient check
2625 // that the index is within the matrix
2626 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2627 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2628 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2630 ptr = mat->data.ptr + (size_t)idx*pix_size;
2632 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2633 ptr = cvPtr1D( arr, idx, &type );
2635 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2637 if( CV_MAT_CN( type ) > 1 )
2638 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2641 icvSetReal( value, ptr, type );
2648 cvSetReal2D( CvArr* arr, int y, int x, double value )
2650 CV_FUNCNAME( "cvSetReal2D" );
2657 if( CV_IS_MAT( arr ))
2659 CvMat* mat = (CvMat*)arr;
2661 if( (unsigned)y >= (unsigned)(mat->rows) ||
2662 (unsigned)x >= (unsigned)(mat->cols) )
2663 CV_ERROR( CV_StsOutOfRange, "index is out of range" );
2665 type = CV_MAT_TYPE(mat->type);
2666 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2668 else if( !CV_IS_SPARSE_MAT( arr ))
2670 ptr = cvPtr2D( arr, y, x, &type );
2674 int idx[] = { y, x };
2675 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2677 if( CV_MAT_CN( type ) > 1 )
2678 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2681 icvSetReal( value, ptr, type );
2688 cvSetReal3D( CvArr* arr, int z, int y, int x, double value )
2690 CV_FUNCNAME( "cvSetReal3D" );
2697 if( !CV_IS_SPARSE_MAT( arr ))
2698 ptr = cvPtr3D( arr, z, y, x, &type );
2701 int idx[] = { z, y, x };
2702 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2704 if( CV_MAT_CN( type ) > 1 )
2705 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2708 icvSetReal( value, ptr, type );
2715 cvSetRealND( CvArr* arr, const int* idx, double value )
2717 CV_FUNCNAME( "cvSetRealND" );
2724 if( !CV_IS_SPARSE_MAT( arr ))
2725 ptr = cvPtrND( arr, idx, &type );
2727 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2729 if( CV_MAT_CN( type ) > 1 )
2730 CV_ERROR( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2733 icvSetReal( value, ptr, type );
2740 cvClearND( CvArr* arr, const int* idx )
2742 /*CV_FUNCNAME( "cvClearND" );*/
2746 if( !CV_IS_SPARSE_MAT( arr ))
2750 ptr = cvPtrND( arr, idx, &type );
2752 CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(type) );
2756 icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
2763 /****************************************************************************************\
2764 * Conversion to CvMat or IplImage *
2765 \****************************************************************************************/
2767 // convert array (CvMat or IplImage) to CvMat
2769 cvGetMat( const CvArr* array, CvMat* mat,
2770 int* pCOI, int allowND )
2773 CvMat* src = (CvMat*)array;
2776 CV_FUNCNAME( "cvGetMat" );
2781 CV_ERROR( CV_StsNullPtr, "NULL array pointer is passed" );
2783 if( CV_IS_MAT_HDR(src))
2785 if( !src->data.ptr )
2786 CV_ERROR( CV_StsNullPtr, "The matrix has NULL data pointer" );
2788 result = (CvMat*)src;
2790 else if( CV_IS_IMAGE_HDR(src) )
2792 const IplImage* img = (const IplImage*)src;
2795 if( img->imageData == 0 )
2796 CV_ERROR( CV_StsNullPtr, "The image has NULL data pointer" );
2798 depth = icvIplToCvDepth( img->depth );
2800 CV_ERROR_FROM_CODE( CV_BadDepth );
2802 order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
2806 if( order == IPL_DATA_ORDER_PLANE )
2810 if( img->roi->coi == 0 )
2811 CV_ERROR( CV_StsBadFlag,
2812 "Images with planar data layout should be used with COI selected" );
2814 CV_CALL( cvInitMatHeader( mat, img->roi->height,
2815 img->roi->width, type,
2816 img->imageData + (img->roi->coi-1)*img->imageSize +
2817 img->roi->yOffset*img->widthStep +
2818 img->roi->xOffset*CV_ELEM_SIZE(type),
2821 else /* pixel order */
2823 int type = CV_MAKETYPE( depth, img->nChannels );
2824 coi = img->roi->coi;
2826 if( img->nChannels > CV_CN_MAX )
2827 CV_ERROR( CV_BadNumChannels,
2828 "The image is interleaved and has over CV_CN_MAX channels" );
2830 CV_CALL( cvInitMatHeader( mat, img->roi->height, img->roi->width,
2831 type, img->imageData +
2832 img->roi->yOffset*img->widthStep +
2833 img->roi->xOffset*CV_ELEM_SIZE(type),
2839 int type = CV_MAKETYPE( depth, img->nChannels );
2841 if( order != IPL_DATA_ORDER_PIXEL )
2842 CV_ERROR( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
2844 CV_CALL( cvInitMatHeader( mat, img->height, img->width, type,
2845 img->imageData, img->widthStep ));
2850 else if( allowND && CV_IS_MATND_HDR(src) )
2852 CvMatND* matnd = (CvMatND*)src;
2854 int size1 = matnd->dim[0].size, size2 = 1;
2856 if( !src->data.ptr )
2857 CV_ERROR( CV_StsNullPtr, "Input array has NULL data pointer" );
2859 if( !CV_IS_MAT_CONT( matnd->type ))
2860 CV_ERROR( CV_StsBadArg, "Only continuous nD arrays are supported here" );
2862 if( matnd->dims > 2 )
2863 for( i = 1; i < matnd->dims; i++ )
2864 size2 *= matnd->dim[i].size;
2866 size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
2869 mat->hdr_refcount = 0;
2870 mat->data.ptr = matnd->data.ptr;
2873 mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
2874 mat->step = size2*CV_ELEM_SIZE(matnd->type);
2875 mat->step &= size1 > 1 ? -1 : 0;
2877 icvCheckHuge( mat );
2882 CV_ERROR( CV_StsBadFlag, "Unrecognized or unsupported array type" );
2895 cvReshapeMatND( const CvArr* arr,
2896 int sizeof_header, CvArr* _header,
2897 int new_cn, int new_dims, int* new_sizes )
2900 CV_FUNCNAME( "cvReshapeMatND" );
2906 if( !arr || !_header )
2907 CV_ERROR( CV_StsNullPtr, "NULL pointer to array or destination header" );
2909 if( new_cn == 0 && new_dims == 0 )
2910 CV_ERROR( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
2912 CV_CALL( dims = cvGetDims( arr ));
2919 else if( new_dims == 1 )
2925 if( new_dims <= 0 || new_dims > CV_MAX_DIM )
2926 CV_ERROR( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
2928 CV_ERROR( CV_StsNullPtr, "New dimension sizes are not specified" );
2933 CvMat* mat = (CvMat*)arr;
2934 CvMat* header = (CvMat*)_header;
2936 int hdr_refcount = 0;
2937 int total_width, new_rows, cn;
2939 if( sizeof_header != sizeof(CvMat))
2940 CV_ERROR( CV_StsBadArg, "The header should be CvMat" );
2944 refcount = mat->refcount;
2945 hdr_refcount = mat->hdr_refcount;
2947 else if( !CV_IS_MAT( mat ))
2948 CV_CALL( mat = cvGetMat( mat, header, &coi, 1 ));
2950 cn = CV_MAT_CN( mat->type );
2951 total_width = mat->cols * cn;
2957 new_rows = new_sizes[0];
2958 else if( new_dims == 1 )
2959 new_rows = total_width*mat->rows/new_cn;
2962 new_rows = mat->rows;
2963 if( new_cn > total_width )
2964 new_rows = mat->rows * total_width / new_cn;
2967 if( new_rows != mat->rows )
2969 int total_size = total_width * mat->rows;
2971 if( !CV_IS_MAT_CONT( mat->type ))
2972 CV_ERROR( CV_BadStep,
2973 "The matrix is not continuous so the number of rows can not be changed" );
2975 total_width = total_size / new_rows;
2977 if( total_width * new_rows != total_size )
2978 CV_ERROR( CV_StsBadArg, "The total number of matrix elements "
2979 "is not divisible by the new number of rows" );
2982 header->rows = new_rows;
2983 header->cols = total_width / new_cn;
2985 if( header->cols * new_cn != total_width ||
2986 new_sizes && header->cols != new_sizes[1] )
2987 CV_ERROR( CV_StsBadArg, "The total matrix width is not "
2988 "divisible by the new number of columns" );
2990 header->type = CV_MAKETYPE( mat->type & ~CV_MAT_CN_MASK, new_cn );
2991 header->step = header->cols * CV_ELEM_SIZE(mat->type);
2992 header->step &= new_rows > 1 ? -1 : 0;
2993 header->refcount = refcount;
2994 header->hdr_refcount = hdr_refcount;
2998 CvMatND* header = (CvMatND*)_header;
3000 if( sizeof_header != sizeof(CvMatND))
3001 CV_ERROR( CV_StsBadSize, "The header should be CvMatND" );
3005 if( !CV_IS_MATND( arr ))
3006 CV_ERROR( CV_StsBadArg, "The source array must be CvMatND" );
3009 CvMatND* mat = (CvMatND*)arr;
3010 assert( new_cn > 0 );
3011 int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
3012 int new_size = last_dim_size/new_cn;
3014 if( new_size*new_cn != last_dim_size )
3015 CV_ERROR( CV_StsBadArg,
3016 "The last dimension full size is not divisible by new number of channels");
3020 memcpy( header, mat, sizeof(*header));
3021 header->refcount = 0;
3022 header->hdr_refcount = 0;
3025 header->dim[header->dims-1].size = new_size;
3026 header->type = CV_MAKETYPE( header->type & ~CV_MAT_CN_MASK, new_cn );
3032 CvMatND* mat = (CvMatND*)arr;
3033 int i, size1, size2;
3037 CV_ERROR( CV_StsBadArg,
3038 "Simultaneous change of shape and number of channels is not supported. "
3039 "Do it by 2 separate calls" );
3041 if( !CV_IS_MATND( mat ))
3043 CV_CALL( cvGetMatND( mat, &stub, &coi ));
3047 if( CV_IS_MAT_CONT( mat->type ))
3048 CV_ERROR( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
3050 size1 = mat->dim[0].size;
3051 for( i = 1; i < dims; i++ )
3052 size1 *= mat->dim[i].size;
3055 for( i = 0; i < new_dims; i++ )
3057 if( new_sizes[i] <= 0 )
3058 CV_ERROR( CV_StsBadSize,
3059 "One of new dimension sizes is non-positive" );
3060 size2 *= new_sizes[i];
3063 if( size1 != size2 )
3064 CV_ERROR( CV_StsBadSize,
3065 "Number of elements in the original and reshaped array is different" );
3069 header->refcount = 0;
3070 header->hdr_refcount = 0;
3073 header->dims = new_dims;
3074 header->type = mat->type;
3075 header->data.ptr = mat->data.ptr;
3076 step = CV_ELEM_SIZE(header->type);
3078 for( i = new_dims - 1; i >= 0; i-- )
3080 header->dim[i].size = new_sizes[i];
3081 header->dim[i].step = step;
3082 step *= new_sizes[i];
3088 CV_ERROR( CV_BadCOI, "COI is not supported by this operation" );
3099 cvReshape( const CvArr* array, CvMat* header,
3100 int new_cn, int new_rows )
3103 CV_FUNCNAME( "cvReshape" );
3107 CvMat *mat = (CvMat*)array;
3108 int total_width, new_width;
3111 CV_ERROR( CV_StsNullPtr, "" );
3113 if( !CV_IS_MAT( mat ))
3116 CV_CALL( mat = cvGetMat( mat, header, &coi, 1 ));
3118 CV_ERROR( CV_BadCOI, "COI is not supported" );
3122 new_cn = CV_MAT_CN(mat->type);
3123 else if( (unsigned)(new_cn - 1) > 3 )
3124 CV_ERROR( CV_BadNumChannels, "" );
3128 int hdr_refcount = header->hdr_refcount;
3130 header->refcount = 0;
3131 header->hdr_refcount = hdr_refcount;
3134 total_width = mat->cols * CV_MAT_CN( mat->type );
3136 if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
3137 new_rows = mat->rows * total_width / new_cn;
3139 if( new_rows == 0 || new_rows == mat->rows )
3141 header->rows = mat->rows;
3142 header->step = mat->step;
3146 int total_size = total_width * mat->rows;
3147 if( !CV_IS_MAT_CONT( mat->type ))
3148 CV_ERROR( CV_BadStep,
3149 "The matrix is not continuous, thus its number of rows can not be changed" );
3151 if( (unsigned)new_rows > (unsigned)total_size )
3152 CV_ERROR( CV_StsOutOfRange, "Bad new number of rows" );
3154 total_width = total_size / new_rows;
3156 if( total_width * new_rows != total_size )
3157 CV_ERROR( CV_StsBadArg, "The total number of matrix elements "
3158 "is not divisible by the new number of rows" );
3160 header->rows = new_rows;
3161 header->step = total_width * CV_ELEM_SIZE1(mat->type);
3164 new_width = total_width / new_cn;
3166 if( new_width * new_cn != total_width )
3167 CV_ERROR( CV_BadNumChannels,
3168 "The total width is not divisible by the new number of channels" );
3170 header->cols = new_width;
3171 header->type = CV_MAKETYPE( mat->type & ~CV_MAT_CN_MASK, new_cn );
3181 // convert array (CvMat or IplImage) to IplImage
3183 cvGetImage( const CvArr* array, IplImage* img )
3185 IplImage* result = 0;
3186 const IplImage* src = (const IplImage*)array;
3188 CV_FUNCNAME( "cvGetImage" );
3195 CV_ERROR_FROM_CODE( CV_StsNullPtr );
3197 if( !CV_IS_IMAGE_HDR(src) )
3199 const CvMat* mat = (const CvMat*)src;
3201 if( !CV_IS_MAT_HDR(mat))
3202 CV_ERROR_FROM_CODE( CV_StsBadFlag );
3204 if( mat->data.ptr == 0 )
3205 CV_ERROR_FROM_CODE( CV_StsNullPtr );
3207 depth = cvCvToIplDepth(mat->type);
3209 cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
3210 depth, CV_MAT_CN(mat->type) );
3211 cvSetData( img, mat->data.ptr, mat->step );
3217 result = (IplImage*)src;
3226 /****************************************************************************************\
3227 * IplImage-specific functions *
3228 \****************************************************************************************/
3230 static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height )
3234 CV_FUNCNAME( "icvCreateROI" );
3238 if( !CvIPL.createROI )
3240 CV_CALL( roi = (IplROI*)cvAlloc( sizeof(*roi)));
3243 roi->xOffset = xOffset;
3244 roi->yOffset = yOffset;
3246 roi->height = height;
3250 roi = CvIPL.createROI( coi, xOffset, yOffset, width, height );
3259 icvGetColorModel( int nchannels, char** colorModel, char** channelSeq )
3261 static char* tab[][2] =
3270 *colorModel = *channelSeq = "";
3272 if( (unsigned)nchannels <= 3 )
3274 *colorModel = tab[nchannels][0];
3275 *channelSeq = tab[nchannels][1];
3280 // create IplImage header
3282 cvCreateImageHeader( CvSize size, int depth, int channels )
3286 CV_FUNCNAME( "cvCreateImageHeader" );
3290 if( !CvIPL.createHeader )
3292 CV_CALL( img = (IplImage *)cvAlloc( sizeof( *img )));
3293 CV_CALL( cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
3294 CV_DEFAULT_IMAGE_ROW_ALIGN ));
3301 icvGetColorModel( channels, &colorModel, &channelSeq );
3303 img = CvIPL.createHeader( channels, 0, depth, colorModel, channelSeq,
3304 IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
3305 CV_DEFAULT_IMAGE_ROW_ALIGN,
3306 size.width, size.height, 0, 0, 0, 0 );
3311 if( cvGetErrStatus() < 0 && img )
3312 cvReleaseImageHeader( &img );
3318 // create IplImage header and allocate underlying data
3320 cvCreateImage( CvSize size, int depth, int channels )
3324 CV_FUNCNAME( "cvCreateImage" );
3328 CV_CALL( img = cvCreateImageHeader( size, depth, channels ));
3330 CV_CALL( cvCreateData( img ));
3334 if( cvGetErrStatus() < 0 )
3335 cvReleaseImage( &img );
3341 // initalize IplImage header, allocated by the user
3343 cvInitImageHeader( IplImage * image, CvSize size, int depth,
3344 int channels, int origin, int align )
3346 IplImage* result = 0;
3348 CV_FUNCNAME( "cvInitImageHeader" );
3352 char *colorModel, *channelSeq;
3355 CV_ERROR( CV_HeaderIsNull, "null pointer to header" );
3357 memset( image, 0, sizeof( *image ));
3358 image->nSize = sizeof( *image );
3360 CV_CALL( icvGetColorModel( channels, &colorModel, &channelSeq ));
3361 strncpy( image->colorModel, colorModel, 4 );
3362 strncpy( image->channelSeq, channelSeq, 4 );
3364 if( size.width < 0 || size.height < 0 )
3365 CV_ERROR( CV_BadROISize, "Bad input roi" );
3367 if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U &&
3368 depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U &&
3369 depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S &&
3370 depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) ||
3372 CV_ERROR( CV_BadDepth, "Unsupported format" );
3373 if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL )
3374 CV_ERROR( CV_BadOrigin, "Bad input origin" );
3376 if( align != 4 && align != 8 )
3377 CV_ERROR( CV_BadAlign, "Bad input align" );
3379 image->width = size.width;
3380 image->height = size.height;
3384 image->roi->coi = 0;
3385 image->roi->xOffset = image->roi->yOffset = 0;
3386 image->roi->width = size.width;
3387 image->roi->height = size.height;
3390 image->nChannels = MAX( channels, 1 );
3391 image->depth = depth;
3392 image->align = align;
3393 image->widthStep = (((image->width * image->nChannels *
3394 (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));
3395 image->origin = origin;
3396 image->imageSize = image->widthStep * image->height;
3407 cvReleaseImageHeader( IplImage** image )
3409 CV_FUNCNAME( "cvReleaseImageHeader" );
3414 CV_ERROR( CV_StsNullPtr, "" );
3418 IplImage* img = *image;
3421 if( !CvIPL.deallocate )
3423 cvFree( &img->roi );
3428 CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
3436 cvReleaseImage( IplImage ** image )
3438 CV_FUNCNAME( "cvReleaseImage" );
3443 CV_ERROR( CV_StsNullPtr, "" );
3447 IplImage* img = *image;
3450 cvReleaseData( img );
3451 cvReleaseImageHeader( &img );
3459 cvSetImageROI( IplImage* image, CvRect rect )
3461 CV_FUNCNAME( "cvSetImageROI" );
3466 CV_ERROR( CV_HeaderIsNull, "" );
3468 if( rect.x > image->width || rect.y > image->height )
3469 CV_ERROR( CV_BadROISize, "" );
3471 if( rect.x + rect.width < 0 || rect.y + rect.height < 0 )
3472 CV_ERROR( CV_BadROISize, "" );
3476 rect.width += rect.x;
3482 rect.height += rect.y;
3486 if( rect.x + rect.width > image->width )
3487 rect.width = image->width - rect.x;
3489 if( rect.y + rect.height > image->height )
3490 rect.height = image->height - rect.y;
3494 image->roi->xOffset = rect.x;
3495 image->roi->yOffset = rect.y;
3496 image->roi->width = rect.width;
3497 image->roi->height = rect.height;
3501 CV_CALL( image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height ));
3509 cvResetImageROI( IplImage* image )
3511 CV_FUNCNAME( "cvResetImageROI" );
3516 CV_ERROR( CV_HeaderIsNull, "" );
3520 if( !CvIPL.deallocate )
3522 cvFree( &image->roi );
3526 CvIPL.deallocate( image, IPL_IMAGE_ROI );
3536 cvGetImageROI( const IplImage* img )
3538 CvRect rect = { 0, 0, 0, 0 };
3540 CV_FUNCNAME( "cvGetImageROI" );
3545 CV_ERROR( CV_StsNullPtr, "Null pointer to image" );
3548 rect = cvRect( img->roi->xOffset, img->roi->yOffset,
3549 img->roi->width, img->roi->height );
3551 rect = cvRect( 0, 0, img->width, img->height );
3560 cvSetImageCOI( IplImage* image, int coi )
3562 CV_FUNCNAME( "cvSetImageCOI" );
3567 CV_ERROR( CV_HeaderIsNull, "" );
3569 if( (unsigned)coi > (unsigned)(image->nChannels) )
3570 CV_ERROR( CV_BadCOI, "" );
3572 if( image->roi || coi != 0 )
3576 image->roi->coi = coi;
3580 CV_CALL( image->roi = icvCreateROI( coi, 0, 0, image->width, image->height ));
3589 cvGetImageCOI( const IplImage* image )
3592 CV_FUNCNAME( "cvGetImageCOI" );
3597 CV_ERROR( CV_HeaderIsNull, "" );
3599 coi = image->roi ? image->roi->coi : 0;
3608 cvCloneImage( const IplImage* src )
3611 CV_FUNCNAME( "cvCloneImage" );
3615 if( !CV_IS_IMAGE_HDR( src ))
3616 CV_ERROR( CV_StsBadArg, "Bad image header" );
3618 if( !CvIPL.cloneImage )
3620 CV_CALL( dst = (IplImage*)cvAlloc( sizeof(*dst)));
3622 memcpy( dst, src, sizeof(*src));
3623 dst->imageData = dst->imageDataOrigin = 0;
3628 dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset,
3629 src->roi->yOffset, src->roi->width, src->roi->height );
3632 if( src->imageData )
3634 int size = src->imageSize;
3635 cvCreateData( dst );
3636 memcpy( dst->imageData, src->imageData, size );
3641 dst = CvIPL.cloneImage( src );
3650 /****************************************************************************************\
3651 * Additional operations on CvTermCriteria *
3652 \****************************************************************************************/
3654 CV_IMPL CvTermCriteria
3655 cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
3656 int default_max_iters )
3658 CV_FUNCNAME( "cvCheckTermCriteria" );
3660 CvTermCriteria crit;
3662 crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
3663 crit.max_iter = default_max_iters;
3664 crit.epsilon = (float)default_eps;
3668 if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 )
3669 CV_ERROR( CV_StsBadArg,
3670 "Unknown type of term criteria" );
3672 if( (criteria.type & CV_TERMCRIT_ITER) != 0 )
3674 if( criteria.max_iter <= 0 )
3675 CV_ERROR( CV_StsBadArg,
3676 "Iterations flag is set and maximum number of iterations is <= 0" );
3677 crit.max_iter = criteria.max_iter;
3680 if( (criteria.type & CV_TERMCRIT_EPS) != 0 )
3682 if( criteria.epsilon < 0 )
3683 CV_ERROR( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" );
3685 crit.epsilon = criteria.epsilon;
3688 if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 )
3689 CV_ERROR( CV_StsBadArg,
3690 "Neither accuracy nor maximum iterations "
3691 "number flags are set in criteria type" );
3695 crit.epsilon = (float)MAX( 0, crit.epsilon );
3696 crit.max_iter = MAX( 1, crit.max_iter );