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.)
54 Cv_iplCreateImageHeader createHeader;
55 Cv_iplAllocateImageData allocateData;
56 Cv_iplDeallocate deallocate;
57 Cv_iplCreateROI createROI;
58 Cv_iplCloneImage cloneImage;
62 // Makes the library use native IPL image allocators
64 cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader,
65 Cv_iplAllocateImageData allocateData,
66 Cv_iplDeallocate deallocate,
67 Cv_iplCreateROI createROI,
68 Cv_iplCloneImage cloneImage )
70 if( !createHeader || !allocateData || !deallocate || !createROI || !cloneImage )
72 if( createHeader || allocateData || deallocate || createROI || cloneImage )
73 CV_Error( CV_StsBadArg, "Either all the pointers should be null or "
74 "they all should be non-null" );
77 CvIPL.createHeader = createHeader;
78 CvIPL.allocateData = allocateData;
79 CvIPL.deallocate = deallocate;
80 CvIPL.createROI = createROI;
81 CvIPL.cloneImage = cloneImage;
85 /****************************************************************************************\
86 * CvMat creation and basic operations *
87 \****************************************************************************************/
89 // Creates CvMat and underlying data
91 cvCreateMat( int height, int width, int type )
93 CvMat* arr = cvCreateMatHeader( height, width, type );
100 static void icvCheckHuge( CvMat* arr )
102 if( (int64)arr->step*arr->rows > INT_MAX )
103 arr->type &= ~CV_MAT_CONT_FLAG;
106 // Creates CvMat header only
108 cvCreateMatHeader( int rows, int cols, int type )
110 type = CV_MAT_TYPE(type);
112 if( rows <= 0 || cols <= 0 )
113 CV_Error( CV_StsBadSize, "Non-positive width or height" );
115 int min_step = CV_ELEM_SIZE(type)*cols;
117 CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" );
119 CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr));
121 arr->step = min_step;
122 arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG;
127 arr->hdr_refcount = 1;
134 // Initializes CvMat header, allocated by the user
136 cvInitMatHeader( CvMat* arr, int rows, int cols,
137 int type, void* data, int step )
140 CV_Error( CV_StsNullPtr, "" );
142 if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
143 CV_Error( CV_BadNumChannels, "" );
145 if( rows <= 0 || cols <= 0 )
146 CV_Error( CV_StsBadSize, "Non-positive cols or rows" );
148 type = CV_MAT_TYPE( type );
149 arr->type = type | CV_MAT_MAGIC_VAL;
152 arr->data.ptr = (uchar*)data;
154 arr->hdr_refcount = 0;
156 int pix_size = CV_ELEM_SIZE(type);
157 int min_step = arr->cols*pix_size;
159 if( step != CV_AUTOSTEP && step != 0 )
161 if( step < min_step )
162 CV_Error( CV_BadStep, "" );
167 arr->step = min_step;
170 arr->type = CV_MAT_MAGIC_VAL | type |
171 (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
178 // Deallocates the CvMat structure and underlying data
180 cvReleaseMat( CvMat** array )
183 CV_Error( CV_HeaderIsNull, "" );
189 if( !CV_IS_MAT_HDR(arr) && !CV_IS_MATND_HDR(arr) )
190 CV_Error( CV_StsBadFlag, "" );
200 // Creates a copy of matrix
202 cvCloneMat( const CvMat* src )
204 if( !CV_IS_MAT_HDR( src ))
205 CV_Error( CV_StsBadArg, "Bad CvMat header" );
207 CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type );
219 /****************************************************************************************\
220 * CvMatND creation and basic operations *
221 \****************************************************************************************/
224 cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
225 int type, void* data )
227 type = CV_MAT_TYPE(type);
228 int64 step = CV_ELEM_SIZE(type);
231 CV_Error( CV_StsNullPtr, "NULL matrix header pointer" );
234 CV_Error( CV_StsUnsupportedFormat, "invalid array data type" );
237 CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" );
239 if( dims <= 0 || dims > CV_MAX_DIM )
240 CV_Error( CV_StsOutOfRange,
241 "non-positive or too large number of dimensions" );
243 for( int i = dims - 1; i >= 0; i-- )
246 CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
247 mat->dim[i].size = sizes[i];
249 CV_Error( CV_StsOutOfRange, "The array is too big" );
250 mat->dim[i].step = (int)step;
254 mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
256 mat->data.ptr = (uchar*)data;
258 mat->hdr_refcount = 0;
263 // Creates CvMatND and underlying data
265 cvCreateMatND( int dims, const int* sizes, int type )
267 CvMatND* arr = cvCreateMatNDHeader( dims, sizes, type );
274 // Creates CvMatND header only
276 cvCreateMatNDHeader( int dims, const int* sizes, int type )
278 if( dims <= 0 || dims > CV_MAX_DIM )
279 CV_Error( CV_StsOutOfRange,
280 "non-positive or too large number of dimensions" );
282 CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) );
284 cvInitMatNDHeader( arr, dims, sizes, type, 0 );
285 arr->hdr_refcount = 1;
290 // Creates a copy of nD array
292 cvCloneMatND( const CvMatND* src )
294 if( !CV_IS_MATND_HDR( src ))
295 CV_Error( CV_StsBadArg, "Bad CvMatND header" );
297 int* sizes = (int*)cvStackAlloc( src->dims*sizeof(sizes[0]) );
299 for( int i = 0; i < src->dims; i++ )
300 sizes[i] = src->dim[i].size;
302 CvMatND* dst = cvCreateMatNDHeader( src->dims, sizes, src->type );
315 cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi )
323 CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
325 if( CV_IS_MATND_HDR(arr))
327 if( !((CvMatND*)arr)->data.ptr )
328 CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
330 result = (CvMatND*)arr;
334 CvMat stub, *mat = (CvMat*)arr;
336 if( CV_IS_IMAGE_HDR( mat ))
337 mat = cvGetMat( mat, &stub, coi );
339 if( !CV_IS_MAT_HDR( mat ))
340 CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" );
343 CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
345 matnd->data.ptr = mat->data.ptr;
347 matnd->hdr_refcount = 0;
348 matnd->type = mat->type;
350 matnd->dim[0].size = mat->rows;
351 matnd->dim[0].step = mat->step;
352 matnd->dim[1].size = mat->cols;
353 matnd->dim[1].step = CV_ELEM_SIZE(mat->type);
361 // returns number of dimensions to iterate.
363 Checks whether <count> arrays have equal type, sizes (mask is optional array
364 that needs to have the same size, but 8uC1 or 8sC1 type).
365 Returns number of dimensions to iterate through:
366 0 means that all arrays are continuous,
367 1 means that all arrays are vectors of continuous arrays etc.
368 and the size of largest common continuous part of the arrays
371 cvInitNArrayIterator( int count, CvArr** arrs,
372 const CvArr* mask, CvMatND* stubs,
373 CvNArrayIterator* iterator, int flags )
376 int i, j, size, dim0 = -1;
380 if( count < 1 || count > CV_MAX_ARR )
381 CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" );
383 if( !arrs || !stubs )
384 CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" );
387 CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" );
389 for( i = 0; i <= count; i++ )
391 const CvArr* arr = i < count ? arrs[i] : mask;
397 CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" );
401 if( CV_IS_MATND( arr ))
406 hdr = cvGetMatND( arr, stubs + i, &coi );
408 CV_Error( CV_BadCOI, "COI set is not allowed here" );
411 iterator->hdr[i] = hdr;
415 if( hdr->dims != hdr0->dims )
416 CV_Error( CV_StsUnmatchedSizes,
417 "Number of dimensions is the same for all arrays" );
421 switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK))
424 if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))
425 CV_Error( CV_StsUnmatchedFormats,
426 "Data type is not the same for all arrays" );
428 case CV_NO_DEPTH_CHECK:
429 if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
430 CV_Error( CV_StsUnmatchedFormats,
431 "Number of channels is not the same for all arrays" );
434 if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
435 CV_Error( CV_StsUnmatchedFormats,
436 "Depth is not the same for all arrays" );
442 if( !CV_IS_MASK_ARR( hdr ))
443 CV_Error( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );
446 if( !(flags & CV_NO_SIZE_CHECK) )
448 for( j = 0; j < hdr->dims; j++ )
449 if( hdr->dim[j].size != hdr0->dim[j].size )
450 CV_Error( CV_StsUnmatchedSizes,
451 "Dimension sizes are the same for all arrays" );
457 step = CV_ELEM_SIZE(hdr->type);
458 for( j = hdr->dims - 1; j > dim0; j-- )
460 if( step != hdr->dim[j].step )
462 step *= hdr->dim[j].size;
465 if( j == dim0 && step > INT_MAX )
471 iterator->hdr[i] = (CvMatND*)hdr;
472 iterator->ptr[i] = (uchar*)hdr->data.ptr;
476 for( j = hdr0->dims - 1; j > dim0; j-- )
477 size *= hdr0->dim[j].size;
480 iterator->dims = dims;
481 iterator->count = count;
482 iterator->size = cvSize(size,1);
484 for( i = 0; i < dims; i++ )
485 iterator->stack[i] = hdr0->dim[i].size;
491 // returns zero value if iteration is finished, non-zero otherwise
492 CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator )
494 assert( iterator != 0 );
495 int i, dims, size = 0;
497 for( dims = iterator->dims; dims > 0; dims-- )
499 for( i = 0; i < iterator->count; i++ )
500 iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;
502 if( --iterator->stack[dims-1] > 0 )
505 size = iterator->hdr[0]->dim[dims-1].size;
507 for( i = 0; i < iterator->count; i++ )
508 iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;
510 iterator->stack[dims-1] = size;
517 /****************************************************************************************\
518 * CvSparseMat creation and basic operations *
519 \****************************************************************************************/
522 // Creates CvMatND and underlying data
524 cvCreateSparseMat( int dims, const int* sizes, int type )
526 type = CV_MAT_TYPE( type );
527 int pix_size1 = CV_ELEM_SIZE1(type);
528 int pix_size = pix_size1*CV_MAT_CN(type);
530 CvMemStorage* storage;
533 CV_Error( CV_StsUnsupportedFormat, "invalid array data type" );
535 if( dims <= 0 || dims > CV_MAX_DIM_HEAP )
536 CV_Error( CV_StsOutOfRange, "bad number of dimensions" );
539 CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" );
541 for( i = 0; i < dims; i++ )
544 CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
547 CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0]));
549 arr->type = CV_SPARSE_MAT_MAGIC_VAL | type;
552 arr->hdr_refcount = 1;
553 memcpy( arr->size, sizes, dims*sizeof(sizes[0]));
555 arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1);
556 arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));
557 size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));
559 storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK );
560 arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage );
562 arr->hashsize = CV_SPARSE_HASH_SIZE0;
563 size = arr->hashsize*sizeof(arr->hashtable[0]);
565 arr->hashtable = (void**)cvAlloc( size );
566 memset( arr->hashtable, 0, size );
572 // Creates CvMatND and underlying data
574 cvReleaseSparseMat( CvSparseMat** array )
577 CV_Error( CV_HeaderIsNull, "" );
581 CvSparseMat* arr = *array;
583 if( !CV_IS_SPARSE_MAT_HDR(arr) )
584 CV_Error( CV_StsBadFlag, "" );
588 CvMemStorage* storage = arr->heap->storage;
589 cvReleaseMemStorage( &storage );
590 cvFree( &arr->hashtable );
596 // Creates CvMatND and underlying data
598 cvCloneSparseMat( const CvSparseMat* src )
600 if( !CV_IS_SPARSE_MAT_HDR(src) )
601 CV_Error( CV_StsBadArg, "Invalid sparse array header" );
603 CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type );
610 cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator )
612 CvSparseNode* node = 0;
615 if( !CV_IS_SPARSE_MAT( mat ))
616 CV_Error( CV_StsBadArg, "Invalid sparse matrix header" );
619 CV_Error( CV_StsNullPtr, "NULL iterator pointer" );
621 iterator->mat = (CvSparseMat*)mat;
624 for( idx = 0; idx < mat->hashsize; idx++ )
625 if( mat->hashtable[idx] )
627 node = iterator->node = (CvSparseNode*)mat->hashtable[idx];
631 iterator->curidx = idx;
635 #define ICV_SPARSE_MAT_HASH_MULTIPLIER cv::SparseMat::HASH_SCALE
638 icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
639 int create_node, unsigned* precalc_hashval )
643 unsigned hashval = 0;
645 assert( CV_IS_SPARSE_MAT( mat ));
647 if( !precalc_hashval )
649 for( i = 0; i < mat->dims; i++ )
652 if( (unsigned)t >= (unsigned)mat->size[i] )
653 CV_Error( CV_StsOutOfRange, "One of indices is out of range" );
654 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
659 hashval = *precalc_hashval;
662 tabidx = hashval & (mat->hashsize - 1);
665 if( create_node >= -1 )
667 for( node = (CvSparseNode*)mat->hashtable[tabidx];
668 node != 0; node = node->next )
670 if( node->hashval == hashval )
672 int* nodeidx = CV_NODE_IDX(mat,node);
673 for( i = 0; i < mat->dims; i++ )
674 if( idx[i] != nodeidx[i] )
678 ptr = (uchar*)CV_NODE_VAL(mat,node);
685 if( !ptr && create_node )
687 if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO )
690 int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);
691 int newrawsize = newsize*sizeof(newtable[0]);
693 CvSparseMatIterator iterator;
694 assert( (newsize & (newsize - 1)) == 0 );
697 newtable = (void**)cvAlloc( newrawsize );
698 memset( newtable, 0, newrawsize );
700 node = cvInitSparseMatIterator( mat, &iterator );
703 CvSparseNode* next = cvGetNextSparseNode( &iterator );
704 int newidx = node->hashval & (newsize - 1);
705 node->next = (CvSparseNode*)newtable[newidx];
706 newtable[newidx] = node;
710 cvFree( &mat->hashtable );
711 mat->hashtable = newtable;
712 mat->hashsize = newsize;
713 tabidx = hashval & (newsize - 1);
716 node = (CvSparseNode*)cvSetNew( mat->heap );
717 node->hashval = hashval;
718 node->next = (CvSparseNode*)mat->hashtable[tabidx];
719 mat->hashtable[tabidx] = node;
720 CV_MEMCPY_INT( CV_NODE_IDX(mat,node), idx, mat->dims );
721 ptr = (uchar*)CV_NODE_VAL(mat,node);
722 if( create_node > 0 )
723 CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(mat->type));
727 *_type = CV_MAT_TYPE(mat->type);
734 icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval )
737 unsigned hashval = 0;
738 CvSparseNode *node, *prev = 0;
739 assert( CV_IS_SPARSE_MAT( mat ));
741 if( !precalc_hashval )
743 for( i = 0; i < mat->dims; i++ )
746 if( (unsigned)t >= (unsigned)mat->size[i] )
747 CV_Error( CV_StsOutOfRange, "One of indices is out of range" );
748 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
753 hashval = *precalc_hashval;
756 tabidx = hashval & (mat->hashsize - 1);
759 for( node = (CvSparseNode*)mat->hashtable[tabidx];
760 node != 0; prev = node, node = node->next )
762 if( node->hashval == hashval )
764 int* nodeidx = CV_NODE_IDX(mat,node);
765 for( i = 0; i < mat->dims; i++ )
766 if( idx[i] != nodeidx[i] )
776 prev->next = node->next;
778 mat->hashtable[tabidx] = node->next;
779 cvSetRemoveByPtr( mat->heap, node );
784 /****************************************************************************************\
785 * Common for multiple array types operations *
786 \****************************************************************************************/
788 // Allocates underlying array data
790 cvCreateData( CvArr* arr )
792 if( CV_IS_MAT_HDR( arr ))
794 size_t step, total_size;
795 CvMat* mat = (CvMat*)arr;
798 if( mat->data.ptr != 0 )
799 CV_Error( CV_StsError, "Data is already allocated" );
802 step = CV_ELEM_SIZE(mat->type)*mat->cols;
804 int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
805 total_size = (size_t)_total_size;
806 if(_total_size != (int64)total_size)
807 CV_Error(CV_StsNoMem, "Too big buffer is allocated" );
808 mat->refcount = (int*)cvAlloc( (size_t)total_size );
809 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
812 else if( CV_IS_IMAGE_HDR(arr))
814 IplImage* img = (IplImage*)arr;
816 if( img->imageData != 0 )
817 CV_Error( CV_StsError, "Data is already allocated" );
819 if( !CvIPL.allocateData )
821 img->imageData = img->imageDataOrigin =
822 (char*)cvAlloc( (size_t)img->imageSize );
826 int depth = img->depth;
827 int width = img->width;
829 if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 )
831 img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
832 img->depth = IPL_DEPTH_8U;
835 CvIPL.allocateData( img, 0, 0 );
841 else if( CV_IS_MATND_HDR( arr ))
843 CvMatND* mat = (CvMatND*)arr;
845 size_t total_size = CV_ELEM_SIZE(mat->type);
847 if( mat->data.ptr != 0 )
848 CV_Error( CV_StsError, "Data is already allocated" );
850 if( CV_IS_MAT_CONT( mat->type ))
852 total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
853 mat->dim[0].step : total_size);
857 for( i = mat->dims - 1; i >= 0; i-- )
859 size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;
861 if( total_size < size )
866 mat->refcount = (int*)cvAlloc( total_size +
867 sizeof(int) + CV_MALLOC_ALIGN );
868 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
872 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
876 // Assigns external data to array
878 cvSetData( CvArr* arr, void* data, int step )
880 int pix_size, min_step;
882 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) )
883 cvReleaseData( arr );
885 if( CV_IS_MAT_HDR( arr ))
887 CvMat* mat = (CvMat*)arr;
889 int type = CV_MAT_TYPE(mat->type);
890 pix_size = CV_ELEM_SIZE(type);
891 min_step = mat->cols*pix_size;
893 if( step != CV_AUTOSTEP && step != 0 )
895 if( step < min_step && data != 0 )
896 CV_Error( CV_BadStep, "" );
900 mat->step = min_step;
902 mat->data.ptr = (uchar*)data;
903 mat->type = CV_MAT_MAGIC_VAL | type |
904 (mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0);
907 else if( CV_IS_IMAGE_HDR( arr ))
909 IplImage* img = (IplImage*)arr;
911 pix_size = ((img->depth & 255) >> 3)*img->nChannels;
912 min_step = img->width*pix_size;
914 if( step != CV_AUTOSTEP && img->height > 1 )
916 if( step < min_step && data != 0 )
917 CV_Error( CV_BadStep, "" );
918 img->widthStep = step;
922 img->widthStep = min_step;
925 img->imageSize = img->widthStep * img->height;
926 img->imageData = img->imageDataOrigin = (char*)data;
928 if( (((int)(size_t)data | step) & 7) == 0 &&
929 cvAlign(img->width * pix_size, 8) == step )
934 else if( CV_IS_MATND_HDR( arr ))
936 CvMatND* mat = (CvMatND*)arr;
940 if( step != CV_AUTOSTEP )
941 CV_Error( CV_BadStep,
942 "For multidimensional array only CV_AUTOSTEP is allowed here" );
944 mat->data.ptr = (uchar*)data;
945 cur_step = CV_ELEM_SIZE(mat->type);
947 for( i = mat->dims - 1; i >= 0; i-- )
949 if( cur_step > INT_MAX )
950 CV_Error( CV_StsOutOfRange, "The array is too big" );
951 mat->dim[i].step = (int)cur_step;
952 cur_step *= mat->dim[i].size;
956 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
960 // Deallocates array's data
962 cvReleaseData( CvArr* arr )
964 if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr ))
966 CvMat* mat = (CvMat*)arr;
969 else if( CV_IS_IMAGE_HDR( arr ))
971 IplImage* img = (IplImage*)arr;
973 if( !CvIPL.deallocate )
975 char* ptr = img->imageDataOrigin;
976 img->imageData = img->imageDataOrigin = 0;
981 CvIPL.deallocate( img, IPL_IMAGE_DATA );
985 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
989 // Retrieves essential information about image ROI or CvMat data
991 cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size )
993 if( CV_IS_MAT( arr ))
995 CvMat *mat = (CvMat*)arr;
1001 *data = mat->data.ptr;
1004 *roi_size = cvGetMatSize( mat );
1006 else if( CV_IS_IMAGE( arr ))
1008 IplImage* img = (IplImage*)arr;
1011 *step = img->widthStep;
1014 *data = cvPtr2D( img, 0, 0 );
1020 *roi_size = cvSize( img->roi->width, img->roi->height );
1024 *roi_size = cvSize( img->width, img->height );
1028 else if( CV_IS_MATND( arr ))
1030 CvMatND* mat = (CvMatND*)arr;
1032 if( !CV_IS_MAT_CONT( mat->type ))
1033 CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
1036 *data = mat->data.ptr;
1038 if( roi_size || step )
1040 int i, size1 = mat->dim[0].size, size2 = 1;
1043 for( i = 1; i < mat->dims; i++ )
1044 size1 *= mat->dim[i].size;
1046 size2 = mat->dim[1].size;
1050 roi_size->width = size2;
1051 roi_size->height = size1;
1055 *step = mat->dim[0].step;
1059 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1064 cvGetElemType( const CvArr* arr )
1067 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr))
1068 type = CV_MAT_TYPE( ((CvMat*)arr)->type );
1069 else if( CV_IS_IMAGE(arr))
1071 IplImage* img = (IplImage*)arr;
1072 type = CV_MAKETYPE( IplToCvDepth(img->depth), img->nChannels );
1075 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1081 // Returns a number of array dimensions
1083 cvGetDims( const CvArr* arr, int* sizes )
1086 if( CV_IS_MAT_HDR( arr ))
1088 CvMat* mat = (CvMat*)arr;
1093 sizes[0] = mat->rows;
1094 sizes[1] = mat->cols;
1097 else if( CV_IS_IMAGE( arr ))
1099 IplImage* img = (IplImage*)arr;
1104 sizes[0] = img->height;
1105 sizes[1] = img->width;
1108 else if( CV_IS_MATND_HDR( arr ))
1110 CvMatND* mat = (CvMatND*)arr;
1116 for( i = 0; i < dims; i++ )
1117 sizes[i] = mat->dim[i].size;
1120 else if( CV_IS_SPARSE_MAT_HDR( arr ))
1122 CvSparseMat* mat = (CvSparseMat*)arr;
1126 memcpy( sizes, mat->size, dims*sizeof(sizes[0]));
1129 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1135 // Returns the size of particular array dimension
1137 cvGetDimSize( const CvArr* arr, int index )
1141 if( CV_IS_MAT( arr ))
1143 CvMat *mat = (CvMat*)arr;
1154 CV_Error( CV_StsOutOfRange, "bad dimension index" );
1157 else if( CV_IS_IMAGE( arr ))
1159 IplImage* img = (IplImage*)arr;
1164 size = !img->roi ? img->height : img->roi->height;
1167 size = !img->roi ? img->width : img->roi->width;
1170 CV_Error( CV_StsOutOfRange, "bad dimension index" );
1173 else if( CV_IS_MATND_HDR( arr ))
1175 CvMatND* mat = (CvMatND*)arr;
1177 if( (unsigned)index >= (unsigned)mat->dims )
1178 CV_Error( CV_StsOutOfRange, "bad dimension index" );
1180 size = mat->dim[index].size;
1182 else if( CV_IS_SPARSE_MAT_HDR( arr ))
1184 CvSparseMat* mat = (CvSparseMat*)arr;
1186 if( (unsigned)index >= (unsigned)mat->dims )
1187 CV_Error( CV_StsOutOfRange, "bad dimension index" );
1189 size = mat->size[index];
1192 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1198 // Returns the size of CvMat or IplImage
1200 cvGetSize( const CvArr* arr )
1202 CvSize size = { 0, 0 };
1204 if( CV_IS_MAT_HDR( arr ))
1206 CvMat *mat = (CvMat*)arr;
1208 size.width = mat->cols;
1209 size.height = mat->rows;
1211 else if( CV_IS_IMAGE_HDR( arr ))
1213 IplImage* img = (IplImage*)arr;
1217 size.width = img->roi->width;
1218 size.height = img->roi->height;
1222 size.width = img->width;
1223 size.height = img->height;
1227 CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" );
1233 // Selects sub-array (no data is copied)
1235 cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
1238 CvMat stub, *mat = (CvMat*)arr;
1240 if( !CV_IS_MAT( mat ))
1241 mat = cvGetMat( mat, &stub );
1244 CV_Error( CV_StsNullPtr, "" );
1246 if( (rect.x|rect.y|rect.width|rect.height) < 0 )
1247 CV_Error( CV_StsBadSize, "" );
1249 if( rect.x + rect.width > mat->cols ||
1250 rect.y + rect.height > mat->rows )
1251 CV_Error( CV_StsBadSize, "" );
1255 int* refcount = mat->refcount;
1260 cvDecRefData( submat );
1262 submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
1263 rect.x*CV_ELEM_SIZE(mat->type);
1264 submat->step = mat->step;
1265 submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
1266 (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0);
1267 submat->rows = rect.height;
1268 submat->cols = rect.width;
1269 submat->refcount = 0;
1277 // Selects array's row span.
1279 cvGetRows( const CvArr* arr, CvMat* submat,
1280 int start_row, int end_row, int delta_row )
1283 CvMat stub, *mat = (CvMat*)arr;
1285 if( !CV_IS_MAT( mat ))
1286 mat = cvGetMat( mat, &stub );
1289 CV_Error( CV_StsNullPtr, "" );
1291 if( (unsigned)start_row >= (unsigned)mat->rows ||
1292 (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 )
1293 CV_Error( CV_StsOutOfRange, "" );
1297 int* refcount = mat->refcount;
1302 cvDecRefData( submat );
1304 if( delta_row == 1 )
1306 submat->rows = end_row - start_row;
1307 submat->step = mat->step;
1311 submat->rows = (end_row - start_row + delta_row - 1)/delta_row;
1312 submat->step = mat->step * delta_row;
1315 submat->cols = mat->cols;
1316 submat->step &= submat->rows > 1 ? -1 : 0;
1317 submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
1318 submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) &
1319 (delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1);
1320 submat->refcount = 0;
1321 submat->hdr_refcount = 0;
1329 // Selects array's column span.
1331 cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col )
1334 CvMat stub, *mat = (CvMat*)arr;
1337 if( !CV_IS_MAT( mat ))
1338 mat = cvGetMat( mat, &stub );
1341 CV_Error( CV_StsNullPtr, "" );
1344 if( (unsigned)start_col >= (unsigned)cols ||
1345 (unsigned)end_col > (unsigned)cols )
1346 CV_Error( CV_StsOutOfRange, "" );
1350 int* refcount = mat->refcount;
1355 cvDecRefData( submat );
1357 submat->rows = mat->rows;
1358 submat->cols = end_col - start_col;
1359 submat->step = mat->step;
1360 submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type);
1361 submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
1362 submat->refcount = 0;
1363 submat->hdr_refcount = 0;
1371 // Selects array diagonal
1373 cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
1376 CvMat stub, *mat = (CvMat*)arr;
1379 if( !CV_IS_MAT( mat ))
1380 mat = cvGetMat( mat, &stub );
1383 CV_Error( CV_StsNullPtr, "" );
1385 pix_size = CV_ELEM_SIZE(mat->type);
1388 int* refcount = mat->refcount;
1393 cvDecRefData( submat );
1398 len = mat->cols - diag;
1401 CV_Error( CV_StsOutOfRange, "" );
1403 len = CV_IMIN( len, mat->rows );
1404 submat->data.ptr = mat->data.ptr + diag*pix_size;
1408 len = mat->rows + diag;
1411 CV_Error( CV_StsOutOfRange, "" );
1413 len = CV_IMIN( len, mat->cols );
1414 submat->data.ptr = mat->data.ptr - diag*mat->step;
1419 submat->step = mat->step + (submat->rows > 1 ? pix_size : 0);
1420 submat->type = mat->type;
1421 if( submat->rows > 1 )
1422 submat->type &= ~CV_MAT_CONT_FLAG;
1424 submat->type |= CV_MAT_CONT_FLAG;
1425 submat->refcount = 0;
1426 submat->hdr_refcount = 0;
1433 /****************************************************************************************\
1434 * Operations on CvScalar and accessing array elements *
1435 \****************************************************************************************/
1437 // Converts CvScalar to specified type
1439 cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 )
1441 type = CV_MAT_TYPE(type);
1442 int cn = CV_MAT_CN( type );
1443 int depth = type & CV_MAT_DEPTH_MASK;
1445 assert( scalar && data );
1446 if( (unsigned)(cn - 1) >= 4 )
1447 CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
1454 int t = cvRound( scalar->val[cn] );
1455 ((uchar*)data)[cn] = CV_CAST_8U(t);
1461 int t = cvRound( scalar->val[cn] );
1462 ((char*)data)[cn] = CV_CAST_8S(t);
1468 int t = cvRound( scalar->val[cn] );
1469 ((ushort*)data)[cn] = CV_CAST_16U(t);
1475 int t = cvRound( scalar->val[cn] );
1476 ((short*)data)[cn] = CV_CAST_16S(t);
1481 ((int*)data)[cn] = cvRound( scalar->val[cn] );
1485 ((float*)data)[cn] = (float)(scalar->val[cn]);
1489 ((double*)data)[cn] = (double)(scalar->val[cn]);
1493 CV_Error( CV_BadDepth, "" );
1498 int pix_size = CV_ELEM_SIZE(type);
1499 int offset = CV_ELEM_SIZE1(depth)*12;
1504 CV_MEMCPY_AUTO( (char*)data + offset, data, pix_size );
1506 while( offset > pix_size );
1511 // Converts data of specified type to CvScalar
1513 cvRawDataToScalar( const void* data, int flags, CvScalar* scalar )
1515 int cn = CV_MAT_CN( flags );
1517 assert( scalar && data );
1519 if( (unsigned)(cn - 1) >= 4 )
1520 CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
1522 memset( scalar->val, 0, sizeof(scalar->val));
1524 switch( CV_MAT_DEPTH( flags ))
1528 scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]);
1532 scalar->val[cn] = CV_8TO32F(((char*)data)[cn]);
1536 scalar->val[cn] = ((ushort*)data)[cn];
1540 scalar->val[cn] = ((short*)data)[cn];
1544 scalar->val[cn] = ((int*)data)[cn];
1548 scalar->val[cn] = ((float*)data)[cn];
1552 scalar->val[cn] = ((double*)data)[cn];
1556 CV_Error( CV_BadDepth, "" );
1561 static double icvGetReal( const void* data, int type )
1566 return *(uchar*)data;
1568 return *(char*)data;
1570 return *(ushort*)data;
1572 return *(short*)data;
1576 return *(float*)data;
1578 return *(double*)data;
1585 static void icvSetReal( double value, const void* data, int type )
1589 int ivalue = cvRound(value);
1593 *(uchar*)data = CV_CAST_8U(ivalue);
1596 *(char*)data = CV_CAST_8S(ivalue);
1599 *(ushort*)data = CV_CAST_16U(ivalue);
1602 *(short*)data = CV_CAST_16S(ivalue);
1605 *(int*)data = CV_CAST_32S(ivalue);
1614 *(float*)data = (float)value;
1617 *(double*)data = value;
1624 // Returns pointer to specified element of array (linear index is used)
1626 cvPtr1D( const CvArr* arr, int idx, int* _type )
1629 if( CV_IS_MAT( arr ))
1631 CvMat* mat = (CvMat*)arr;
1633 int type = CV_MAT_TYPE(mat->type);
1634 int pix_size = CV_ELEM_SIZE(type);
1639 // the first part is mul-free sufficient check
1640 // that the index is within the matrix
1641 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
1642 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
1643 CV_Error( CV_StsOutOfRange, "index is out of range" );
1645 if( CV_IS_MAT_CONT(mat->type))
1647 ptr = mat->data.ptr + (size_t)idx*pix_size;
1652 if( mat->cols == 1 )
1655 row = idx/mat->cols, col = idx - row*mat->cols;
1656 ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size;
1659 else if( CV_IS_IMAGE_HDR( arr ))
1661 IplImage* img = (IplImage*)arr;
1662 int width = !img->roi ? img->width : img->roi->width;
1663 int y = idx/width, x = idx - y*width;
1665 ptr = cvPtr2D( arr, y, x, _type );
1667 else if( CV_IS_MATND( arr ))
1669 CvMatND* mat = (CvMatND*)arr;
1670 int j, type = CV_MAT_TYPE(mat->type);
1671 size_t size = mat->dim[0].size;
1676 for( j = 1; j < mat->dims; j++ )
1677 size *= mat->dim[j].size;
1679 if((unsigned)idx >= (unsigned)size )
1680 CV_Error( CV_StsOutOfRange, "index is out of range" );
1682 if( CV_IS_MAT_CONT(mat->type))
1684 int pix_size = CV_ELEM_SIZE(type);
1685 ptr = mat->data.ptr + (size_t)idx*pix_size;
1689 ptr = mat->data.ptr;
1690 for( j = mat->dims - 1; j >= 0; j-- )
1692 int sz = mat->dim[j].size;
1696 ptr += (idx - t*sz)*mat->dim[j].step;
1702 else if( CV_IS_SPARSE_MAT( arr ))
1704 CvSparseMat* m = (CvSparseMat*)arr;
1706 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 );
1710 int* _idx = (int*)cvStackAlloc(n*sizeof(_idx[0]));
1712 for( i = n - 1; i >= 0; i-- )
1714 int t = idx / m->size[i];
1715 _idx[i] = idx - t*m->size[i];
1718 ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 );
1723 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1730 // Returns pointer to specified element of 2d array
1732 cvPtr2D( const CvArr* arr, int y, int x, int* _type )
1735 if( CV_IS_MAT( arr ))
1737 CvMat* mat = (CvMat*)arr;
1740 if( (unsigned)y >= (unsigned)(mat->rows) ||
1741 (unsigned)x >= (unsigned)(mat->cols) )
1742 CV_Error( CV_StsOutOfRange, "index is out of range" );
1744 type = CV_MAT_TYPE(mat->type);
1748 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
1750 else if( CV_IS_IMAGE( arr ))
1752 IplImage* img = (IplImage*)arr;
1753 int pix_size = (img->depth & 255) >> 3;
1755 ptr = (uchar*)img->imageData;
1757 if( img->dataOrder == 0 )
1758 pix_size *= img->nChannels;
1762 width = img->roi->width;
1763 height = img->roi->height;
1765 ptr += img->roi->yOffset*img->widthStep +
1766 img->roi->xOffset*pix_size;
1768 if( img->dataOrder )
1770 int coi = img->roi->coi;
1772 CV_Error( CV_BadCOI,
1773 "COI must be non-null in case of planar images" );
1774 ptr += (coi - 1)*img->imageSize;
1780 height = img->height;
1783 if( (unsigned)y >= (unsigned)height ||
1784 (unsigned)x >= (unsigned)width )
1785 CV_Error( CV_StsOutOfRange, "index is out of range" );
1787 ptr += y*img->widthStep + x*pix_size;
1791 int type = IplToCvDepth(img->depth);
1792 if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
1793 CV_Error( CV_StsUnsupportedFormat, "" );
1795 *_type = CV_MAKETYPE( type, img->nChannels );
1798 else if( CV_IS_MATND( arr ))
1800 CvMatND* mat = (CvMatND*)arr;
1802 if( mat->dims != 2 ||
1803 (unsigned)y >= (unsigned)(mat->dim[0].size) ||
1804 (unsigned)x >= (unsigned)(mat->dim[1].size) )
1805 CV_Error( CV_StsOutOfRange, "index is out of range" );
1807 ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step;
1809 *_type = CV_MAT_TYPE(mat->type);
1811 else if( CV_IS_SPARSE_MAT( arr ))
1813 int idx[] = { y, x };
1814 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
1818 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1825 // Returns pointer to specified element of 3d array
1827 cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type )
1830 if( CV_IS_MATND( arr ))
1832 CvMatND* mat = (CvMatND*)arr;
1834 if( mat->dims != 3 ||
1835 (unsigned)z >= (unsigned)(mat->dim[0].size) ||
1836 (unsigned)y >= (unsigned)(mat->dim[1].size) ||
1837 (unsigned)x >= (unsigned)(mat->dim[2].size) )
1838 CV_Error( CV_StsOutOfRange, "index is out of range" );
1840 ptr = mat->data.ptr + (size_t)z*mat->dim[0].step +
1841 (size_t)y*mat->dim[1].step + x*mat->dim[2].step;
1844 *_type = CV_MAT_TYPE(mat->type);
1846 else if( CV_IS_SPARSE_MAT( arr ))
1848 int idx[] = { z, y, x };
1849 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
1853 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1860 // Returns pointer to specified element of n-d array
1862 cvPtrND( const CvArr* arr, const int* idx, int* _type,
1863 int create_node, unsigned* precalc_hashval )
1867 CV_Error( CV_StsNullPtr, "NULL pointer to indices" );
1869 if( CV_IS_SPARSE_MAT( arr ))
1870 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx,
1871 _type, create_node, precalc_hashval );
1872 else if( CV_IS_MATND( arr ))
1874 CvMatND* mat = (CvMatND*)arr;
1876 ptr = mat->data.ptr;
1878 for( i = 0; i < mat->dims; i++ )
1880 if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) )
1881 CV_Error( CV_StsOutOfRange, "index is out of range" );
1882 ptr += (size_t)idx[i]*mat->dim[i].step;
1886 *_type = CV_MAT_TYPE(mat->type);
1888 else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) )
1889 ptr = cvPtr2D( arr, idx[0], idx[1], _type );
1891 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1897 // Returns specifed element of n-D array given linear index
1899 cvGet1D( const CvArr* arr, int idx )
1901 CvScalar scalar = {{0,0,0,0}};
1905 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
1907 CvMat* mat = (CvMat*)arr;
1909 type = CV_MAT_TYPE(mat->type);
1910 int pix_size = CV_ELEM_SIZE(type);
1912 // the first part is mul-free sufficient check
1913 // that the index is within the matrix
1914 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
1915 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
1916 CV_Error( CV_StsOutOfRange, "index is out of range" );
1918 ptr = mat->data.ptr + (size_t)idx*pix_size;
1920 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
1921 ptr = cvPtr1D( arr, idx, &type );
1923 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
1926 cvRawDataToScalar( ptr, type, &scalar );
1932 // Returns specifed element of 2D array
1934 cvGet2D( const CvArr* arr, int y, int x )
1936 CvScalar scalar = {{0,0,0,0}};
1940 if( CV_IS_MAT( arr ))
1942 CvMat* mat = (CvMat*)arr;
1944 if( (unsigned)y >= (unsigned)(mat->rows) ||
1945 (unsigned)x >= (unsigned)(mat->cols) )
1946 CV_Error( CV_StsOutOfRange, "index is out of range" );
1948 type = CV_MAT_TYPE(mat->type);
1949 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
1951 else if( !CV_IS_SPARSE_MAT( arr ))
1952 ptr = cvPtr2D( arr, y, x, &type );
1955 int idx[] = { y, x };
1956 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
1960 cvRawDataToScalar( ptr, type, &scalar );
1966 // Returns specifed element of 3D array
1968 cvGet3D( const CvArr* arr, int z, int y, int x )
1970 CvScalar scalar = {{0,0,0,0}};
1974 if( !CV_IS_SPARSE_MAT( arr ))
1975 ptr = cvPtr3D( arr, z, y, x, &type );
1978 int idx[] = { z, y, x };
1979 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
1983 cvRawDataToScalar( ptr, type, &scalar );
1988 // Returns specifed element of nD array
1990 cvGetND( const CvArr* arr, const int* idx )
1992 CvScalar scalar = {{0,0,0,0}};
1996 if( !CV_IS_SPARSE_MAT( arr ))
1997 ptr = cvPtrND( arr, idx, &type );
1999 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2002 cvRawDataToScalar( ptr, type, &scalar );
2008 // Returns specifed element of n-D array given linear index
2010 cvGetReal1D( const CvArr* arr, int idx )
2016 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2018 CvMat* mat = (CvMat*)arr;
2020 type = CV_MAT_TYPE(mat->type);
2021 int pix_size = CV_ELEM_SIZE(type);
2023 // the first part is mul-free sufficient check
2024 // that the index is within the matrix
2025 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2026 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2027 CV_Error( CV_StsOutOfRange, "index is out of range" );
2029 ptr = mat->data.ptr + (size_t)idx*pix_size;
2031 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2032 ptr = cvPtr1D( arr, idx, &type );
2034 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
2038 if( CV_MAT_CN( type ) > 1 )
2039 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2041 value = icvGetReal( ptr, type );
2047 // Returns specifed element of 2D array
2049 cvGetReal2D( const CvArr* arr, int y, int x )
2055 if( CV_IS_MAT( arr ))
2057 CvMat* mat = (CvMat*)arr;
2059 if( (unsigned)y >= (unsigned)(mat->rows) ||
2060 (unsigned)x >= (unsigned)(mat->cols) )
2061 CV_Error( CV_StsOutOfRange, "index is out of range" );
2063 type = CV_MAT_TYPE(mat->type);
2064 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2066 else if( !CV_IS_SPARSE_MAT( arr ))
2067 ptr = cvPtr2D( arr, y, x, &type );
2070 int idx[] = { y, x };
2071 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2076 if( CV_MAT_CN( type ) > 1 )
2077 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2079 value = icvGetReal( ptr, type );
2086 // Returns specifed element of 3D array
2088 cvGetReal3D( const CvArr* arr, int z, int y, int x )
2094 if( !CV_IS_SPARSE_MAT( arr ))
2095 ptr = cvPtr3D( arr, z, y, x, &type );
2098 int idx[] = { z, y, x };
2099 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2104 if( CV_MAT_CN( type ) > 1 )
2105 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2107 value = icvGetReal( ptr, type );
2114 // Returns specifed element of nD array
2116 cvGetRealND( const CvArr* arr, const int* idx )
2122 if( !CV_IS_SPARSE_MAT( arr ))
2123 ptr = cvPtrND( arr, idx, &type );
2125 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2129 if( CV_MAT_CN( type ) > 1 )
2130 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2132 value = icvGetReal( ptr, type );
2139 // Assigns new value to specifed element of nD array given linear index
2141 cvSet1D( CvArr* arr, int idx, CvScalar scalar )
2146 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2148 CvMat* mat = (CvMat*)arr;
2150 type = CV_MAT_TYPE(mat->type);
2151 int pix_size = CV_ELEM_SIZE(type);
2153 // the first part is mul-free sufficient check
2154 // that the index is within the matrix
2155 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2156 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2157 CV_Error( CV_StsOutOfRange, "index is out of range" );
2159 ptr = mat->data.ptr + (size_t)idx*pix_size;
2161 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2162 ptr = cvPtr1D( arr, idx, &type );
2164 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2166 cvScalarToRawData( &scalar, ptr, type );
2170 // Assigns new value to specifed element of 2D array
2172 cvSet2D( CvArr* arr, int y, int x, CvScalar scalar )
2177 if( CV_IS_MAT( arr ))
2179 CvMat* mat = (CvMat*)arr;
2181 if( (unsigned)y >= (unsigned)(mat->rows) ||
2182 (unsigned)x >= (unsigned)(mat->cols) )
2183 CV_Error( CV_StsOutOfRange, "index is out of range" );
2185 type = CV_MAT_TYPE(mat->type);
2186 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2188 else if( !CV_IS_SPARSE_MAT( arr ))
2189 ptr = cvPtr2D( arr, y, x, &type );
2192 int idx[] = { y, x };
2193 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2195 cvScalarToRawData( &scalar, ptr, type );
2199 // Assigns new value to specifed element of 3D array
2201 cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar )
2206 if( !CV_IS_SPARSE_MAT( arr ))
2207 ptr = cvPtr3D( arr, z, y, x, &type );
2210 int idx[] = { z, y, x };
2211 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2213 cvScalarToRawData( &scalar, ptr, type );
2217 // Assigns new value to specifed element of nD array
2219 cvSetND( CvArr* arr, const int* idx, CvScalar scalar )
2224 if( !CV_IS_SPARSE_MAT( arr ))
2225 ptr = cvPtrND( arr, idx, &type );
2227 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2228 cvScalarToRawData( &scalar, ptr, type );
2233 cvSetReal1D( CvArr* arr, int idx, double value )
2238 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2240 CvMat* mat = (CvMat*)arr;
2242 type = CV_MAT_TYPE(mat->type);
2243 int pix_size = CV_ELEM_SIZE(type);
2245 // the first part is mul-free sufficient check
2246 // that the index is within the matrix
2247 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2248 (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2249 CV_Error( CV_StsOutOfRange, "index is out of range" );
2251 ptr = mat->data.ptr + (size_t)idx*pix_size;
2253 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2254 ptr = cvPtr1D( arr, idx, &type );
2256 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2258 if( CV_MAT_CN( type ) > 1 )
2259 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2262 icvSetReal( value, ptr, type );
2267 cvSetReal2D( CvArr* arr, int y, int x, double value )
2272 if( CV_IS_MAT( arr ))
2274 CvMat* mat = (CvMat*)arr;
2276 if( (unsigned)y >= (unsigned)(mat->rows) ||
2277 (unsigned)x >= (unsigned)(mat->cols) )
2278 CV_Error( CV_StsOutOfRange, "index is out of range" );
2280 type = CV_MAT_TYPE(mat->type);
2281 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2283 else if( !CV_IS_SPARSE_MAT( arr ))
2285 ptr = cvPtr2D( arr, y, x, &type );
2289 int idx[] = { y, x };
2290 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2292 if( CV_MAT_CN( type ) > 1 )
2293 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2296 icvSetReal( value, ptr, type );
2301 cvSetReal3D( CvArr* arr, int z, int y, int x, double value )
2306 if( !CV_IS_SPARSE_MAT( arr ))
2307 ptr = cvPtr3D( arr, z, y, x, &type );
2310 int idx[] = { z, y, x };
2311 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2313 if( CV_MAT_CN( type ) > 1 )
2314 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2317 icvSetReal( value, ptr, type );
2322 cvSetRealND( CvArr* arr, const int* idx, double value )
2327 if( !CV_IS_SPARSE_MAT( arr ))
2328 ptr = cvPtrND( arr, idx, &type );
2330 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2332 if( CV_MAT_CN( type ) > 1 )
2333 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2336 icvSetReal( value, ptr, type );
2341 cvClearND( CvArr* arr, const int* idx )
2343 if( !CV_IS_SPARSE_MAT( arr ))
2347 ptr = cvPtrND( arr, idx, &type );
2349 CV_ZERO_CHAR( ptr, CV_ELEM_SIZE(type) );
2352 icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
2356 /****************************************************************************************\
2357 * Conversion to CvMat or IplImage *
2358 \****************************************************************************************/
2360 // convert array (CvMat or IplImage) to CvMat
2362 cvGetMat( const CvArr* array, CvMat* mat,
2363 int* pCOI, int allowND )
2366 CvMat* src = (CvMat*)array;
2370 CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
2372 if( CV_IS_MAT_HDR(src))
2374 if( !src->data.ptr )
2375 CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
2377 result = (CvMat*)src;
2379 else if( CV_IS_IMAGE_HDR(src) )
2381 const IplImage* img = (const IplImage*)src;
2384 if( img->imageData == 0 )
2385 CV_Error( CV_StsNullPtr, "The image has NULL data pointer" );
2387 depth = IplToCvDepth( img->depth );
2389 CV_Error( CV_BadDepth, "" );
2391 order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
2395 if( order == IPL_DATA_ORDER_PLANE )
2399 if( img->roi->coi == 0 )
2400 CV_Error( CV_StsBadFlag,
2401 "Images with planar data layout should be used with COI selected" );
2403 cvInitMatHeader( mat, img->roi->height,
2404 img->roi->width, type,
2405 img->imageData + (img->roi->coi-1)*img->imageSize +
2406 img->roi->yOffset*img->widthStep +
2407 img->roi->xOffset*CV_ELEM_SIZE(type),
2410 else /* pixel order */
2412 int type = CV_MAKETYPE( depth, img->nChannels );
2413 coi = img->roi->coi;
2415 if( img->nChannels > CV_CN_MAX )
2416 CV_Error( CV_BadNumChannels,
2417 "The image is interleaved and has over CV_CN_MAX channels" );
2419 cvInitMatHeader( mat, img->roi->height, img->roi->width,
2420 type, img->imageData +
2421 img->roi->yOffset*img->widthStep +
2422 img->roi->xOffset*CV_ELEM_SIZE(type),
2428 int type = CV_MAKETYPE( depth, img->nChannels );
2430 if( order != IPL_DATA_ORDER_PIXEL )
2431 CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
2433 cvInitMatHeader( mat, img->height, img->width, type,
2434 img->imageData, img->widthStep );
2439 else if( allowND && CV_IS_MATND_HDR(src) )
2441 CvMatND* matnd = (CvMatND*)src;
2443 int size1 = matnd->dim[0].size, size2 = 1;
2445 if( !src->data.ptr )
2446 CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
2448 if( !CV_IS_MAT_CONT( matnd->type ))
2449 CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
2451 if( matnd->dims > 2 )
2452 for( i = 1; i < matnd->dims; i++ )
2453 size2 *= matnd->dim[i].size;
2455 size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
2458 mat->hdr_refcount = 0;
2459 mat->data.ptr = matnd->data.ptr;
2462 mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
2463 mat->step = size2*CV_ELEM_SIZE(matnd->type);
2464 mat->step &= size1 > 1 ? -1 : 0;
2466 icvCheckHuge( mat );
2470 CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" );
2480 cvReshapeMatND( const CvArr* arr,
2481 int sizeof_header, CvArr* _header,
2482 int new_cn, int new_dims, int* new_sizes )
2487 if( !arr || !_header )
2488 CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" );
2490 if( new_cn == 0 && new_dims == 0 )
2491 CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
2493 dims = cvGetDims( arr );
2500 else if( new_dims == 1 )
2506 if( new_dims <= 0 || new_dims > CV_MAX_DIM )
2507 CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
2509 CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" );
2514 CvMat* mat = (CvMat*)arr;
2515 CvMat* header = (CvMat*)_header;
2517 int hdr_refcount = 0;
2518 int total_width, new_rows, cn;
2520 if( sizeof_header != sizeof(CvMat))
2521 CV_Error( CV_StsBadArg, "The header should be CvMat" );
2525 refcount = mat->refcount;
2526 hdr_refcount = mat->hdr_refcount;
2528 else if( !CV_IS_MAT( mat ))
2529 mat = cvGetMat( mat, header, &coi, 1 );
2531 cn = CV_MAT_CN( mat->type );
2532 total_width = mat->cols * cn;
2538 new_rows = new_sizes[0];
2539 else if( new_dims == 1 )
2540 new_rows = total_width*mat->rows/new_cn;
2543 new_rows = mat->rows;
2544 if( new_cn > total_width )
2545 new_rows = mat->rows * total_width / new_cn;
2548 if( new_rows != mat->rows )
2550 int total_size = total_width * mat->rows;
2552 if( !CV_IS_MAT_CONT( mat->type ))
2553 CV_Error( CV_BadStep,
2554 "The matrix is not continuous so the number of rows can not be changed" );
2556 total_width = total_size / new_rows;
2558 if( total_width * new_rows != total_size )
2559 CV_Error( CV_StsBadArg, "The total number of matrix elements "
2560 "is not divisible by the new number of rows" );
2563 header->rows = new_rows;
2564 header->cols = total_width / new_cn;
2566 if( header->cols * new_cn != total_width ||
2567 (new_sizes && header->cols != new_sizes[1]) )
2568 CV_Error( CV_StsBadArg, "The total matrix width is not "
2569 "divisible by the new number of columns" );
2571 header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
2572 header->step = header->cols * CV_ELEM_SIZE(mat->type);
2573 header->step &= new_rows > 1 ? -1 : 0;
2574 header->refcount = refcount;
2575 header->hdr_refcount = hdr_refcount;
2579 CvMatND* header = (CvMatND*)_header;
2581 if( sizeof_header != sizeof(CvMatND))
2582 CV_Error( CV_StsBadSize, "The header should be CvMatND" );
2586 if( !CV_IS_MATND( arr ))
2587 CV_Error( CV_StsBadArg, "The source array must be CvMatND" );
2590 CvMatND* mat = (CvMatND*)arr;
2591 assert( new_cn > 0 );
2592 int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
2593 int new_size = last_dim_size/new_cn;
2595 if( new_size*new_cn != last_dim_size )
2596 CV_Error( CV_StsBadArg,
2597 "The last dimension full size is not divisible by new number of channels");
2601 memcpy( header, mat, sizeof(*header));
2602 header->refcount = 0;
2603 header->hdr_refcount = 0;
2606 header->dim[header->dims-1].size = new_size;
2607 header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn);
2613 CvMatND* mat = (CvMatND*)arr;
2614 int i, size1, size2;
2618 CV_Error( CV_StsBadArg,
2619 "Simultaneous change of shape and number of channels is not supported. "
2620 "Do it by 2 separate calls" );
2622 if( !CV_IS_MATND( mat ))
2624 cvGetMatND( mat, &stub, &coi );
2628 if( CV_IS_MAT_CONT( mat->type ))
2629 CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
2631 size1 = mat->dim[0].size;
2632 for( i = 1; i < dims; i++ )
2633 size1 *= mat->dim[i].size;
2636 for( i = 0; i < new_dims; i++ )
2638 if( new_sizes[i] <= 0 )
2639 CV_Error( CV_StsBadSize,
2640 "One of new dimension sizes is non-positive" );
2641 size2 *= new_sizes[i];
2644 if( size1 != size2 )
2645 CV_Error( CV_StsBadSize,
2646 "Number of elements in the original and reshaped array is different" );
2650 header->refcount = 0;
2651 header->hdr_refcount = 0;
2654 header->dims = new_dims;
2655 header->type = mat->type;
2656 header->data.ptr = mat->data.ptr;
2657 step = CV_ELEM_SIZE(header->type);
2659 for( i = new_dims - 1; i >= 0; i-- )
2661 header->dim[i].size = new_sizes[i];
2662 header->dim[i].step = step;
2663 step *= new_sizes[i];
2669 CV_Error( CV_BadCOI, "COI is not supported by this operation" );
2677 cvReshape( const CvArr* array, CvMat* header,
2678 int new_cn, int new_rows )
2681 CvMat *mat = (CvMat*)array;
2682 int total_width, new_width;
2685 CV_Error( CV_StsNullPtr, "" );
2687 if( !CV_IS_MAT( mat ))
2690 mat = cvGetMat( mat, header, &coi, 1 );
2692 CV_Error( CV_BadCOI, "COI is not supported" );
2696 new_cn = CV_MAT_CN(mat->type);
2697 else if( (unsigned)(new_cn - 1) > 3 )
2698 CV_Error( CV_BadNumChannels, "" );
2702 int hdr_refcount = header->hdr_refcount;
2704 header->refcount = 0;
2705 header->hdr_refcount = hdr_refcount;
2708 total_width = mat->cols * CV_MAT_CN( mat->type );
2710 if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
2711 new_rows = mat->rows * total_width / new_cn;
2713 if( new_rows == 0 || new_rows == mat->rows )
2715 header->rows = mat->rows;
2716 header->step = mat->step;
2720 int total_size = total_width * mat->rows;
2721 if( !CV_IS_MAT_CONT( mat->type ))
2722 CV_Error( CV_BadStep,
2723 "The matrix is not continuous, thus its number of rows can not be changed" );
2725 if( (unsigned)new_rows > (unsigned)total_size )
2726 CV_Error( CV_StsOutOfRange, "Bad new number of rows" );
2728 total_width = total_size / new_rows;
2730 if( total_width * new_rows != total_size )
2731 CV_Error( CV_StsBadArg, "The total number of matrix elements "
2732 "is not divisible by the new number of rows" );
2734 header->rows = new_rows;
2735 header->step = total_width * CV_ELEM_SIZE1(mat->type);
2738 new_width = total_width / new_cn;
2740 if( new_width * new_cn != total_width )
2741 CV_Error( CV_BadNumChannels,
2742 "The total width is not divisible by the new number of channels" );
2744 header->cols = new_width;
2745 header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
2752 // convert array (CvMat or IplImage) to IplImage
2754 cvGetImage( const CvArr* array, IplImage* img )
2756 IplImage* result = 0;
2757 const IplImage* src = (const IplImage*)array;
2761 CV_Error( CV_StsNullPtr, "" );
2763 if( !CV_IS_IMAGE_HDR(src) )
2765 const CvMat* mat = (const CvMat*)src;
2767 if( !CV_IS_MAT_HDR(mat))
2768 CV_Error( CV_StsBadFlag, "" );
2770 if( mat->data.ptr == 0 )
2771 CV_Error( CV_StsNullPtr, "" );
2773 depth = cvIplDepth(mat->type);
2775 cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
2776 depth, CV_MAT_CN(mat->type) );
2777 cvSetData( img, mat->data.ptr, mat->step );
2783 result = (IplImage*)src;
2790 /****************************************************************************************\
2791 * IplImage-specific functions *
2792 \****************************************************************************************/
2794 static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height )
2797 if( !CvIPL.createROI )
2799 roi = (IplROI*)cvAlloc( sizeof(*roi));
2802 roi->xOffset = xOffset;
2803 roi->yOffset = yOffset;
2805 roi->height = height;
2809 roi = CvIPL.createROI( coi, xOffset, yOffset, width, height );
2816 icvGetColorModel( int nchannels, const char** colorModel, const char** channelSeq )
2818 static const char* tab[][2] =
2827 *colorModel = *channelSeq = "";
2829 if( (unsigned)nchannels <= 3 )
2831 *colorModel = tab[nchannels][0];
2832 *channelSeq = tab[nchannels][1];
2837 // create IplImage header
2839 cvCreateImageHeader( CvSize size, int depth, int channels )
2843 if( !CvIPL.createHeader )
2845 img = (IplImage *)cvAlloc( sizeof( *img ));
2846 cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
2847 CV_DEFAULT_IMAGE_ROW_ALIGN );
2851 const char *colorModel, *channelSeq;
2853 icvGetColorModel( channels, &colorModel, &channelSeq );
2855 img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq,
2856 IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
2857 CV_DEFAULT_IMAGE_ROW_ALIGN,
2858 size.width, size.height, 0, 0, 0, 0 );
2865 // create IplImage header and allocate underlying data
2867 cvCreateImage( CvSize size, int depth, int channels )
2869 IplImage *img = cvCreateImageHeader( size, depth, channels );
2871 cvCreateData( img );
2877 // initalize IplImage header, allocated by the user
2879 cvInitImageHeader( IplImage * image, CvSize size, int depth,
2880 int channels, int origin, int align )
2882 const char *colorModel, *channelSeq;
2885 CV_Error( CV_HeaderIsNull, "null pointer to header" );
2887 memset( image, 0, sizeof( *image ));
2888 image->nSize = sizeof( *image );
2890 icvGetColorModel( channels, &colorModel, &channelSeq );
2891 strncpy( image->colorModel, colorModel, 4 );
2892 strncpy( image->channelSeq, channelSeq, 4 );
2894 if( size.width < 0 || size.height < 0 )
2895 CV_Error( CV_BadROISize, "Bad input roi" );
2897 if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U &&
2898 depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U &&
2899 depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S &&
2900 depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) ||
2902 CV_Error( CV_BadDepth, "Unsupported format" );
2903 if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL )
2904 CV_Error( CV_BadOrigin, "Bad input origin" );
2906 if( align != 4 && align != 8 )
2907 CV_Error( CV_BadAlign, "Bad input align" );
2909 image->width = size.width;
2910 image->height = size.height;
2914 image->roi->coi = 0;
2915 image->roi->xOffset = image->roi->yOffset = 0;
2916 image->roi->width = size.width;
2917 image->roi->height = size.height;
2920 image->nChannels = MAX( channels, 1 );
2921 image->depth = depth;
2922 image->align = align;
2923 image->widthStep = (((image->width * image->nChannels *
2924 (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));
2925 image->origin = origin;
2926 image->imageSize = image->widthStep * image->height;
2933 cvReleaseImageHeader( IplImage** image )
2936 CV_Error( CV_StsNullPtr, "" );
2940 IplImage* img = *image;
2943 if( !CvIPL.deallocate )
2945 cvFree( &img->roi );
2950 CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
2957 cvReleaseImage( IplImage ** image )
2960 CV_Error( CV_StsNullPtr, "" );
2964 IplImage* img = *image;
2967 cvReleaseData( img );
2968 cvReleaseImageHeader( &img );
2974 cvSetImageROI( IplImage* image, CvRect rect )
2977 CV_Error( CV_HeaderIsNull, "" );
2979 // allow zero ROI width or height
2980 CV_Assert( rect.width >= 0 && rect.height >= 0 &&
2981 rect.x < image->width && rect.y < image->height &&
2982 rect.x + rect.width >= (int)(rect.width > 0) &&
2983 rect.y + rect.height >= (int)(rect.height > 0) );
2985 rect.width += rect.x;
2986 rect.height += rect.y;
2988 rect.x = std::max(rect.x, 0);
2989 rect.y = std::max(rect.y, 0);
2990 rect.width = std::min(rect.width, image->width);
2991 rect.height = std::min(rect.height, image->height);
2993 rect.width -= rect.x;
2994 rect.height -= rect.y;
2998 image->roi->xOffset = rect.x;
2999 image->roi->yOffset = rect.y;
3000 image->roi->width = rect.width;
3001 image->roi->height = rect.height;
3004 image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height );
3009 cvResetImageROI( IplImage* image )
3012 CV_Error( CV_HeaderIsNull, "" );
3016 if( !CvIPL.deallocate )
3018 cvFree( &image->roi );
3022 CvIPL.deallocate( image, IPL_IMAGE_ROI );
3030 cvGetImageROI( const IplImage* img )
3032 CvRect rect = { 0, 0, 0, 0 };
3034 CV_Error( CV_StsNullPtr, "Null pointer to image" );
3037 rect = cvRect( img->roi->xOffset, img->roi->yOffset,
3038 img->roi->width, img->roi->height );
3040 rect = cvRect( 0, 0, img->width, img->height );
3047 cvSetImageCOI( IplImage* image, int coi )
3050 CV_Error( CV_HeaderIsNull, "" );
3052 if( (unsigned)coi > (unsigned)(image->nChannels) )
3053 CV_Error( CV_BadCOI, "" );
3055 if( image->roi || coi != 0 )
3059 image->roi->coi = coi;
3063 image->roi = icvCreateROI( coi, 0, 0, image->width, image->height );
3070 cvGetImageCOI( const IplImage* image )
3073 CV_Error( CV_HeaderIsNull, "" );
3075 return image->roi ? image->roi->coi : 0;
3080 cvCloneImage( const IplImage* src )
3084 if( !CV_IS_IMAGE_HDR( src ))
3085 CV_Error( CV_StsBadArg, "Bad image header" );
3087 if( !CvIPL.cloneImage )
3089 dst = (IplImage*)cvAlloc( sizeof(*dst));
3091 memcpy( dst, src, sizeof(*src));
3092 dst->imageData = dst->imageDataOrigin = 0;
3097 dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset,
3098 src->roi->yOffset, src->roi->width, src->roi->height );
3101 if( src->imageData )
3103 int size = src->imageSize;
3104 cvCreateData( dst );
3105 memcpy( dst->imageData, src->imageData, size );
3109 dst = CvIPL.cloneImage( src );
3115 /****************************************************************************************\
3116 * Additional operations on CvTermCriteria *
3117 \****************************************************************************************/
3119 CV_IMPL CvTermCriteria
3120 cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
3121 int default_max_iters )
3123 CvTermCriteria crit;
3125 crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
3126 crit.max_iter = default_max_iters;
3127 crit.epsilon = (float)default_eps;
3129 if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 )
3130 CV_Error( CV_StsBadArg,
3131 "Unknown type of term criteria" );
3133 if( (criteria.type & CV_TERMCRIT_ITER) != 0 )
3135 if( criteria.max_iter <= 0 )
3136 CV_Error( CV_StsBadArg,
3137 "Iterations flag is set and maximum number of iterations is <= 0" );
3138 crit.max_iter = criteria.max_iter;
3141 if( (criteria.type & CV_TERMCRIT_EPS) != 0 )
3143 if( criteria.epsilon < 0 )
3144 CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" );
3146 crit.epsilon = criteria.epsilon;
3149 if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 )
3150 CV_Error( CV_StsBadArg,
3151 "Neither accuracy nor maximum iterations "
3152 "number flags are set in criteria type" );
3154 crit.epsilon = (float)MAX( 0, crit.epsilon );
3155 crit.max_iter = MAX( 1, crit.max_iter );