Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
array.cpp
00001 /*M/////////////////////////////////////////////////////////////////////////////////////// 00002 // 00003 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 00004 // 00005 // By downloading, copying, installing or using the software you agree to this license. 00006 // If you do not agree to this license, do not download, install, 00007 // copy or use the software. 00008 // 00009 // 00010 // Intel License Agreement 00011 // For Open Source Computer Vision Library 00012 // 00013 // Copyright (C) 2000, Intel Corporation, all rights reserved. 00014 // Third party copyrights are property of their respective owners. 00015 // 00016 // Redistribution and use in source and binary forms, with or without modification, 00017 // are permitted provided that the following conditions are met: 00018 // 00019 // * Redistribution's of source code must retain the above copyright notice, 00020 // this list of conditions and the following disclaimer. 00021 // 00022 // * Redistribution's in binary form must reproduce the above copyright notice, 00023 // this list of conditions and the following disclaimer in the documentation 00024 // and/or other materials provided with the distribution. 00025 // 00026 // * The name of Intel Corporation may not be used to endorse or promote products 00027 // derived from this software without specific prior written permission. 00028 // 00029 // This software is provided by the copyright holders and contributors "as is" and 00030 // any express or implied warranties, including, but not limited to, the implied 00031 // warranties of merchantability and fitness for a particular purpose are disclaimed. 00032 // In no event shall the Intel Corporation or contributors be liable for any direct, 00033 // indirect, incidental, special, exemplary, or consequential damages 00034 // (including, but not limited to, procurement of substitute goods or services; 00035 // loss of use, data, or profits; or business interruption) however caused 00036 // and on any theory of liability, whether in contract, strict liability, 00037 // or tort (including negligence or otherwise) arising in any way out of 00038 // the use of this software, even if advised of the possibility of such damage. 00039 // 00040 //M*/ 00041 00042 /* //////////////////////////////////////////////////////////////////// 00043 // 00044 // CvMat, CvMatND, CvSparceMat and IplImage support functions 00045 // (creation, deletion, copying, retrieving and setting elements etc.) 00046 // 00047 // */ 00048 00049 #include "precomp.hpp" 00050 00051 #define CV_ORIGIN_TL 0 00052 #define CV_ORIGIN_BL 1 00053 00054 /* default image row align (in bytes) */ 00055 #define CV_DEFAULT_IMAGE_ROW_ALIGN 4 00056 00057 00058 static struct 00059 { 00060 Cv_iplCreateImageHeader createHeader; 00061 Cv_iplAllocateImageData allocateData; 00062 Cv_iplDeallocate deallocate; 00063 Cv_iplCreateROI createROI; 00064 Cv_iplCloneImage cloneImage; 00065 } 00066 CvIPL; 00067 00068 // Makes the library use native IPL image allocators 00069 CV_IMPL void 00070 cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader, 00071 Cv_iplAllocateImageData allocateData, 00072 Cv_iplDeallocate deallocate, 00073 Cv_iplCreateROI createROI, 00074 Cv_iplCloneImage cloneImage ) 00075 { 00076 int count = (createHeader != 0) + (allocateData != 0) + (deallocate != 0) + 00077 (createROI != 0) + (cloneImage != 0); 00078 00079 if( count != 0 && count != 5 ) 00080 CV_Error( CV_StsBadArg, "Either all the pointers should be null or " 00081 "they all should be non-null" ); 00082 00083 CvIPL.createHeader = createHeader; 00084 CvIPL.allocateData = allocateData; 00085 CvIPL.deallocate = deallocate; 00086 CvIPL.createROI = createROI; 00087 CvIPL.cloneImage = cloneImage; 00088 } 00089 00090 00091 /****************************************************************************************\ 00092 * CvMat creation and basic operations * 00093 \****************************************************************************************/ 00094 00095 // Creates CvMat and underlying data 00096 CV_IMPL CvMat* 00097 cvCreateMat( int height, int width, int type ) 00098 { 00099 CvMat* arr = cvCreateMatHeader( height, width, type ); 00100 cvCreateData( arr ); 00101 00102 return arr; 00103 } 00104 00105 00106 static void icvCheckHuge( CvMat* arr ) 00107 { 00108 if( (int64)arr->step*arr->rows > INT_MAX ) 00109 arr->type &= ~CV_MAT_CONT_FLAG; 00110 } 00111 00112 // Creates CvMat header only 00113 CV_IMPL CvMat* 00114 cvCreateMatHeader( int rows, int cols, int type ) 00115 { 00116 type = CV_MAT_TYPE(type); 00117 00118 if( rows < 0 || cols <= 0 ) 00119 CV_Error( CV_StsBadSize, "Non-positive width or height" ); 00120 00121 int min_step = CV_ELEM_SIZE(type)*cols; 00122 if( min_step <= 0 ) 00123 CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" ); 00124 00125 CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr)); 00126 00127 arr->step = min_step; 00128 arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG; 00129 arr->rows = rows; 00130 arr->cols = cols; 00131 arr->data.ptr = 0; 00132 arr->refcount = 0; 00133 arr->hdr_refcount = 1; 00134 00135 icvCheckHuge( arr ); 00136 return arr; 00137 } 00138 00139 00140 // Initializes CvMat header, allocated by the user 00141 CV_IMPL CvMat* 00142 cvInitMatHeader( CvMat* arr, int rows, int cols, 00143 int type, void* data, int step ) 00144 { 00145 if( !arr ) 00146 CV_Error( CV_StsNullPtr, "" ); 00147 00148 if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX ) 00149 CV_Error( CV_BadNumChannels, "" ); 00150 00151 if( rows < 0 || cols <= 0 ) 00152 CV_Error( CV_StsBadSize, "Non-positive cols or rows" ); 00153 00154 type = CV_MAT_TYPE( type ); 00155 arr->type = type | CV_MAT_MAGIC_VAL; 00156 arr->rows = rows; 00157 arr->cols = cols; 00158 arr->data.ptr = (uchar*)data; 00159 arr->refcount = 0; 00160 arr->hdr_refcount = 0; 00161 00162 int pix_size = CV_ELEM_SIZE(type); 00163 int min_step = arr->cols*pix_size; 00164 00165 if( step != CV_AUTOSTEP && step != 0 ) 00166 { 00167 if( step < min_step ) 00168 CV_Error( CV_BadStep, "" ); 00169 arr->step = step; 00170 } 00171 else 00172 { 00173 arr->step = min_step; 00174 } 00175 00176 arr->type = CV_MAT_MAGIC_VAL | type | 00177 (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0); 00178 00179 icvCheckHuge( arr ); 00180 return arr; 00181 } 00182 00183 00184 // Deallocates the CvMat structure and underlying data 00185 CV_IMPL void 00186 cvReleaseMat( CvMat** array ) 00187 { 00188 if( !array ) 00189 CV_Error( CV_HeaderIsNull, "" ); 00190 00191 if( *array ) 00192 { 00193 CvMat* arr = *array; 00194 00195 if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) ) 00196 CV_Error( CV_StsBadFlag, "" ); 00197 00198 *array = 0; 00199 00200 cvDecRefData( arr ); 00201 cvFree( &arr ); 00202 } 00203 } 00204 00205 00206 // Creates a copy of matrix 00207 CV_IMPL CvMat* 00208 cvCloneMat( const CvMat* src ) 00209 { 00210 if( !CV_IS_MAT_HDR( src )) 00211 CV_Error( CV_StsBadArg, "Bad CvMat header" ); 00212 00213 CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type ); 00214 00215 if( src->data.ptr ) 00216 { 00217 cvCreateData( dst ); 00218 cvCopy( src, dst ); 00219 } 00220 00221 return dst; 00222 } 00223 00224 00225 /****************************************************************************************\ 00226 * CvMatND creation and basic operations * 00227 \****************************************************************************************/ 00228 00229 CV_IMPL CvMatND * 00230 cvInitMatNDHeader( CvMatND * mat, int dims, const int* sizes, 00231 int type, void* data ) 00232 { 00233 type = CV_MAT_TYPE(type); 00234 int64 step = CV_ELEM_SIZE(type); 00235 00236 if( !mat ) 00237 CV_Error( CV_StsNullPtr, "NULL matrix header pointer" ); 00238 00239 if( step == 0 ) 00240 CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); 00241 00242 if( !sizes ) 00243 CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" ); 00244 00245 if( dims <= 0 || dims > CV_MAX_DIM ) 00246 CV_Error( CV_StsOutOfRange, 00247 "non-positive or too large number of dimensions" ); 00248 00249 for( int i = dims - 1; i >= 0; i-- ) 00250 { 00251 if( sizes[i] < 0 ) 00252 CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" ); 00253 mat->dim[i].size = sizes[i]; 00254 if( step > INT_MAX ) 00255 CV_Error( CV_StsOutOfRange, "The array is too big" ); 00256 mat->dim[i].step = (int)step; 00257 step *= sizes[i]; 00258 } 00259 00260 mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type; 00261 mat->dims = dims; 00262 mat->data.ptr = (uchar*)data; 00263 mat->refcount = 0; 00264 mat->hdr_refcount = 0; 00265 return mat; 00266 } 00267 00268 00269 // Creates CvMatND and underlying data 00270 CV_IMPL CvMatND * 00271 cvCreateMatND( int dims, const int* sizes, int type ) 00272 { 00273 CvMatND * arr = cvCreateMatNDHeader( dims, sizes, type ); 00274 cvCreateData( arr ); 00275 00276 return arr; 00277 } 00278 00279 00280 // Creates CvMatND header only 00281 CV_IMPL CvMatND * 00282 cvCreateMatNDHeader( int dims, const int* sizes, int type ) 00283 { 00284 if( dims <= 0 || dims > CV_MAX_DIM ) 00285 CV_Error( CV_StsOutOfRange, 00286 "non-positive or too large number of dimensions" ); 00287 00288 CvMatND * arr = (CvMatND *)cvAlloc( sizeof(*arr) ); 00289 00290 cvInitMatNDHeader( arr, dims, sizes, type, 0 ); 00291 arr->hdr_refcount = 1; 00292 return arr; 00293 } 00294 00295 00296 // Creates a copy of nD array 00297 CV_IMPL CvMatND * 00298 cvCloneMatND( const CvMatND * src ) 00299 { 00300 if( !CV_IS_MATND_HDR( src )) 00301 CV_Error( CV_StsBadArg, "Bad CvMatND header" ); 00302 00303 CV_Assert( src->dims <= CV_MAX_DIM ); 00304 int sizes[CV_MAX_DIM]; 00305 00306 for( int i = 0; i < src->dims; i++ ) 00307 sizes[i] = src->dim[i].size; 00308 00309 CvMatND * dst = cvCreateMatNDHeader( src->dims, sizes, src->type ); 00310 00311 if( src->data.ptr ) 00312 { 00313 cvCreateData( dst ); 00314 cv::Mat _src = cv::cvarrToMat(src); 00315 cv::Mat _dst = cv::cvarrToMat(dst); 00316 uchar* data0 = dst->data.ptr; 00317 _src.copyTo(_dst); 00318 CV_Assert(_dst.data == data0); 00319 //cvCopy( src, dst ); 00320 } 00321 00322 return dst; 00323 } 00324 00325 00326 static CvMatND * 00327 cvGetMatND( const CvArr* arr, CvMatND * matnd, int* coi ) 00328 { 00329 CvMatND * result = 0; 00330 00331 if( coi ) 00332 *coi = 0; 00333 00334 if( !matnd || !arr ) 00335 CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); 00336 00337 if( CV_IS_MATND_HDR(arr)) 00338 { 00339 if( !((CvMatND *)arr)->data.ptr ) 00340 CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); 00341 00342 result = (CvMatND *)arr; 00343 } 00344 else 00345 { 00346 CvMat stub, *mat = (CvMat*)arr; 00347 00348 if( CV_IS_IMAGE_HDR( mat )) 00349 mat = cvGetMat( mat, &stub, coi ); 00350 00351 if( !CV_IS_MAT_HDR( mat )) 00352 CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" ); 00353 00354 if( !mat->data.ptr ) 00355 CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); 00356 00357 matnd->data.ptr = mat->data.ptr; 00358 matnd->refcount = 0; 00359 matnd->hdr_refcount = 0; 00360 matnd->type = mat->type; 00361 matnd->dims = 2; 00362 matnd->dim[0].size = mat->rows; 00363 matnd->dim[0].step = mat->step; 00364 matnd->dim[1].size = mat->cols; 00365 matnd->dim[1].step = CV_ELEM_SIZE(mat->type); 00366 result = matnd; 00367 } 00368 00369 return result; 00370 } 00371 00372 00373 // returns number of dimensions to iterate. 00374 /* 00375 Checks whether <count> arrays have equal type, sizes (mask is optional array 00376 that needs to have the same size, but 8uC1 or 8sC1 type). 00377 Returns number of dimensions to iterate through: 00378 0 means that all arrays are continuous, 00379 1 means that all arrays are vectors of continuous arrays etc. 00380 and the size of largest common continuous part of the arrays 00381 */ 00382 CV_IMPL int 00383 cvInitNArrayIterator( int count, CvArr** arrs, 00384 const CvArr* mask, CvMatND * stubs, 00385 CvNArrayIterator* iterator, int flags ) 00386 { 00387 int dims = -1; 00388 int i, j, size, dim0 = -1; 00389 int64 step; 00390 CvMatND * hdr0 = 0; 00391 00392 if( count < 1 || count > CV_MAX_ARR ) 00393 CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" ); 00394 00395 if( !arrs || !stubs ) 00396 CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); 00397 00398 if( !iterator ) 00399 CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" ); 00400 00401 for( i = 0; i <= count; i++ ) 00402 { 00403 const CvArr* arr = i < count ? arrs[i] : mask; 00404 CvMatND * hdr; 00405 00406 if( !arr ) 00407 { 00408 if( i < count ) 00409 CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); 00410 break; 00411 } 00412 00413 if( CV_IS_MATND( arr )) 00414 hdr = (CvMatND *)arr; 00415 else 00416 { 00417 int coi = 0; 00418 hdr = cvGetMatND( arr, stubs + i, &coi ); 00419 if( coi != 0 ) 00420 CV_Error( CV_BadCOI, "COI set is not allowed here" ); 00421 } 00422 00423 iterator->hdr[i] = hdr; 00424 00425 if( i > 0 ) 00426 { 00427 if( hdr->dims != hdr0->dims ) 00428 CV_Error( CV_StsUnmatchedSizes, 00429 "Number of dimensions is the same for all arrays" ); 00430 00431 if( i < count ) 00432 { 00433 switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK)) 00434 { 00435 case 0: 00436 if( !CV_ARE_TYPES_EQ( hdr, hdr0 )) 00437 CV_Error( CV_StsUnmatchedFormats, 00438 "Data type is not the same for all arrays" ); 00439 break; 00440 case CV_NO_DEPTH_CHECK: 00441 if( !CV_ARE_CNS_EQ( hdr, hdr0 )) 00442 CV_Error( CV_StsUnmatchedFormats, 00443 "Number of channels is not the same for all arrays" ); 00444 break; 00445 case CV_NO_CN_CHECK: 00446 if( !CV_ARE_CNS_EQ( hdr, hdr0 )) 00447 CV_Error( CV_StsUnmatchedFormats, 00448 "Depth is not the same for all arrays" ); 00449 break; 00450 } 00451 } 00452 else 00453 { 00454 if( !CV_IS_MASK_ARR( hdr )) 00455 CV_Error( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" ); 00456 } 00457 00458 if( !(flags & CV_NO_SIZE_CHECK) ) 00459 { 00460 for( j = 0; j < hdr->dims; j++ ) 00461 if( hdr->dim[j].size != hdr0->dim[j].size ) 00462 CV_Error( CV_StsUnmatchedSizes, 00463 "Dimension sizes are the same for all arrays" ); 00464 } 00465 } 00466 else 00467 hdr0 = hdr; 00468 00469 step = CV_ELEM_SIZE(hdr->type); 00470 for( j = hdr->dims - 1; j > dim0; j-- ) 00471 { 00472 if( step != hdr->dim[j].step ) 00473 break; 00474 step *= hdr->dim[j].size; 00475 } 00476 00477 if( j == dim0 && step > INT_MAX ) 00478 j++; 00479 00480 if( j > dim0 ) 00481 dim0 = j; 00482 00483 iterator->hdr[i] = (CvMatND *)hdr; 00484 iterator->ptr[i] = (uchar*)hdr->data.ptr; 00485 } 00486 00487 size = 1; 00488 for( j = hdr0->dims - 1; j > dim0; j-- ) 00489 size *= hdr0->dim[j].size; 00490 00491 dims = dim0 + 1; 00492 iterator->dims = dims; 00493 iterator->count = count; 00494 iterator->size = cvSize(size,1); 00495 00496 for( i = 0; i < dims; i++ ) 00497 iterator->stack[i] = hdr0->dim[i].size; 00498 00499 return dims; 00500 } 00501 00502 00503 // returns zero value if iteration is finished, non-zero otherwise 00504 CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator ) 00505 { 00506 assert( iterator != 0 ); 00507 int i, dims; 00508 00509 for( dims = iterator->dims; dims > 0; dims-- ) 00510 { 00511 for( i = 0; i < iterator->count; i++ ) 00512 iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step; 00513 00514 if( --iterator->stack[dims-1] > 0 ) 00515 break; 00516 00517 const int size = iterator->hdr[0]->dim[dims-1].size; 00518 00519 for( i = 0; i < iterator->count; i++ ) 00520 iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step; 00521 00522 iterator->stack[dims-1] = size; 00523 } 00524 00525 return dims > 0; 00526 } 00527 00528 00529 /****************************************************************************************\ 00530 * CvSparseMat creation and basic operations * 00531 \****************************************************************************************/ 00532 00533 00534 // Creates CvMatND and underlying data 00535 CV_IMPL CvSparseMat* 00536 cvCreateSparseMat( int dims, const int* sizes, int type ) 00537 { 00538 type = CV_MAT_TYPE( type ); 00539 int pix_size1 = CV_ELEM_SIZE1(type); 00540 int pix_size = pix_size1*CV_MAT_CN(type); 00541 int i, size; 00542 CvMemStorage* storage; 00543 00544 if( pix_size == 0 ) 00545 CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); 00546 00547 if( dims <= 0 || dims > CV_MAX_DIM_HEAP ) 00548 CV_Error( CV_StsOutOfRange, "bad number of dimensions" ); 00549 00550 if( !sizes ) 00551 CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" ); 00552 00553 for( i = 0; i < dims; i++ ) 00554 { 00555 if( sizes[i] <= 0 ) 00556 CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" ); 00557 } 00558 00559 CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])); 00560 00561 arr->type = CV_SPARSE_MAT_MAGIC_VAL | type; 00562 arr->dims = dims; 00563 arr->refcount = 0; 00564 arr->hdr_refcount = 1; 00565 memcpy( arr->size, sizes, dims*sizeof(sizes[0])); 00566 00567 arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1); 00568 arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int)); 00569 size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem)); 00570 00571 storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK ); 00572 arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ); 00573 00574 arr->hashsize = CV_SPARSE_HASH_SIZE0; 00575 size = arr->hashsize*sizeof(arr->hashtable[0]); 00576 00577 arr->hashtable = (void**)cvAlloc( size ); 00578 memset( arr->hashtable, 0, size ); 00579 00580 return arr; 00581 } 00582 00583 00584 // Creates CvMatND and underlying data 00585 CV_IMPL void 00586 cvReleaseSparseMat( CvSparseMat** array ) 00587 { 00588 if( !array ) 00589 CV_Error( CV_HeaderIsNull, "" ); 00590 00591 if( *array ) 00592 { 00593 CvSparseMat* arr = *array; 00594 00595 if( !CV_IS_SPARSE_MAT_HDR(arr) ) 00596 CV_Error( CV_StsBadFlag, "" ); 00597 00598 *array = 0; 00599 00600 CvMemStorage* storage = arr->heap->storage; 00601 cvReleaseMemStorage( &storage ); 00602 cvFree( &arr->hashtable ); 00603 cvFree( &arr ); 00604 } 00605 } 00606 00607 00608 // Creates CvMatND and underlying data 00609 CV_IMPL CvSparseMat* 00610 cvCloneSparseMat( const CvSparseMat* src ) 00611 { 00612 if( !CV_IS_SPARSE_MAT_HDR(src) ) 00613 CV_Error( CV_StsBadArg, "Invalid sparse array header" ); 00614 00615 CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type ); 00616 cvCopy( src, dst ); 00617 return dst; 00618 } 00619 00620 00621 CvSparseNode* 00622 cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator ) 00623 { 00624 CvSparseNode* node = 0; 00625 int idx; 00626 00627 if( !CV_IS_SPARSE_MAT( mat )) 00628 CV_Error( CV_StsBadArg, "Invalid sparse matrix header" ); 00629 00630 if( !iterator ) 00631 CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); 00632 00633 iterator->mat = (CvSparseMat*)mat; 00634 iterator->node = 0; 00635 00636 for( idx = 0; idx < mat->hashsize; idx++ ) 00637 if( mat->hashtable[idx] ) 00638 { 00639 node = iterator->node = (CvSparseNode*)mat->hashtable[idx]; 00640 break; 00641 } 00642 00643 iterator->curidx = idx; 00644 return node; 00645 } 00646 00647 #define ICV_SPARSE_MAT_HASH_MULTIPLIER cv::SparseMat::HASH_SCALE 00648 00649 static uchar* 00650 icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type, 00651 int create_node, unsigned* precalc_hashval ) 00652 { 00653 uchar* ptr = 0; 00654 int i, tabidx; 00655 unsigned hashval = 0; 00656 CvSparseNode *node; 00657 assert( CV_IS_SPARSE_MAT( mat )); 00658 00659 if( !precalc_hashval ) 00660 { 00661 for( i = 0; i < mat->dims; i++ ) 00662 { 00663 int t = idx[i]; 00664 if( (unsigned)t >= (unsigned)mat->size[i] ) 00665 CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); 00666 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; 00667 } 00668 } 00669 else 00670 { 00671 hashval = *precalc_hashval; 00672 } 00673 00674 tabidx = hashval & (mat->hashsize - 1); 00675 hashval &= INT_MAX; 00676 00677 if( create_node >= -1 ) 00678 { 00679 for( node = (CvSparseNode*)mat->hashtable[tabidx]; 00680 node != 0; node = node->next ) 00681 { 00682 if( node->hashval == hashval ) 00683 { 00684 int* nodeidx = CV_NODE_IDX(mat,node); 00685 for( i = 0; i < mat->dims; i++ ) 00686 if( idx[i] != nodeidx[i] ) 00687 break; 00688 if( i == mat->dims ) 00689 { 00690 ptr = (uchar*)CV_NODE_VAL(mat,node); 00691 break; 00692 } 00693 } 00694 } 00695 } 00696 00697 if( !ptr && create_node ) 00698 { 00699 if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO ) 00700 { 00701 void** newtable; 00702 int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0); 00703 int newrawsize = newsize*sizeof(newtable[0]); 00704 00705 CvSparseMatIterator iterator; 00706 assert( (newsize & (newsize - 1)) == 0 ); 00707 00708 // resize hash table 00709 newtable = (void**)cvAlloc( newrawsize ); 00710 memset( newtable, 0, newrawsize ); 00711 00712 node = cvInitSparseMatIterator( mat, &iterator ); 00713 while( node ) 00714 { 00715 CvSparseNode* next = cvGetNextSparseNode( &iterator ); 00716 int newidx = node->hashval & (newsize - 1); 00717 node->next = (CvSparseNode*)newtable[newidx]; 00718 newtable[newidx] = node; 00719 node = next; 00720 } 00721 00722 cvFree( &mat->hashtable ); 00723 mat->hashtable = newtable; 00724 mat->hashsize = newsize; 00725 tabidx = hashval & (newsize - 1); 00726 } 00727 00728 node = (CvSparseNode*)cvSetNew( mat->heap ); 00729 node->hashval = hashval; 00730 node->next = (CvSparseNode*)mat->hashtable[tabidx]; 00731 mat->hashtable[tabidx] = node; 00732 memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0])); 00733 ptr = (uchar*)CV_NODE_VAL(mat,node); 00734 if( create_node > 0 ) 00735 memset( ptr, 0, CV_ELEM_SIZE(mat->type)); 00736 } 00737 00738 if( _type ) 00739 *_type = CV_MAT_TYPE(mat->type); 00740 00741 return ptr; 00742 } 00743 00744 00745 static void 00746 icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval ) 00747 { 00748 int i, tabidx; 00749 unsigned hashval = 0; 00750 CvSparseNode *node, *prev = 0; 00751 assert( CV_IS_SPARSE_MAT( mat )); 00752 00753 if( !precalc_hashval ) 00754 { 00755 for( i = 0; i < mat->dims; i++ ) 00756 { 00757 int t = idx[i]; 00758 if( (unsigned)t >= (unsigned)mat->size[i] ) 00759 CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); 00760 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; 00761 } 00762 } 00763 else 00764 { 00765 hashval = *precalc_hashval; 00766 } 00767 00768 tabidx = hashval & (mat->hashsize - 1); 00769 hashval &= INT_MAX; 00770 00771 for( node = (CvSparseNode*)mat->hashtable[tabidx]; 00772 node != 0; prev = node, node = node->next ) 00773 { 00774 if( node->hashval == hashval ) 00775 { 00776 int* nodeidx = CV_NODE_IDX(mat,node); 00777 for( i = 0; i < mat->dims; i++ ) 00778 if( idx[i] != nodeidx[i] ) 00779 break; 00780 if( i == mat->dims ) 00781 break; 00782 } 00783 } 00784 00785 if( node ) 00786 { 00787 if( prev ) 00788 prev->next = node->next; 00789 else 00790 mat->hashtable[tabidx] = node->next; 00791 cvSetRemoveByPtr( mat->heap, node ); 00792 } 00793 } 00794 00795 00796 /****************************************************************************************\ 00797 * Common for multiple array types operations * 00798 \****************************************************************************************/ 00799 00800 // Allocates underlying array data 00801 CV_IMPL void 00802 cvCreateData( CvArr* arr ) 00803 { 00804 if( CV_IS_MAT_HDR_Z( arr )) 00805 { 00806 size_t step, total_size; 00807 CvMat* mat = (CvMat*)arr; 00808 step = mat->step; 00809 00810 if( mat->rows == 0 || mat->cols == 0 ) 00811 return; 00812 00813 if( mat->data.ptr != 0 ) 00814 CV_Error( CV_StsError, "Data is already allocated" ); 00815 00816 if( step == 0 ) 00817 step = CV_ELEM_SIZE(mat->type)*mat->cols; 00818 00819 int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN; 00820 total_size = (size_t)_total_size; 00821 if(_total_size != (int64)total_size) 00822 CV_Error(CV_StsNoMem, "Too big buffer is allocated" ); 00823 mat->refcount = (int*)cvAlloc( (size_t)total_size ); 00824 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); 00825 *mat->refcount = 1; 00826 } 00827 else if( CV_IS_IMAGE_HDR(arr)) 00828 { 00829 IplImage* img = (IplImage*)arr; 00830 00831 if( img->imageData != 0 ) 00832 CV_Error( CV_StsError, "Data is already allocated" ); 00833 00834 if( !CvIPL.allocateData ) 00835 { 00836 img->imageData = img->imageDataOrigin = 00837 (char*)cvAlloc( (size_t)img->imageSize ); 00838 } 00839 else 00840 { 00841 int depth = img->depth; 00842 int width = img->width; 00843 00844 if( img->depth == IPL_DEPTH_32F || img->depth == IPL_DEPTH_64F ) 00845 { 00846 img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double); 00847 img->depth = IPL_DEPTH_8U; 00848 } 00849 00850 CvIPL.allocateData( img, 0, 0 ); 00851 00852 img->width = width; 00853 img->depth = depth; 00854 } 00855 } 00856 else if( CV_IS_MATND_HDR( arr )) 00857 { 00858 CvMatND * mat = (CvMatND *)arr; 00859 size_t total_size = CV_ELEM_SIZE(mat->type); 00860 00861 if( mat->dim[0].size == 0 ) 00862 return; 00863 00864 if( mat->data.ptr != 0 ) 00865 CV_Error( CV_StsError, "Data is already allocated" ); 00866 00867 if( CV_IS_MAT_CONT( mat->type )) 00868 { 00869 total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ? 00870 (size_t)mat->dim[0].step : total_size); 00871 } 00872 else 00873 { 00874 int i; 00875 for( i = mat->dims - 1; i >= 0; i-- ) 00876 { 00877 size_t size = (size_t)mat->dim[i].step*mat->dim[i].size; 00878 00879 if( total_size < size ) 00880 total_size = size; 00881 } 00882 } 00883 00884 mat->refcount = (int*)cvAlloc( total_size + 00885 sizeof(int) + CV_MALLOC_ALIGN ); 00886 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); 00887 *mat->refcount = 1; 00888 } 00889 else 00890 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 00891 } 00892 00893 00894 // Assigns external data to array 00895 CV_IMPL void 00896 cvSetData( CvArr* arr, void* data, int step ) 00897 { 00898 int pix_size, min_step; 00899 00900 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) ) 00901 cvReleaseData( arr ); 00902 00903 if( CV_IS_MAT_HDR( arr )) 00904 { 00905 CvMat* mat = (CvMat*)arr; 00906 00907 int type = CV_MAT_TYPE(mat->type); 00908 pix_size = CV_ELEM_SIZE(type); 00909 min_step = mat->cols*pix_size; 00910 00911 if( step != CV_AUTOSTEP && step != 0 ) 00912 { 00913 if( step < min_step && data != 0 ) 00914 CV_Error( CV_BadStep, "" ); 00915 mat->step = step; 00916 } 00917 else 00918 mat->step = min_step; 00919 00920 mat->data.ptr = (uchar*)data; 00921 mat->type = CV_MAT_MAGIC_VAL | type | 00922 (mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0); 00923 icvCheckHuge( mat ); 00924 } 00925 else if( CV_IS_IMAGE_HDR( arr )) 00926 { 00927 IplImage* img = (IplImage*)arr; 00928 00929 pix_size = ((img->depth & 255) >> 3)*img->nChannels; 00930 min_step = img->width*pix_size; 00931 00932 if( step != CV_AUTOSTEP && img->height > 1 ) 00933 { 00934 if( step < min_step && data != 0 ) 00935 CV_Error( CV_BadStep, "" ); 00936 img->widthStep = step; 00937 } 00938 else 00939 { 00940 img->widthStep = min_step; 00941 } 00942 00943 img->imageSize = img->widthStep * img->height; 00944 img->imageData = img->imageDataOrigin = (char*)data; 00945 00946 if( (((int)(size_t)data | step) & 7) == 0 && 00947 cvAlign(img->width * pix_size, 8) == step ) 00948 img->align = 8; 00949 else 00950 img->align = 4; 00951 } 00952 else if( CV_IS_MATND_HDR( arr )) 00953 { 00954 CvMatND * mat = (CvMatND *)arr; 00955 int i; 00956 int64 cur_step; 00957 00958 if( step != CV_AUTOSTEP ) 00959 CV_Error( CV_BadStep, 00960 "For multidimensional array only CV_AUTOSTEP is allowed here" ); 00961 00962 mat->data.ptr = (uchar*)data; 00963 cur_step = CV_ELEM_SIZE(mat->type); 00964 00965 for( i = mat->dims - 1; i >= 0; i-- ) 00966 { 00967 if( cur_step > INT_MAX ) 00968 CV_Error( CV_StsOutOfRange, "The array is too big" ); 00969 mat->dim[i].step = (int)cur_step; 00970 cur_step *= mat->dim[i].size; 00971 } 00972 } 00973 else 00974 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 00975 } 00976 00977 00978 // Deallocates array's data 00979 CV_IMPL void 00980 cvReleaseData( CvArr* arr ) 00981 { 00982 if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr )) 00983 { 00984 CvMat* mat = (CvMat*)arr; 00985 cvDecRefData( mat ); 00986 } 00987 else if( CV_IS_IMAGE_HDR( arr )) 00988 { 00989 IplImage* img = (IplImage*)arr; 00990 00991 if( !CvIPL.deallocate ) 00992 { 00993 char* ptr = img->imageDataOrigin; 00994 img->imageData = img->imageDataOrigin = 0; 00995 cvFree( &ptr ); 00996 } 00997 else 00998 { 00999 CvIPL.deallocate( img, IPL_IMAGE_DATA ); 01000 } 01001 } 01002 else 01003 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01004 } 01005 01006 01007 // Retrieves essential information about image ROI or CvMat data 01008 CV_IMPL void 01009 cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) 01010 { 01011 if( CV_IS_MAT( arr )) 01012 { 01013 CvMat *mat = (CvMat*)arr; 01014 01015 if( step ) 01016 *step = mat->step; 01017 01018 if( data ) 01019 *data = mat->data.ptr; 01020 01021 if( roi_size ) 01022 *roi_size = cvGetMatSize( mat ); 01023 } 01024 else if( CV_IS_IMAGE( arr )) 01025 { 01026 IplImage* img = (IplImage*)arr; 01027 01028 if( step ) 01029 *step = img->widthStep; 01030 01031 if( data ) 01032 *data = cvPtr2D( img, 0, 0 ); 01033 01034 if( roi_size ) 01035 { 01036 if( img->roi ) 01037 { 01038 *roi_size = cvSize( img->roi->width, img->roi->height ); 01039 } 01040 else 01041 { 01042 *roi_size = cvSize( img->width, img->height ); 01043 } 01044 } 01045 } 01046 else if( CV_IS_MATND( arr )) 01047 { 01048 CvMatND * mat = (CvMatND *)arr; 01049 01050 if( !CV_IS_MAT_CONT( mat->type )) 01051 CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); 01052 01053 if( data ) 01054 *data = mat->data.ptr; 01055 01056 if( roi_size || step ) 01057 { 01058 if( roi_size ) 01059 { 01060 int size1 = mat->dim[0].size, size2 = 1; 01061 01062 if( mat->dims > 2 ) 01063 { 01064 int i; 01065 for( i = 1; i < mat->dims; i++ ) 01066 size1 *= mat->dim[i].size; 01067 } 01068 else 01069 size2 = mat->dim[1].size; 01070 01071 roi_size->width = size2; 01072 roi_size->height = size1; 01073 } 01074 01075 if( step ) 01076 *step = mat->dim[0].step; 01077 } 01078 } 01079 else 01080 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01081 } 01082 01083 01084 CV_IMPL int 01085 cvGetElemType( const CvArr* arr ) 01086 { 01087 int type = -1; 01088 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr)) 01089 type = CV_MAT_TYPE( ((CvMat*)arr)->type ); 01090 else if( CV_IS_IMAGE(arr)) 01091 { 01092 IplImage* img = (IplImage*)arr; 01093 type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels ); 01094 } 01095 else 01096 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01097 01098 return type; 01099 } 01100 01101 01102 // Returns a number of array dimensions 01103 CV_IMPL int 01104 cvGetDims( const CvArr* arr, int* sizes ) 01105 { 01106 int dims = -1; 01107 if( CV_IS_MAT_HDR( arr )) 01108 { 01109 CvMat* mat = (CvMat*)arr; 01110 01111 dims = 2; 01112 if( sizes ) 01113 { 01114 sizes[0] = mat->rows; 01115 sizes[1] = mat->cols; 01116 } 01117 } 01118 else if( CV_IS_IMAGE( arr )) 01119 { 01120 IplImage* img = (IplImage*)arr; 01121 dims = 2; 01122 01123 if( sizes ) 01124 { 01125 sizes[0] = img->height; 01126 sizes[1] = img->width; 01127 } 01128 } 01129 else if( CV_IS_MATND_HDR( arr )) 01130 { 01131 CvMatND * mat = (CvMatND *)arr; 01132 dims = mat->dims; 01133 01134 if( sizes ) 01135 { 01136 int i; 01137 for( i = 0; i < dims; i++ ) 01138 sizes[i] = mat->dim[i].size; 01139 } 01140 } 01141 else if( CV_IS_SPARSE_MAT_HDR( arr )) 01142 { 01143 CvSparseMat* mat = (CvSparseMat*)arr; 01144 dims = mat->dims; 01145 01146 if( sizes ) 01147 memcpy( sizes, mat->size, dims*sizeof(sizes[0])); 01148 } 01149 else 01150 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01151 01152 return dims; 01153 } 01154 01155 01156 // Returns the size of particular array dimension 01157 CV_IMPL int 01158 cvGetDimSize( const CvArr* arr, int index ) 01159 { 01160 int size = -1; 01161 01162 if( CV_IS_MAT( arr )) 01163 { 01164 CvMat *mat = (CvMat*)arr; 01165 01166 switch( index ) 01167 { 01168 case 0: 01169 size = mat->rows; 01170 break; 01171 case 1: 01172 size = mat->cols; 01173 break; 01174 default: 01175 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 01176 } 01177 } 01178 else if( CV_IS_IMAGE( arr )) 01179 { 01180 IplImage* img = (IplImage*)arr; 01181 01182 switch( index ) 01183 { 01184 case 0: 01185 size = !img->roi ? img->height : img->roi->height; 01186 break; 01187 case 1: 01188 size = !img->roi ? img->width : img->roi->width; 01189 break; 01190 default: 01191 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 01192 } 01193 } 01194 else if( CV_IS_MATND_HDR( arr )) 01195 { 01196 CvMatND * mat = (CvMatND *)arr; 01197 01198 if( (unsigned)index >= (unsigned)mat->dims ) 01199 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 01200 01201 size = mat->dim[index].size; 01202 } 01203 else if( CV_IS_SPARSE_MAT_HDR( arr )) 01204 { 01205 CvSparseMat* mat = (CvSparseMat*)arr; 01206 01207 if( (unsigned)index >= (unsigned)mat->dims ) 01208 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 01209 01210 size = mat->size[index]; 01211 } 01212 else 01213 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01214 01215 return size; 01216 } 01217 01218 01219 // Returns the size of CvMat or IplImage 01220 CV_IMPL CvSize 01221 cvGetSize( const CvArr* arr ) 01222 { 01223 CvSize size; 01224 01225 if( CV_IS_MAT_HDR_Z( arr )) 01226 { 01227 CvMat *mat = (CvMat*)arr; 01228 01229 size.width = mat->cols; 01230 size.height = mat->rows; 01231 } 01232 else if( CV_IS_IMAGE_HDR( arr )) 01233 { 01234 IplImage* img = (IplImage*)arr; 01235 01236 if( img->roi ) 01237 { 01238 size.width = img->roi->width; 01239 size.height = img->roi->height; 01240 } 01241 else 01242 { 01243 size.width = img->width; 01244 size.height = img->height; 01245 } 01246 } 01247 else 01248 CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" ); 01249 01250 return size; 01251 } 01252 01253 01254 // Selects sub-array (no data is copied) 01255 CV_IMPL CvMat* 01256 cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ) 01257 { 01258 CvMat* res = 0; 01259 CvMat stub, *mat = (CvMat*)arr; 01260 01261 if( !CV_IS_MAT( mat )) 01262 mat = cvGetMat( mat, &stub ); 01263 01264 if( !submat ) 01265 CV_Error( CV_StsNullPtr, "" ); 01266 01267 if( (rect.x|rect.y|rect.width|rect.height) < 0 ) 01268 CV_Error( CV_StsBadSize, "" ); 01269 01270 if( rect.x + rect.width > mat->cols || 01271 rect.y + rect.height > mat->rows ) 01272 CV_Error( CV_StsBadSize, "" ); 01273 01274 { 01275 /* 01276 int* refcount = mat->refcount; 01277 01278 if( refcount ) 01279 ++*refcount; 01280 01281 cvDecRefData( submat ); 01282 */ 01283 submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step + 01284 rect.x*CV_ELEM_SIZE(mat->type); 01285 submat->step = mat->step; 01286 submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) | 01287 (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0); 01288 submat->rows = rect.height; 01289 submat->cols = rect.width; 01290 submat->refcount = 0; 01291 res = submat; 01292 } 01293 01294 return res; 01295 } 01296 01297 01298 // Selects array's row span. 01299 CV_IMPL CvMat* 01300 cvGetRows( const CvArr* arr, CvMat* submat, 01301 int start_row, int end_row, int delta_row ) 01302 { 01303 CvMat* res = 0; 01304 CvMat stub, *mat = (CvMat*)arr; 01305 01306 if( !CV_IS_MAT( mat )) 01307 mat = cvGetMat( mat, &stub ); 01308 01309 if( !submat ) 01310 CV_Error( CV_StsNullPtr, "" ); 01311 01312 if( (unsigned)start_row >= (unsigned)mat->rows || 01313 (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 ) 01314 CV_Error( CV_StsOutOfRange, "" ); 01315 01316 { 01317 /* 01318 int* refcount = mat->refcount; 01319 01320 if( refcount ) 01321 ++*refcount; 01322 01323 cvDecRefData( submat ); 01324 */ 01325 if( delta_row == 1 ) 01326 { 01327 submat->rows = end_row - start_row; 01328 submat->step = mat->step; 01329 } 01330 else 01331 { 01332 submat->rows = (end_row - start_row + delta_row - 1)/delta_row; 01333 submat->step = mat->step * delta_row; 01334 } 01335 01336 submat->cols = mat->cols; 01337 submat->step &= submat->rows > 1 ? -1 : 0; 01338 submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step; 01339 submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) & 01340 (delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1); 01341 submat->refcount = 0; 01342 submat->hdr_refcount = 0; 01343 res = submat; 01344 } 01345 01346 return res; 01347 } 01348 01349 01350 // Selects array's column span. 01351 CV_IMPL CvMat* 01352 cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ) 01353 { 01354 CvMat* res = 0; 01355 CvMat stub, *mat = (CvMat*)arr; 01356 int cols; 01357 01358 if( !CV_IS_MAT( mat )) 01359 mat = cvGetMat( mat, &stub ); 01360 01361 if( !submat ) 01362 CV_Error( CV_StsNullPtr, "" ); 01363 01364 cols = mat->cols; 01365 if( (unsigned)start_col >= (unsigned)cols || 01366 (unsigned)end_col > (unsigned)cols ) 01367 CV_Error( CV_StsOutOfRange, "" ); 01368 01369 { 01370 /* 01371 int* refcount = mat->refcount; 01372 01373 if( refcount ) 01374 ++*refcount; 01375 01376 cvDecRefData( submat ); 01377 */ 01378 submat->rows = mat->rows; 01379 submat->cols = end_col - start_col; 01380 submat->step = mat->step; 01381 submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type); 01382 submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1); 01383 submat->refcount = 0; 01384 submat->hdr_refcount = 0; 01385 res = submat; 01386 } 01387 01388 return res; 01389 } 01390 01391 01392 // Selects array diagonal 01393 CV_IMPL CvMat* 01394 cvGetDiag( const CvArr* arr, CvMat* submat, int diag ) 01395 { 01396 CvMat* res = 0; 01397 CvMat stub, *mat = (CvMat*)arr; 01398 int len, pix_size; 01399 01400 if( !CV_IS_MAT( mat )) 01401 mat = cvGetMat( mat, &stub ); 01402 01403 if( !submat ) 01404 CV_Error( CV_StsNullPtr, "" ); 01405 01406 pix_size = CV_ELEM_SIZE(mat->type); 01407 01408 /*{ 01409 int* refcount = mat->refcount; 01410 01411 if( refcount ) 01412 ++*refcount; 01413 01414 cvDecRefData( submat ); 01415 }*/ 01416 01417 if( diag >= 0 ) 01418 { 01419 len = mat->cols - diag; 01420 01421 if( len <= 0 ) 01422 CV_Error( CV_StsOutOfRange, "" ); 01423 01424 len = CV_IMIN( len, mat->rows ); 01425 submat->data.ptr = mat->data.ptr + diag*pix_size; 01426 } 01427 else 01428 { 01429 len = mat->rows + diag; 01430 01431 if( len <= 0 ) 01432 CV_Error( CV_StsOutOfRange, "" ); 01433 01434 len = CV_IMIN( len, mat->cols ); 01435 submat->data.ptr = mat->data.ptr - diag*mat->step; 01436 } 01437 01438 submat->rows = len; 01439 submat->cols = 1; 01440 submat->step = mat->step + (submat->rows > 1 ? pix_size : 0); 01441 submat->type = mat->type; 01442 if( submat->rows > 1 ) 01443 submat->type &= ~CV_MAT_CONT_FLAG; 01444 else 01445 submat->type |= CV_MAT_CONT_FLAG; 01446 submat->refcount = 0; 01447 submat->hdr_refcount = 0; 01448 res = submat; 01449 01450 return res; 01451 } 01452 01453 01454 /****************************************************************************************\ 01455 * Operations on CvScalar and accessing array elements * 01456 \****************************************************************************************/ 01457 01458 // Converts CvScalar to specified type 01459 CV_IMPL void 01460 cvScalarToRawData( const CvScalar * scalar, void* data, int type, int extend_to_12 ) 01461 { 01462 type = CV_MAT_TYPE(type); 01463 int cn = CV_MAT_CN( type ); 01464 int depth = type & CV_MAT_DEPTH_MASK; 01465 01466 assert( scalar && data ); 01467 if( (unsigned)(cn - 1) >= 4 ) 01468 CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); 01469 01470 switch( depth ) 01471 { 01472 case CV_8UC1: 01473 while( cn-- ) 01474 { 01475 int t = cvRound( scalar->val[cn] ); 01476 ((uchar*)data)[cn] = cv::saturate_cast<uchar>(t); 01477 } 01478 break; 01479 case CV_8SC1: 01480 while( cn-- ) 01481 { 01482 int t = cvRound( scalar->val[cn] ); 01483 ((char*)data)[cn] = cv::saturate_cast<schar>(t); 01484 } 01485 break; 01486 case CV_16UC1: 01487 while( cn-- ) 01488 { 01489 int t = cvRound( scalar->val[cn] ); 01490 ((ushort*)data)[cn] = cv::saturate_cast<ushort>(t); 01491 } 01492 break; 01493 case CV_16SC1: 01494 while( cn-- ) 01495 { 01496 int t = cvRound( scalar->val[cn] ); 01497 ((short*)data)[cn] = cv::saturate_cast<short>(t); 01498 } 01499 break; 01500 case CV_32SC1: 01501 while( cn-- ) 01502 ((int*)data)[cn] = cvRound( scalar->val[cn] ); 01503 break; 01504 case CV_32FC1: 01505 while( cn-- ) 01506 ((float*)data)[cn] = (float)(scalar->val[cn]); 01507 break; 01508 case CV_64FC1: 01509 while( cn-- ) 01510 ((double*)data)[cn] = (double)(scalar->val[cn]); 01511 break; 01512 default: 01513 assert(0); 01514 CV_Error( CV_BadDepth, "" ); 01515 } 01516 01517 if( extend_to_12 ) 01518 { 01519 int pix_size = CV_ELEM_SIZE(type); 01520 int offset = CV_ELEM_SIZE1(depth)*12; 01521 01522 do 01523 { 01524 offset -= pix_size; 01525 memcpy((char*)data + offset, data, pix_size); 01526 } 01527 while( offset > pix_size ); 01528 } 01529 } 01530 01531 01532 // Converts data of specified type to CvScalar 01533 CV_IMPL void 01534 cvRawDataToScalar( const void* data, int flags, CvScalar * scalar ) 01535 { 01536 int cn = CV_MAT_CN( flags ); 01537 01538 assert( scalar && data ); 01539 01540 if( (unsigned)(cn - 1) >= 4 ) 01541 CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); 01542 01543 memset( scalar->val, 0, sizeof(scalar->val)); 01544 01545 switch( CV_MAT_DEPTH( flags )) 01546 { 01547 case CV_8U: 01548 while( cn-- ) 01549 scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]); 01550 break; 01551 case CV_8S: 01552 while( cn-- ) 01553 scalar->val[cn] = CV_8TO32F(((char*)data)[cn]); 01554 break; 01555 case CV_16U: 01556 while( cn-- ) 01557 scalar->val[cn] = ((ushort*)data)[cn]; 01558 break; 01559 case CV_16S: 01560 while( cn-- ) 01561 scalar->val[cn] = ((short*)data)[cn]; 01562 break; 01563 case CV_32S: 01564 while( cn-- ) 01565 scalar->val[cn] = ((int*)data)[cn]; 01566 break; 01567 case CV_32F: 01568 while( cn-- ) 01569 scalar->val[cn] = ((float*)data)[cn]; 01570 break; 01571 case CV_64F: 01572 while( cn-- ) 01573 scalar->val[cn] = ((double*)data)[cn]; 01574 break; 01575 default: 01576 assert(0); 01577 CV_Error( CV_BadDepth, "" ); 01578 } 01579 } 01580 01581 01582 static double icvGetReal( const void* data, int type ) 01583 { 01584 switch( type ) 01585 { 01586 case CV_8U: 01587 return *(uchar*)data; 01588 case CV_8S: 01589 return *(char*)data; 01590 case CV_16U: 01591 return *(ushort*)data; 01592 case CV_16S: 01593 return *(short*)data; 01594 case CV_32S: 01595 return *(int*)data; 01596 case CV_32F: 01597 return *(float*)data; 01598 case CV_64F: 01599 return *(double*)data; 01600 } 01601 01602 return 0; 01603 } 01604 01605 01606 static void icvSetReal( double value, const void* data, int type ) 01607 { 01608 if( type < CV_32F ) 01609 { 01610 int ivalue = cvRound(value); 01611 switch( type ) 01612 { 01613 case CV_8U: 01614 *(uchar*)data = cv::saturate_cast<uchar>(ivalue); 01615 break; 01616 case CV_8S: 01617 *(schar*)data = cv::saturate_cast<schar>(ivalue); 01618 break; 01619 case CV_16U: 01620 *(ushort*)data = cv::saturate_cast<ushort>(ivalue); 01621 break; 01622 case CV_16S: 01623 *(short*)data = cv::saturate_cast<short>(ivalue); 01624 break; 01625 case CV_32S: 01626 *(int*)data = cv::saturate_cast<int>(ivalue); 01627 break; 01628 } 01629 } 01630 else 01631 { 01632 switch( type ) 01633 { 01634 case CV_32F: 01635 *(float*)data = (float)value; 01636 break; 01637 case CV_64F: 01638 *(double*)data = value; 01639 break; 01640 } 01641 } 01642 } 01643 01644 01645 // Returns pointer to specified element of array (linear index is used) 01646 CV_IMPL uchar* 01647 cvPtr1D( const CvArr* arr, int idx, int* _type ) 01648 { 01649 uchar* ptr = 0; 01650 if( CV_IS_MAT( arr )) 01651 { 01652 CvMat* mat = (CvMat*)arr; 01653 01654 int type = CV_MAT_TYPE(mat->type); 01655 int pix_size = CV_ELEM_SIZE(type); 01656 01657 if( _type ) 01658 *_type = type; 01659 01660 // the first part is mul-free sufficient check 01661 // that the index is within the matrix 01662 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 01663 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 01664 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01665 01666 if( CV_IS_MAT_CONT(mat->type)) 01667 { 01668 ptr = mat->data.ptr + (size_t)idx*pix_size; 01669 } 01670 else 01671 { 01672 int row, col; 01673 if( mat->cols == 1 ) 01674 row = idx, col = 0; 01675 else 01676 row = idx/mat->cols, col = idx - row*mat->cols; 01677 ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size; 01678 } 01679 } 01680 else if( CV_IS_IMAGE_HDR( arr )) 01681 { 01682 IplImage* img = (IplImage*)arr; 01683 int width = !img->roi ? img->width : img->roi->width; 01684 int y = idx/width, x = idx - y*width; 01685 01686 ptr = cvPtr2D( arr, y, x, _type ); 01687 } 01688 else if( CV_IS_MATND( arr )) 01689 { 01690 CvMatND * mat = (CvMatND *)arr; 01691 int j, type = CV_MAT_TYPE(mat->type); 01692 size_t size = mat->dim[0].size; 01693 01694 if( _type ) 01695 *_type = type; 01696 01697 for( j = 1; j < mat->dims; j++ ) 01698 size *= mat->dim[j].size; 01699 01700 if((unsigned)idx >= (unsigned)size ) 01701 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01702 01703 if( CV_IS_MAT_CONT(mat->type)) 01704 { 01705 int pix_size = CV_ELEM_SIZE(type); 01706 ptr = mat->data.ptr + (size_t)idx*pix_size; 01707 } 01708 else 01709 { 01710 ptr = mat->data.ptr; 01711 for( j = mat->dims - 1; j >= 0; j-- ) 01712 { 01713 int sz = mat->dim[j].size; 01714 if( sz ) 01715 { 01716 int t = idx/sz; 01717 ptr += (idx - t*sz)*mat->dim[j].step; 01718 idx = t; 01719 } 01720 } 01721 } 01722 } 01723 else if( CV_IS_SPARSE_MAT( arr )) 01724 { 01725 CvSparseMat* m = (CvSparseMat*)arr; 01726 if( m->dims == 1 ) 01727 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 ); 01728 else 01729 { 01730 int i, n = m->dims; 01731 CV_DbgAssert( n <= CV_MAX_DIM_HEAP ); 01732 int _idx[CV_MAX_DIM_HEAP]; 01733 01734 for( i = n - 1; i >= 0; i-- ) 01735 { 01736 int t = idx / m->size[i]; 01737 _idx[i] = idx - t*m->size[i]; 01738 idx = t; 01739 } 01740 ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 ); 01741 } 01742 } 01743 else 01744 { 01745 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01746 } 01747 01748 return ptr; 01749 } 01750 01751 01752 // Returns pointer to specified element of 2d array 01753 CV_IMPL uchar* 01754 cvPtr2D( const CvArr* arr, int y, int x, int* _type ) 01755 { 01756 uchar* ptr = 0; 01757 if( CV_IS_MAT( arr )) 01758 { 01759 CvMat* mat = (CvMat*)arr; 01760 int type; 01761 01762 if( (unsigned)y >= (unsigned)(mat->rows) || 01763 (unsigned)x >= (unsigned)(mat->cols) ) 01764 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01765 01766 type = CV_MAT_TYPE(mat->type); 01767 if( _type ) 01768 *_type = type; 01769 01770 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 01771 } 01772 else if( CV_IS_IMAGE( arr )) 01773 { 01774 IplImage* img = (IplImage*)arr; 01775 int pix_size = (img->depth & 255) >> 3; 01776 int width, height; 01777 ptr = (uchar*)img->imageData; 01778 01779 if( img->dataOrder == 0 ) 01780 pix_size *= img->nChannels; 01781 01782 if( img->roi ) 01783 { 01784 width = img->roi->width; 01785 height = img->roi->height; 01786 01787 ptr += img->roi->yOffset*img->widthStep + 01788 img->roi->xOffset*pix_size; 01789 01790 if( img->dataOrder ) 01791 { 01792 int coi = img->roi->coi; 01793 if( !coi ) 01794 CV_Error( CV_BadCOI, 01795 "COI must be non-null in case of planar images" ); 01796 ptr += (coi - 1)*img->imageSize; 01797 } 01798 } 01799 else 01800 { 01801 width = img->width; 01802 height = img->height; 01803 } 01804 01805 if( (unsigned)y >= (unsigned)height || 01806 (unsigned)x >= (unsigned)width ) 01807 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01808 01809 ptr += y*img->widthStep + x*pix_size; 01810 01811 if( _type ) 01812 { 01813 int type = IPL2CV_DEPTH(img->depth); 01814 if( type < 0 || (unsigned)(img->nChannels - 1) > 3 ) 01815 CV_Error( CV_StsUnsupportedFormat, "" ); 01816 01817 *_type = CV_MAKETYPE( type, img->nChannels ); 01818 } 01819 } 01820 else if( CV_IS_MATND( arr )) 01821 { 01822 CvMatND * mat = (CvMatND *)arr; 01823 01824 if( mat->dims != 2 || 01825 (unsigned)y >= (unsigned)(mat->dim[0].size) || 01826 (unsigned)x >= (unsigned)(mat->dim[1].size) ) 01827 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01828 01829 ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step; 01830 if( _type ) 01831 *_type = CV_MAT_TYPE(mat->type); 01832 } 01833 else if( CV_IS_SPARSE_MAT( arr )) 01834 { 01835 int idx[] = { y, x }; 01836 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 ); 01837 } 01838 else 01839 { 01840 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01841 } 01842 01843 return ptr; 01844 } 01845 01846 01847 // Returns pointer to specified element of 3d array 01848 CV_IMPL uchar* 01849 cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) 01850 { 01851 uchar* ptr = 0; 01852 if( CV_IS_MATND( arr )) 01853 { 01854 CvMatND * mat = (CvMatND *)arr; 01855 01856 if( mat->dims != 3 || 01857 (unsigned)z >= (unsigned)(mat->dim[0].size) || 01858 (unsigned)y >= (unsigned)(mat->dim[1].size) || 01859 (unsigned)x >= (unsigned)(mat->dim[2].size) ) 01860 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01861 01862 ptr = mat->data.ptr + (size_t)z*mat->dim[0].step + 01863 (size_t)y*mat->dim[1].step + x*mat->dim[2].step; 01864 01865 if( _type ) 01866 *_type = CV_MAT_TYPE(mat->type); 01867 } 01868 else if( CV_IS_SPARSE_MAT( arr )) 01869 { 01870 int idx[] = { z, y, x }; 01871 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 ); 01872 } 01873 else 01874 { 01875 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01876 } 01877 01878 return ptr; 01879 } 01880 01881 01882 // Returns pointer to specified element of n-d array 01883 CV_IMPL uchar* 01884 cvPtrND( const CvArr* arr, const int* idx, int* _type, 01885 int create_node, unsigned* precalc_hashval ) 01886 { 01887 uchar* ptr = 0; 01888 if( !idx ) 01889 CV_Error( CV_StsNullPtr, "NULL pointer to indices" ); 01890 01891 if( CV_IS_SPARSE_MAT( arr )) 01892 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, 01893 _type, create_node, precalc_hashval ); 01894 else if( CV_IS_MATND( arr )) 01895 { 01896 CvMatND * mat = (CvMatND *)arr; 01897 int i; 01898 ptr = mat->data.ptr; 01899 01900 for( i = 0; i < mat->dims; i++ ) 01901 { 01902 if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) ) 01903 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01904 ptr += (size_t)idx[i]*mat->dim[i].step; 01905 } 01906 01907 if( _type ) 01908 *_type = CV_MAT_TYPE(mat->type); 01909 } 01910 else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) ) 01911 ptr = cvPtr2D( arr, idx[0], idx[1], _type ); 01912 else 01913 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 01914 01915 return ptr; 01916 } 01917 01918 01919 // Returns specifed element of n-D array given linear index 01920 CV_IMPL CvScalar 01921 cvGet1D( const CvArr* arr, int idx ) 01922 { 01923 CvScalar scalar(0); 01924 int type = 0; 01925 uchar* ptr; 01926 01927 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 01928 { 01929 CvMat* mat = (CvMat*)arr; 01930 01931 type = CV_MAT_TYPE(mat->type); 01932 int pix_size = CV_ELEM_SIZE(type); 01933 01934 // the first part is mul-free sufficient check 01935 // that the index is within the matrix 01936 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 01937 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 01938 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01939 01940 ptr = mat->data.ptr + (size_t)idx*pix_size; 01941 } 01942 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 01943 ptr = cvPtr1D( arr, idx, &type ); 01944 else 01945 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 ); 01946 01947 if( ptr ) 01948 cvRawDataToScalar( ptr, type, &scalar ); 01949 01950 return scalar; 01951 } 01952 01953 01954 // Returns specifed element of 2D array 01955 CV_IMPL CvScalar 01956 cvGet2D( const CvArr* arr, int y, int x ) 01957 { 01958 CvScalar scalar(0); 01959 int type = 0; 01960 uchar* ptr; 01961 01962 if( CV_IS_MAT( arr )) 01963 { 01964 CvMat* mat = (CvMat*)arr; 01965 01966 if( (unsigned)y >= (unsigned)(mat->rows) || 01967 (unsigned)x >= (unsigned)(mat->cols) ) 01968 CV_Error( CV_StsOutOfRange, "index is out of range" ); 01969 01970 type = CV_MAT_TYPE(mat->type); 01971 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 01972 } 01973 else if( !CV_IS_SPARSE_MAT( arr )) 01974 ptr = cvPtr2D( arr, y, x, &type ); 01975 else 01976 { 01977 int idx[] = { y, x }; 01978 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 01979 } 01980 01981 if( ptr ) 01982 cvRawDataToScalar( ptr, type, &scalar ); 01983 01984 return scalar; 01985 } 01986 01987 01988 // Returns specifed element of 3D array 01989 CV_IMPL CvScalar 01990 cvGet3D( const CvArr* arr, int z, int y, int x ) 01991 { 01992 CvScalar scalar(0); 01993 int type = 0; 01994 uchar* ptr; 01995 01996 if( !CV_IS_SPARSE_MAT( arr )) 01997 ptr = cvPtr3D( arr, z, y, x, &type ); 01998 else 01999 { 02000 int idx[] = { z, y, x }; 02001 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 02002 } 02003 02004 if( ptr ) 02005 cvRawDataToScalar( ptr, type, &scalar ); 02006 return scalar; 02007 } 02008 02009 02010 // Returns specifed element of nD array 02011 CV_IMPL CvScalar 02012 cvGetND( const CvArr* arr, const int* idx ) 02013 { 02014 CvScalar scalar(0); 02015 int type = 0; 02016 uchar* ptr; 02017 02018 if( !CV_IS_SPARSE_MAT( arr )) 02019 ptr = cvPtrND( arr, idx, &type ); 02020 else 02021 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 02022 02023 if( ptr ) 02024 cvRawDataToScalar( ptr, type, &scalar ); 02025 02026 return scalar; 02027 } 02028 02029 02030 // Returns specifed element of n-D array given linear index 02031 CV_IMPL double 02032 cvGetReal1D( const CvArr* arr, int idx ) 02033 { 02034 double value = 0; 02035 int type = 0; 02036 uchar* ptr; 02037 02038 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 02039 { 02040 CvMat* mat = (CvMat*)arr; 02041 02042 type = CV_MAT_TYPE(mat->type); 02043 int pix_size = CV_ELEM_SIZE(type); 02044 02045 // the first part is mul-free sufficient check 02046 // that the index is within the matrix 02047 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 02048 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 02049 CV_Error( CV_StsOutOfRange, "index is out of range" ); 02050 02051 ptr = mat->data.ptr + (size_t)idx*pix_size; 02052 } 02053 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 02054 ptr = cvPtr1D( arr, idx, &type ); 02055 else 02056 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 ); 02057 02058 if( ptr ) 02059 { 02060 if( CV_MAT_CN( type ) > 1 ) 02061 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 02062 02063 value = icvGetReal( ptr, type ); 02064 } 02065 return value; 02066 } 02067 02068 02069 // Returns specifed element of 2D array 02070 CV_IMPL double 02071 cvGetReal2D( const CvArr* arr, int y, int x ) 02072 { 02073 double value = 0; 02074 int type = 0; 02075 uchar* ptr; 02076 02077 if( CV_IS_MAT( arr )) 02078 { 02079 CvMat* mat = (CvMat*)arr; 02080 02081 if( (unsigned)y >= (unsigned)(mat->rows) || 02082 (unsigned)x >= (unsigned)(mat->cols) ) 02083 CV_Error( CV_StsOutOfRange, "index is out of range" ); 02084 02085 type = CV_MAT_TYPE(mat->type); 02086 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 02087 } 02088 else if( !CV_IS_SPARSE_MAT( arr )) 02089 ptr = cvPtr2D( arr, y, x, &type ); 02090 else 02091 { 02092 int idx[] = { y, x }; 02093 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 02094 } 02095 02096 if( ptr ) 02097 { 02098 if( CV_MAT_CN( type ) > 1 ) 02099 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 02100 02101 value = icvGetReal( ptr, type ); 02102 } 02103 02104 return value; 02105 } 02106 02107 02108 // Returns specifed element of 3D array 02109 CV_IMPL double 02110 cvGetReal3D( const CvArr* arr, int z, int y, int x ) 02111 { 02112 double value = 0; 02113 int type = 0; 02114 uchar* ptr; 02115 02116 if( !CV_IS_SPARSE_MAT( arr )) 02117 ptr = cvPtr3D( arr, z, y, x, &type ); 02118 else 02119 { 02120 int idx[] = { z, y, x }; 02121 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 02122 } 02123 02124 if( ptr ) 02125 { 02126 if( CV_MAT_CN( type ) > 1 ) 02127 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 02128 02129 value = icvGetReal( ptr, type ); 02130 } 02131 02132 return value; 02133 } 02134 02135 02136 // Returns specifed element of nD array 02137 CV_IMPL double 02138 cvGetRealND( const CvArr* arr, const int* idx ) 02139 { 02140 double value = 0; 02141 int type = 0; 02142 uchar* ptr; 02143 02144 if( !CV_IS_SPARSE_MAT( arr )) 02145 ptr = cvPtrND( arr, idx, &type ); 02146 else 02147 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 02148 02149 if( ptr ) 02150 { 02151 if( CV_MAT_CN( type ) > 1 ) 02152 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 02153 02154 value = icvGetReal( ptr, type ); 02155 } 02156 02157 return value; 02158 } 02159 02160 02161 // Assigns new value to specifed element of nD array given linear index 02162 CV_IMPL void 02163 cvSet1D( CvArr* arr, int idx, CvScalar scalar ) 02164 { 02165 int type = 0; 02166 uchar* ptr; 02167 02168 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 02169 { 02170 CvMat* mat = (CvMat*)arr; 02171 02172 type = CV_MAT_TYPE(mat->type); 02173 int pix_size = CV_ELEM_SIZE(type); 02174 02175 // the first part is mul-free sufficient check 02176 // that the index is within the matrix 02177 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 02178 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 02179 CV_Error( CV_StsOutOfRange, "index is out of range" ); 02180 02181 ptr = mat->data.ptr + (size_t)idx*pix_size; 02182 } 02183 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 02184 ptr = cvPtr1D( arr, idx, &type ); 02185 else 02186 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); 02187 02188 cvScalarToRawData( &scalar, ptr, type ); 02189 } 02190 02191 02192 // Assigns new value to specifed element of 2D array 02193 CV_IMPL void 02194 cvSet2D( CvArr* arr, int y, int x, CvScalar scalar ) 02195 { 02196 int type = 0; 02197 uchar* ptr; 02198 02199 if( CV_IS_MAT( arr )) 02200 { 02201 CvMat* mat = (CvMat*)arr; 02202 02203 if( (unsigned)y >= (unsigned)(mat->rows) || 02204 (unsigned)x >= (unsigned)(mat->cols) ) 02205 CV_Error( CV_StsOutOfRange, "index is out of range" ); 02206 02207 type = CV_MAT_TYPE(mat->type); 02208 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 02209 } 02210 else if( !CV_IS_SPARSE_MAT( arr )) 02211 ptr = cvPtr2D( arr, y, x, &type ); 02212 else 02213 { 02214 int idx[] = { y, x }; 02215 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 02216 } 02217 cvScalarToRawData( &scalar, ptr, type ); 02218 } 02219 02220 02221 // Assigns new value to specifed element of 3D array 02222 CV_IMPL void 02223 cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar ) 02224 { 02225 int type = 0; 02226 uchar* ptr; 02227 02228 if( !CV_IS_SPARSE_MAT( arr )) 02229 ptr = cvPtr3D( arr, z, y, x, &type ); 02230 else 02231 { 02232 int idx[] = { z, y, x }; 02233 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 02234 } 02235 cvScalarToRawData( &scalar, ptr, type ); 02236 } 02237 02238 02239 // Assigns new value to specifed element of nD array 02240 CV_IMPL void 02241 cvSetND( CvArr* arr, const int* idx, CvScalar scalar ) 02242 { 02243 int type = 0; 02244 uchar* ptr; 02245 02246 if( !CV_IS_SPARSE_MAT( arr )) 02247 ptr = cvPtrND( arr, idx, &type ); 02248 else 02249 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 02250 cvScalarToRawData( &scalar, ptr, type ); 02251 } 02252 02253 02254 CV_IMPL void 02255 cvSetReal1D( CvArr* arr, int idx, double value ) 02256 { 02257 int type = 0; 02258 uchar* ptr; 02259 02260 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 02261 { 02262 CvMat* mat = (CvMat*)arr; 02263 02264 type = CV_MAT_TYPE(mat->type); 02265 int pix_size = CV_ELEM_SIZE(type); 02266 02267 // the first part is mul-free sufficient check 02268 // that the index is within the matrix 02269 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 02270 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 02271 CV_Error( CV_StsOutOfRange, "index is out of range" ); 02272 02273 ptr = mat->data.ptr + (size_t)idx*pix_size; 02274 } 02275 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 02276 ptr = cvPtr1D( arr, idx, &type ); 02277 else 02278 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); 02279 02280 if( CV_MAT_CN( type ) > 1 ) 02281 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 02282 02283 if( ptr ) 02284 icvSetReal( value, ptr, type ); 02285 } 02286 02287 02288 CV_IMPL void 02289 cvSetReal2D( CvArr* arr, int y, int x, double value ) 02290 { 02291 int type = 0; 02292 uchar* ptr; 02293 02294 if( CV_IS_MAT( arr )) 02295 { 02296 CvMat* mat = (CvMat*)arr; 02297 02298 if( (unsigned)y >= (unsigned)(mat->rows) || 02299 (unsigned)x >= (unsigned)(mat->cols) ) 02300 CV_Error( CV_StsOutOfRange, "index is out of range" ); 02301 02302 type = CV_MAT_TYPE(mat->type); 02303 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 02304 } 02305 else if( !CV_IS_SPARSE_MAT( arr )) 02306 { 02307 ptr = cvPtr2D( arr, y, x, &type ); 02308 } 02309 else 02310 { 02311 int idx[] = { y, x }; 02312 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 02313 } 02314 if( CV_MAT_CN( type ) > 1 ) 02315 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 02316 02317 if( ptr ) 02318 icvSetReal( value, ptr, type ); 02319 } 02320 02321 02322 CV_IMPL void 02323 cvSetReal3D( CvArr* arr, int z, int y, int x, double value ) 02324 { 02325 int type = 0; 02326 uchar* ptr; 02327 02328 if( !CV_IS_SPARSE_MAT( arr )) 02329 ptr = cvPtr3D( arr, z, y, x, &type ); 02330 else 02331 { 02332 int idx[] = { z, y, x }; 02333 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 02334 } 02335 if( CV_MAT_CN( type ) > 1 ) 02336 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 02337 02338 if( ptr ) 02339 icvSetReal( value, ptr, type ); 02340 } 02341 02342 02343 CV_IMPL void 02344 cvSetRealND( CvArr* arr, const int* idx, double value ) 02345 { 02346 int type = 0; 02347 uchar* ptr; 02348 02349 if( !CV_IS_SPARSE_MAT( arr )) 02350 ptr = cvPtrND( arr, idx, &type ); 02351 else 02352 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 02353 02354 if( CV_MAT_CN( type ) > 1 ) 02355 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 02356 02357 if( ptr ) 02358 icvSetReal( value, ptr, type ); 02359 } 02360 02361 02362 CV_IMPL void 02363 cvClearND( CvArr* arr, const int* idx ) 02364 { 02365 if( !CV_IS_SPARSE_MAT( arr )) 02366 { 02367 int type; 02368 uchar* ptr; 02369 ptr = cvPtrND( arr, idx, &type ); 02370 if( ptr ) 02371 memset( ptr, 0, CV_ELEM_SIZE(type) ); 02372 } 02373 else 02374 icvDeleteNode( (CvSparseMat*)arr, idx, 0 ); 02375 } 02376 02377 02378 /****************************************************************************************\ 02379 * Conversion to CvMat or IplImage * 02380 \****************************************************************************************/ 02381 02382 // convert array (CvMat or IplImage) to CvMat 02383 CV_IMPL CvMat* 02384 cvGetMat( const CvArr* array, CvMat* mat, 02385 int* pCOI, int allowND ) 02386 { 02387 CvMat* result = 0; 02388 CvMat* src = (CvMat*)array; 02389 int coi = 0; 02390 02391 if( !mat || !src ) 02392 CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); 02393 02394 if( CV_IS_MAT_HDR(src)) 02395 { 02396 if( !src->data.ptr ) 02397 CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); 02398 02399 result = (CvMat*)src; 02400 } 02401 else if( CV_IS_IMAGE_HDR(src) ) 02402 { 02403 const IplImage* img = (const IplImage*)src; 02404 int depth, order; 02405 02406 if( img->imageData == 0 ) 02407 CV_Error( CV_StsNullPtr, "The image has NULL data pointer" ); 02408 02409 depth = IPL2CV_DEPTH( img->depth ); 02410 if( depth < 0 ) 02411 CV_Error( CV_BadDepth, "" ); 02412 02413 order = img->dataOrder & (img->nChannels > 1 ? -1 : 0); 02414 02415 if( img->roi ) 02416 { 02417 if( order == IPL_DATA_ORDER_PLANE ) 02418 { 02419 int type = depth; 02420 02421 if( img->roi->coi == 0 ) 02422 CV_Error( CV_StsBadFlag, 02423 "Images with planar data layout should be used with COI selected" ); 02424 02425 cvInitMatHeader( mat, img->roi->height, 02426 img->roi->width, type, 02427 img->imageData + (img->roi->coi-1)*img->imageSize + 02428 img->roi->yOffset*img->widthStep + 02429 img->roi->xOffset*CV_ELEM_SIZE(type), 02430 img->widthStep ); 02431 } 02432 else /* pixel order */ 02433 { 02434 int type = CV_MAKETYPE( depth, img->nChannels ); 02435 coi = img->roi->coi; 02436 02437 if( img->nChannels > CV_CN_MAX ) 02438 CV_Error( CV_BadNumChannels, 02439 "The image is interleaved and has over CV_CN_MAX channels" ); 02440 02441 cvInitMatHeader( mat, img->roi->height, img->roi->width, 02442 type, img->imageData + 02443 img->roi->yOffset*img->widthStep + 02444 img->roi->xOffset*CV_ELEM_SIZE(type), 02445 img->widthStep ); 02446 } 02447 } 02448 else 02449 { 02450 int type = CV_MAKETYPE( depth, img->nChannels ); 02451 02452 if( order != IPL_DATA_ORDER_PIXEL ) 02453 CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" ); 02454 02455 cvInitMatHeader( mat, img->height, img->width, type, 02456 img->imageData, img->widthStep ); 02457 } 02458 02459 result = mat; 02460 } 02461 else if( allowND && CV_IS_MATND_HDR(src) ) 02462 { 02463 CvMatND * matnd = (CvMatND *)src; 02464 int size1 = matnd->dim[0].size, size2 = 1; 02465 02466 if( !src->data.ptr ) 02467 CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); 02468 02469 if( !CV_IS_MAT_CONT( matnd->type )) 02470 CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); 02471 02472 if( matnd->dims > 2 ) 02473 { 02474 int i; 02475 for( i = 1; i < matnd->dims; i++ ) 02476 size2 *= matnd->dim[i].size; 02477 } 02478 else 02479 size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size; 02480 02481 mat->refcount = 0; 02482 mat->hdr_refcount = 0; 02483 mat->data.ptr = matnd->data.ptr; 02484 mat->rows = size1; 02485 mat->cols = size2; 02486 mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG; 02487 mat->step = size2*CV_ELEM_SIZE(matnd->type); 02488 mat->step &= size1 > 1 ? -1 : 0; 02489 02490 icvCheckHuge( mat ); 02491 result = mat; 02492 } 02493 else 02494 CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" ); 02495 02496 if( pCOI ) 02497 *pCOI = coi; 02498 02499 return result; 02500 } 02501 02502 02503 CV_IMPL CvArr* 02504 cvReshapeMatND( const CvArr* arr, 02505 int sizeof_header, CvArr* _header, 02506 int new_cn, int new_dims, int* new_sizes ) 02507 { 02508 CvArr* result = 0; 02509 int dims, coi = 0; 02510 02511 if( !arr || !_header ) 02512 CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" ); 02513 02514 if( new_cn == 0 && new_dims == 0 ) 02515 CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" ); 02516 02517 dims = cvGetDims( arr ); 02518 02519 if( new_dims == 0 ) 02520 { 02521 new_sizes = 0; 02522 new_dims = dims; 02523 } 02524 else if( new_dims == 1 ) 02525 { 02526 new_sizes = 0; 02527 } 02528 else 02529 { 02530 if( new_dims <= 0 || new_dims > CV_MAX_DIM ) 02531 CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" ); 02532 if( !new_sizes ) 02533 CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" ); 02534 } 02535 02536 if( new_dims <= 2 ) 02537 { 02538 CvMat* mat = (CvMat*)arr; 02539 CvMat header; 02540 int* refcount = 0; 02541 int hdr_refcount = 0; 02542 int total_width, new_rows, cn; 02543 02544 if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND ) ) 02545 CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" ); 02546 02547 if( mat == (CvMat*)_header ) 02548 { 02549 refcount = mat->refcount; 02550 hdr_refcount = mat->hdr_refcount; 02551 } 02552 02553 if( !CV_IS_MAT( mat )) 02554 mat = cvGetMat( mat, &header, &coi, 1 ); 02555 02556 cn = CV_MAT_CN( mat->type ); 02557 total_width = mat->cols * cn; 02558 02559 if( new_cn == 0 ) 02560 new_cn = cn; 02561 02562 if( new_sizes ) 02563 new_rows = new_sizes[0]; 02564 else if( new_dims == 1 ) 02565 new_rows = total_width*mat->rows/new_cn; 02566 else 02567 { 02568 new_rows = mat->rows; 02569 if( new_cn > total_width ) 02570 new_rows = mat->rows * total_width / new_cn; 02571 } 02572 02573 if( new_rows != mat->rows ) 02574 { 02575 int total_size = total_width * mat->rows; 02576 02577 if( !CV_IS_MAT_CONT( mat->type )) 02578 CV_Error( CV_BadStep, 02579 "The matrix is not continuous so the number of rows can not be changed" ); 02580 02581 total_width = total_size / new_rows; 02582 02583 if( total_width * new_rows != total_size ) 02584 CV_Error( CV_StsBadArg, "The total number of matrix elements " 02585 "is not divisible by the new number of rows" ); 02586 } 02587 02588 header.rows = new_rows; 02589 header.cols = total_width / new_cn; 02590 02591 if( header.cols * new_cn != total_width || 02592 (new_sizes && header.cols != new_sizes[1]) ) 02593 CV_Error( CV_StsBadArg, "The total matrix width is not " 02594 "divisible by the new number of columns" ); 02595 02596 header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); 02597 header.step = header.cols * CV_ELEM_SIZE(mat->type); 02598 header.step &= new_rows > 1 ? -1 : 0; 02599 header.refcount = refcount; 02600 header.hdr_refcount = hdr_refcount; 02601 02602 if( sizeof_header == sizeof(CvMat) ) 02603 *(CvMat*)_header = header; 02604 else 02605 { 02606 CvMatND * __header = (CvMatND *)_header; 02607 cvGetMatND(&header, __header, 0); 02608 if( new_dims > 0 ) 02609 __header->dims = new_dims; 02610 } 02611 } 02612 else 02613 { 02614 CvMatND * header = (CvMatND *)_header; 02615 02616 if( sizeof_header != sizeof(CvMatND )) 02617 CV_Error( CV_StsBadSize, "The output header should be CvMatND" ); 02618 02619 if( !new_sizes ) 02620 { 02621 if( !CV_IS_MATND( arr )) 02622 CV_Error( CV_StsBadArg, "The input array must be CvMatND" ); 02623 02624 { 02625 CvMatND * mat = (CvMatND *)arr; 02626 assert( new_cn > 0 ); 02627 int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type); 02628 int new_size = last_dim_size/new_cn; 02629 02630 if( new_size*new_cn != last_dim_size ) 02631 CV_Error( CV_StsBadArg, 02632 "The last dimension full size is not divisible by new number of channels"); 02633 02634 if( mat != header ) 02635 { 02636 memcpy( header, mat, sizeof(*header)); 02637 header->refcount = 0; 02638 header->hdr_refcount = 0; 02639 } 02640 02641 header->dim[header->dims-1].size = new_size; 02642 header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn); 02643 } 02644 } 02645 else 02646 { 02647 CvMatND stub; 02648 CvMatND * mat = (CvMatND *)arr; 02649 int i, size1, size2; 02650 int step; 02651 02652 if( new_cn != 0 ) 02653 CV_Error( CV_StsBadArg, 02654 "Simultaneous change of shape and number of channels is not supported. " 02655 "Do it by 2 separate calls" ); 02656 02657 if( !CV_IS_MATND( mat )) 02658 { 02659 cvGetMatND( mat, &stub, &coi ); 02660 mat = &stub; 02661 } 02662 02663 if( CV_IS_MAT_CONT( mat->type )) 02664 CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" ); 02665 02666 size1 = mat->dim[0].size; 02667 for( i = 1; i < dims; i++ ) 02668 size1 *= mat->dim[i].size; 02669 02670 size2 = 1; 02671 for( i = 0; i < new_dims; i++ ) 02672 { 02673 if( new_sizes[i] <= 0 ) 02674 CV_Error( CV_StsBadSize, 02675 "One of new dimension sizes is non-positive" ); 02676 size2 *= new_sizes[i]; 02677 } 02678 02679 if( size1 != size2 ) 02680 CV_Error( CV_StsBadSize, 02681 "Number of elements in the original and reshaped array is different" ); 02682 02683 if( header != mat ) 02684 { 02685 header->refcount = 0; 02686 header->hdr_refcount = 0; 02687 } 02688 02689 header->dims = new_dims; 02690 header->type = mat->type; 02691 header->data.ptr = mat->data.ptr; 02692 step = CV_ELEM_SIZE(header->type); 02693 02694 for( i = new_dims - 1; i >= 0; i-- ) 02695 { 02696 header->dim[i].size = new_sizes[i]; 02697 header->dim[i].step = step; 02698 step *= new_sizes[i]; 02699 } 02700 } 02701 } 02702 02703 if( coi ) 02704 CV_Error( CV_BadCOI, "COI is not supported by this operation" ); 02705 02706 result = _header; 02707 return result; 02708 } 02709 02710 02711 CV_IMPL CvMat* 02712 cvReshape( const CvArr* array, CvMat* header, 02713 int new_cn, int new_rows ) 02714 { 02715 CvMat* result = 0; 02716 CvMat *mat = (CvMat*)array; 02717 int total_width, new_width; 02718 02719 if( !header ) 02720 CV_Error( CV_StsNullPtr, "" ); 02721 02722 if( !CV_IS_MAT( mat )) 02723 { 02724 int coi = 0; 02725 mat = cvGetMat( mat, header, &coi, 1 ); 02726 if( coi ) 02727 CV_Error( CV_BadCOI, "COI is not supported" ); 02728 } 02729 02730 if( new_cn == 0 ) 02731 new_cn = CV_MAT_CN(mat->type); 02732 else if( (unsigned)(new_cn - 1) > 3 ) 02733 CV_Error( CV_BadNumChannels, "" ); 02734 02735 if( mat != header ) 02736 { 02737 int hdr_refcount = header->hdr_refcount; 02738 *header = *mat; 02739 header->refcount = 0; 02740 header->hdr_refcount = hdr_refcount; 02741 } 02742 02743 total_width = mat->cols * CV_MAT_CN( mat->type ); 02744 02745 if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 ) 02746 new_rows = mat->rows * total_width / new_cn; 02747 02748 if( new_rows == 0 || new_rows == mat->rows ) 02749 { 02750 header->rows = mat->rows; 02751 header->step = mat->step; 02752 } 02753 else 02754 { 02755 int total_size = total_width * mat->rows; 02756 if( !CV_IS_MAT_CONT( mat->type )) 02757 CV_Error( CV_BadStep, 02758 "The matrix is not continuous, thus its number of rows can not be changed" ); 02759 02760 if( (unsigned)new_rows > (unsigned)total_size ) 02761 CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); 02762 02763 total_width = total_size / new_rows; 02764 02765 if( total_width * new_rows != total_size ) 02766 CV_Error( CV_StsBadArg, "The total number of matrix elements " 02767 "is not divisible by the new number of rows" ); 02768 02769 header->rows = new_rows; 02770 header->step = total_width * CV_ELEM_SIZE1(mat->type); 02771 } 02772 02773 new_width = total_width / new_cn; 02774 02775 if( new_width * new_cn != total_width ) 02776 CV_Error( CV_BadNumChannels, 02777 "The total width is not divisible by the new number of channels" ); 02778 02779 header->cols = new_width; 02780 header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); 02781 02782 result = header; 02783 return result; 02784 } 02785 02786 02787 // convert array (CvMat or IplImage) to IplImage 02788 CV_IMPL IplImage* 02789 cvGetImage( const CvArr* array, IplImage* img ) 02790 { 02791 IplImage* result = 0; 02792 const IplImage* src = (const IplImage*)array; 02793 02794 if( !img ) 02795 CV_Error( CV_StsNullPtr, "" ); 02796 02797 if( !CV_IS_IMAGE_HDR(src) ) 02798 { 02799 const CvMat* mat = (const CvMat*)src; 02800 02801 if( !CV_IS_MAT_HDR(mat)) 02802 CV_Error( CV_StsBadFlag, "" ); 02803 02804 if( mat->data.ptr == 0 ) 02805 CV_Error( CV_StsNullPtr, "" ); 02806 02807 int depth = cvIplDepth(mat->type); 02808 02809 cvInitImageHeader( img, cvSize(mat->cols, mat->rows), 02810 depth, CV_MAT_CN(mat->type) ); 02811 cvSetData( img, mat->data.ptr, mat->step ); 02812 02813 result = img; 02814 } 02815 else 02816 { 02817 result = (IplImage*)src; 02818 } 02819 02820 return result; 02821 } 02822 02823 02824 /****************************************************************************************\ 02825 * IplImage-specific functions * 02826 \****************************************************************************************/ 02827 02828 static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height ) 02829 { 02830 IplROI *roi = 0; 02831 if( !CvIPL.createROI ) 02832 { 02833 roi = (IplROI*)cvAlloc( sizeof(*roi)); 02834 02835 roi->coi = coi; 02836 roi->xOffset = xOffset; 02837 roi->yOffset = yOffset; 02838 roi->width = width; 02839 roi->height = height; 02840 } 02841 else 02842 { 02843 roi = CvIPL.createROI( coi, xOffset, yOffset, width, height ); 02844 } 02845 02846 return roi; 02847 } 02848 02849 static void 02850 icvGetColorModel( int nchannels, const char** colorModel, const char** channelSeq ) 02851 { 02852 static const char* tab[][2] = 02853 { 02854 {"GRAY", "GRAY"}, 02855 {"",""}, 02856 {"RGB","BGR"}, 02857 {"RGB","BGRA"} 02858 }; 02859 02860 nchannels--; 02861 *colorModel = *channelSeq = ""; 02862 02863 if( (unsigned)nchannels <= 3 ) 02864 { 02865 *colorModel = tab[nchannels][0]; 02866 *channelSeq = tab[nchannels][1]; 02867 } 02868 } 02869 02870 02871 // create IplImage header 02872 CV_IMPL IplImage * 02873 cvCreateImageHeader( CvSize size, int depth, int channels ) 02874 { 02875 IplImage *img = 0; 02876 02877 if( !CvIPL.createHeader ) 02878 { 02879 img = (IplImage *)cvAlloc( sizeof( *img )); 02880 cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL, 02881 CV_DEFAULT_IMAGE_ROW_ALIGN ); 02882 } 02883 else 02884 { 02885 const char *colorModel, *channelSeq; 02886 02887 icvGetColorModel( channels, &colorModel, &channelSeq ); 02888 02889 img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq, 02890 IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, 02891 CV_DEFAULT_IMAGE_ROW_ALIGN, 02892 size.width, size.height, 0, 0, 0, 0 ); 02893 } 02894 02895 return img; 02896 } 02897 02898 02899 // create IplImage header and allocate underlying data 02900 CV_IMPL IplImage * 02901 cvCreateImage( CvSize size, int depth, int channels ) 02902 { 02903 IplImage *img = cvCreateImageHeader( size, depth, channels ); 02904 assert( img ); 02905 cvCreateData( img ); 02906 02907 return img; 02908 } 02909 02910 02911 // initialize IplImage header, allocated by the user 02912 CV_IMPL IplImage* 02913 cvInitImageHeader( IplImage * image, CvSize size, int depth, 02914 int channels, int origin, int align ) 02915 { 02916 const char *colorModel, *channelSeq; 02917 02918 if( !image ) 02919 CV_Error( CV_HeaderIsNull, "null pointer to header" ); 02920 02921 memset( image, 0, sizeof( *image )); 02922 image->nSize = sizeof( *image ); 02923 02924 icvGetColorModel( channels, &colorModel, &channelSeq ); 02925 strncpy( image->colorModel, colorModel, 4 ); 02926 strncpy( image->channelSeq, channelSeq, 4 ); 02927 02928 if( size.width < 0 || size.height < 0 ) 02929 CV_Error( CV_BadROISize, "Bad input roi" ); 02930 02931 if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U && 02932 depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U && 02933 depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S && 02934 depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) || 02935 channels < 0 ) 02936 CV_Error( CV_BadDepth, "Unsupported format" ); 02937 if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL ) 02938 CV_Error( CV_BadOrigin, "Bad input origin" ); 02939 02940 if( align != 4 && align != 8 ) 02941 CV_Error( CV_BadAlign, "Bad input align" ); 02942 02943 image->width = size.width; 02944 image->height = size.height; 02945 02946 if( image->roi ) 02947 { 02948 image->roi->coi = 0; 02949 image->roi->xOffset = image->roi->yOffset = 0; 02950 image->roi->width = size.width; 02951 image->roi->height = size.height; 02952 } 02953 02954 image->nChannels = MAX( channels, 1 ); 02955 image->depth = depth; 02956 image->align = align; 02957 image->widthStep = (((image->width * image->nChannels * 02958 (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1)); 02959 image->origin = origin; 02960 image->imageSize = image->widthStep * image->height; 02961 02962 return image; 02963 } 02964 02965 02966 CV_IMPL void 02967 cvReleaseImageHeader( IplImage** image ) 02968 { 02969 if( !image ) 02970 CV_Error( CV_StsNullPtr, "" ); 02971 02972 if( *image ) 02973 { 02974 IplImage* img = *image; 02975 *image = 0; 02976 02977 if( !CvIPL.deallocate ) 02978 { 02979 cvFree( &img->roi ); 02980 cvFree( &img ); 02981 } 02982 else 02983 { 02984 CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI ); 02985 } 02986 } 02987 } 02988 02989 02990 CV_IMPL void 02991 cvReleaseImage( IplImage ** image ) 02992 { 02993 if( !image ) 02994 CV_Error( CV_StsNullPtr, "" ); 02995 02996 if( *image ) 02997 { 02998 IplImage* img = *image; 02999 *image = 0; 03000 03001 cvReleaseData( img ); 03002 cvReleaseImageHeader( &img ); 03003 } 03004 } 03005 03006 03007 CV_IMPL void 03008 cvSetImageROI( IplImage* image, CvRect rect ) 03009 { 03010 if( !image ) 03011 CV_Error( CV_HeaderIsNull, "" ); 03012 03013 // allow zero ROI width or height 03014 CV_Assert( rect.width >= 0 && rect.height >= 0 && 03015 rect.x < image->width && rect.y < image->height && 03016 rect.x + rect.width >= (int)(rect.width > 0) && 03017 rect.y + rect.height >= (int)(rect.height > 0) ); 03018 03019 rect.width += rect.x; 03020 rect.height += rect.y; 03021 03022 rect.x = std::max(rect.x, 0); 03023 rect.y = std::max(rect.y, 0); 03024 rect.width = std::min(rect.width, image->width); 03025 rect.height = std::min(rect.height, image->height); 03026 03027 rect.width -= rect.x; 03028 rect.height -= rect.y; 03029 03030 if( image->roi ) 03031 { 03032 image->roi->xOffset = rect.x; 03033 image->roi->yOffset = rect.y; 03034 image->roi->width = rect.width; 03035 image->roi->height = rect.height; 03036 } 03037 else 03038 image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height ); 03039 } 03040 03041 03042 CV_IMPL void 03043 cvResetImageROI( IplImage* image ) 03044 { 03045 if( !image ) 03046 CV_Error( CV_HeaderIsNull, "" ); 03047 03048 if( image->roi ) 03049 { 03050 if( !CvIPL.deallocate ) 03051 { 03052 cvFree( &image->roi ); 03053 } 03054 else 03055 { 03056 CvIPL.deallocate( image, IPL_IMAGE_ROI ); 03057 image->roi = 0; 03058 } 03059 } 03060 } 03061 03062 03063 CV_IMPL CvRect 03064 cvGetImageROI( const IplImage* img ) 03065 { 03066 CvRect rect; 03067 if( !img ) 03068 CV_Error( CV_StsNullPtr, "Null pointer to image" ); 03069 03070 if( img->roi ) 03071 rect = cvRect( img->roi->xOffset, img->roi->yOffset, 03072 img->roi->width, img->roi->height ); 03073 else 03074 rect = cvRect( 0, 0, img->width, img->height ); 03075 03076 return rect; 03077 } 03078 03079 03080 CV_IMPL void 03081 cvSetImageCOI( IplImage* image, int coi ) 03082 { 03083 if( !image ) 03084 CV_Error( CV_HeaderIsNull, "" ); 03085 03086 if( (unsigned)coi > (unsigned)(image->nChannels) ) 03087 CV_Error( CV_BadCOI, "" ); 03088 03089 if( image->roi || coi != 0 ) 03090 { 03091 if( image->roi ) 03092 { 03093 image->roi->coi = coi; 03094 } 03095 else 03096 { 03097 image->roi = icvCreateROI( coi, 0, 0, image->width, image->height ); 03098 } 03099 } 03100 } 03101 03102 03103 CV_IMPL int 03104 cvGetImageCOI( const IplImage* image ) 03105 { 03106 if( !image ) 03107 CV_Error( CV_HeaderIsNull, "" ); 03108 03109 return image->roi ? image->roi->coi : 0; 03110 } 03111 03112 03113 CV_IMPL IplImage* 03114 cvCloneImage( const IplImage* src ) 03115 { 03116 IplImage* dst = 0; 03117 03118 if( !CV_IS_IMAGE_HDR( src )) 03119 CV_Error( CV_StsBadArg, "Bad image header" ); 03120 03121 if( !CvIPL.cloneImage ) 03122 { 03123 dst = (IplImage*)cvAlloc( sizeof(*dst)); 03124 03125 memcpy( dst, src, sizeof(*src)); 03126 dst->imageData = dst->imageDataOrigin = 0; 03127 dst->roi = 0; 03128 03129 if( src->roi ) 03130 { 03131 dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset, 03132 src->roi->yOffset, src->roi->width, src->roi->height ); 03133 } 03134 03135 if( src->imageData ) 03136 { 03137 int size = src->imageSize; 03138 cvCreateData( dst ); 03139 memcpy( dst->imageData, src->imageData, size ); 03140 } 03141 } 03142 else 03143 dst = CvIPL.cloneImage( src ); 03144 03145 return dst; 03146 } 03147 03148 03149 /****************************************************************************************\ 03150 * Additional operations on CvTermCriteria * 03151 \****************************************************************************************/ 03152 03153 CV_IMPL CvTermCriteria 03154 cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, 03155 int default_max_iters ) 03156 { 03157 CvTermCriteria crit; 03158 03159 crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS; 03160 crit.max_iter = default_max_iters; 03161 crit.epsilon = (float)default_eps; 03162 03163 if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 ) 03164 CV_Error( CV_StsBadArg, 03165 "Unknown type of term criteria" ); 03166 03167 if( (criteria.type & CV_TERMCRIT_ITER) != 0 ) 03168 { 03169 if( criteria.max_iter <= 0 ) 03170 CV_Error( CV_StsBadArg, 03171 "Iterations flag is set and maximum number of iterations is <= 0" ); 03172 crit.max_iter = criteria.max_iter; 03173 } 03174 03175 if( (criteria.type & CV_TERMCRIT_EPS) != 0 ) 03176 { 03177 if( criteria.epsilon < 0 ) 03178 CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" ); 03179 03180 crit.epsilon = criteria.epsilon; 03181 } 03182 03183 if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 ) 03184 CV_Error( CV_StsBadArg, 03185 "Neither accuracy nor maximum iterations " 03186 "number flags are set in criteria type" ); 03187 03188 crit.epsilon = (float)MAX( 0, crit.epsilon ); 03189 crit.max_iter = MAX( 1, crit.max_iter ); 03190 03191 return crit; 03192 } 03193 03194 namespace cv 03195 { 03196 03197 template<> void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const 03198 { cvReleaseMat(&obj); } 03199 03200 template<> void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const 03201 { cvReleaseImage(&obj); } 03202 03203 template<> void DefaultDeleter<CvMatND>::operator ()(CvMatND * obj) const 03204 { cvReleaseMatND(&obj); } 03205 03206 template<> void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const 03207 { cvReleaseSparseMat(&obj); } 03208 03209 template<> void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const 03210 { cvReleaseMemStorage(&obj); } 03211 03212 template<> void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const 03213 { cvReleaseFileStorage(&obj); } 03214 03215 } 03216 03217 /* End of file. */ 03218
Generated on Tue Jul 12 2022 14:45:59 by
1.7.2
