1/*M/////////////////////////////////////////////////////////////////////////////////////// 2// 3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4// 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. 8// 9// 10// Intel License Agreement 11// For Open Source Computer Vision Library 12// 13// Copyright (C) 2000, Intel Corporation, all rights reserved. 14// Third party copyrights are property of their respective owners. 15// 16// Redistribution and use in source and binary forms, with or without modification, 17// are permitted provided that the following conditions are met: 18// 19// * Redistribution's of source code must retain the above copyright notice, 20// this list of conditions and the following disclaimer. 21// 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. 25// 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. 28// 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. 39// 40//M*/ 41 42/* //////////////////////////////////////////////////////////////////// 43// 44// CvMat, CvMatND, CvSparceMat and IplImage support functions 45// (creation, deletion, copying, retrieving and setting elements etc.) 46// 47// */ 48 49#include "precomp.hpp" 50 51#define CV_ORIGIN_TL 0 52#define CV_ORIGIN_BL 1 53 54/* default image row align (in bytes) */ 55#define CV_DEFAULT_IMAGE_ROW_ALIGN 4 56 57 58static struct 59{ 60 Cv_iplCreateImageHeader createHeader; 61 Cv_iplAllocateImageData allocateData; 62 Cv_iplDeallocate deallocate; 63 Cv_iplCreateROI createROI; 64 Cv_iplCloneImage cloneImage; 65} 66CvIPL; 67 68// Makes the library use native IPL image allocators 69CV_IMPL void 70cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader, 71 Cv_iplAllocateImageData allocateData, 72 Cv_iplDeallocate deallocate, 73 Cv_iplCreateROI createROI, 74 Cv_iplCloneImage cloneImage ) 75{ 76 int count = (createHeader != 0) + (allocateData != 0) + (deallocate != 0) + 77 (createROI != 0) + (cloneImage != 0); 78 79 if( count != 0 && count != 5 ) 80 CV_Error( CV_StsBadArg, "Either all the pointers should be null or " 81 "they all should be non-null" ); 82 83 CvIPL.createHeader = createHeader; 84 CvIPL.allocateData = allocateData; 85 CvIPL.deallocate = deallocate; 86 CvIPL.createROI = createROI; 87 CvIPL.cloneImage = cloneImage; 88} 89 90 91/****************************************************************************************\ 92* CvMat creation and basic operations * 93\****************************************************************************************/ 94 95// Creates CvMat and underlying data 96CV_IMPL CvMat* 97cvCreateMat( int height, int width, int type ) 98{ 99 CvMat* arr = cvCreateMatHeader( height, width, type ); 100 cvCreateData( arr ); 101 102 return arr; 103} 104 105 106static void icvCheckHuge( CvMat* arr ) 107{ 108 if( (int64)arr->step*arr->rows > INT_MAX ) 109 arr->type &= ~CV_MAT_CONT_FLAG; 110} 111 112// Creates CvMat header only 113CV_IMPL CvMat* 114cvCreateMatHeader( int rows, int cols, int type ) 115{ 116 type = CV_MAT_TYPE(type); 117 118 if( rows < 0 || cols <= 0 ) 119 CV_Error( CV_StsBadSize, "Non-positive width or height" ); 120 121 int min_step = CV_ELEM_SIZE(type)*cols; 122 if( min_step <= 0 ) 123 CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" ); 124 125 CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr)); 126 127 arr->step = min_step; 128 arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG; 129 arr->rows = rows; 130 arr->cols = cols; 131 arr->data.ptr = 0; 132 arr->refcount = 0; 133 arr->hdr_refcount = 1; 134 135 icvCheckHuge( arr ); 136 return arr; 137} 138 139 140// Initializes CvMat header, allocated by the user 141CV_IMPL CvMat* 142cvInitMatHeader( CvMat* arr, int rows, int cols, 143 int type, void* data, int step ) 144{ 145 if( !arr ) 146 CV_Error( CV_StsNullPtr, "" ); 147 148 if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX ) 149 CV_Error( CV_BadNumChannels, "" ); 150 151 if( rows < 0 || cols <= 0 ) 152 CV_Error( CV_StsBadSize, "Non-positive cols or rows" ); 153 154 type = CV_MAT_TYPE( type ); 155 arr->type = type | CV_MAT_MAGIC_VAL; 156 arr->rows = rows; 157 arr->cols = cols; 158 arr->data.ptr = (uchar*)data; 159 arr->refcount = 0; 160 arr->hdr_refcount = 0; 161 162 int pix_size = CV_ELEM_SIZE(type); 163 int min_step = arr->cols*pix_size; 164 165 if( step != CV_AUTOSTEP && step != 0 ) 166 { 167 if( step < min_step ) 168 CV_Error( CV_BadStep, "" ); 169 arr->step = step; 170 } 171 else 172 { 173 arr->step = min_step; 174 } 175 176 arr->type = CV_MAT_MAGIC_VAL | type | 177 (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0); 178 179 icvCheckHuge( arr ); 180 return arr; 181} 182 183 184// Deallocates the CvMat structure and underlying data 185CV_IMPL void 186cvReleaseMat( CvMat** array ) 187{ 188 if( !array ) 189 CV_Error( CV_HeaderIsNull, "" ); 190 191 if( *array ) 192 { 193 CvMat* arr = *array; 194 195 if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) ) 196 CV_Error( CV_StsBadFlag, "" ); 197 198 *array = 0; 199 200 cvDecRefData( arr ); 201 cvFree( &arr ); 202 } 203} 204 205 206// Creates a copy of matrix 207CV_IMPL CvMat* 208cvCloneMat( const CvMat* src ) 209{ 210 if( !CV_IS_MAT_HDR( src )) 211 CV_Error( CV_StsBadArg, "Bad CvMat header" ); 212 213 CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type ); 214 215 if( src->data.ptr ) 216 { 217 cvCreateData( dst ); 218 cvCopy( src, dst ); 219 } 220 221 return dst; 222} 223 224 225/****************************************************************************************\ 226* CvMatND creation and basic operations * 227\****************************************************************************************/ 228 229CV_IMPL CvMatND* 230cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, 231 int type, void* data ) 232{ 233 type = CV_MAT_TYPE(type); 234 int64 step = CV_ELEM_SIZE(type); 235 236 if( !mat ) 237 CV_Error( CV_StsNullPtr, "NULL matrix header pointer" ); 238 239 if( step == 0 ) 240 CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); 241 242 if( !sizes ) 243 CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" ); 244 245 if( dims <= 0 || dims > CV_MAX_DIM ) 246 CV_Error( CV_StsOutOfRange, 247 "non-positive or too large number of dimensions" ); 248 249 for( int i = dims - 1; i >= 0; i-- ) 250 { 251 if( sizes[i] < 0 ) 252 CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" ); 253 mat->dim[i].size = sizes[i]; 254 if( step > INT_MAX ) 255 CV_Error( CV_StsOutOfRange, "The array is too big" ); 256 mat->dim[i].step = (int)step; 257 step *= sizes[i]; 258 } 259 260 mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type; 261 mat->dims = dims; 262 mat->data.ptr = (uchar*)data; 263 mat->refcount = 0; 264 mat->hdr_refcount = 0; 265 return mat; 266} 267 268 269// Creates CvMatND and underlying data 270CV_IMPL CvMatND* 271cvCreateMatND( int dims, const int* sizes, int type ) 272{ 273 CvMatND* arr = cvCreateMatNDHeader( dims, sizes, type ); 274 cvCreateData( arr ); 275 276 return arr; 277} 278 279 280// Creates CvMatND header only 281CV_IMPL CvMatND* 282cvCreateMatNDHeader( int dims, const int* sizes, int type ) 283{ 284 if( dims <= 0 || dims > CV_MAX_DIM ) 285 CV_Error( CV_StsOutOfRange, 286 "non-positive or too large number of dimensions" ); 287 288 CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) ); 289 290 cvInitMatNDHeader( arr, dims, sizes, type, 0 ); 291 arr->hdr_refcount = 1; 292 return arr; 293} 294 295 296// Creates a copy of nD array 297CV_IMPL CvMatND* 298cvCloneMatND( const CvMatND* src ) 299{ 300 if( !CV_IS_MATND_HDR( src )) 301 CV_Error( CV_StsBadArg, "Bad CvMatND header" ); 302 303 CV_Assert( src->dims <= CV_MAX_DIM ); 304 int sizes[CV_MAX_DIM]; 305 306 for( int i = 0; i < src->dims; i++ ) 307 sizes[i] = src->dim[i].size; 308 309 CvMatND* dst = cvCreateMatNDHeader( src->dims, sizes, src->type ); 310 311 if( src->data.ptr ) 312 { 313 cvCreateData( dst ); 314 cv::Mat _src = cv::cvarrToMat(src); 315 cv::Mat _dst = cv::cvarrToMat(dst); 316 uchar* data0 = dst->data.ptr; 317 _src.copyTo(_dst); 318 CV_Assert(_dst.data == data0); 319 //cvCopy( src, dst ); 320 } 321 322 return dst; 323} 324 325 326static CvMatND* 327cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi ) 328{ 329 CvMatND* result = 0; 330 331 if( coi ) 332 *coi = 0; 333 334 if( !matnd || !arr ) 335 CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); 336 337 if( CV_IS_MATND_HDR(arr)) 338 { 339 if( !((CvMatND*)arr)->data.ptr ) 340 CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); 341 342 result = (CvMatND*)arr; 343 } 344 else 345 { 346 CvMat stub, *mat = (CvMat*)arr; 347 348 if( CV_IS_IMAGE_HDR( mat )) 349 mat = cvGetMat( mat, &stub, coi ); 350 351 if( !CV_IS_MAT_HDR( mat )) 352 CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" ); 353 354 if( !mat->data.ptr ) 355 CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); 356 357 matnd->data.ptr = mat->data.ptr; 358 matnd->refcount = 0; 359 matnd->hdr_refcount = 0; 360 matnd->type = mat->type; 361 matnd->dims = 2; 362 matnd->dim[0].size = mat->rows; 363 matnd->dim[0].step = mat->step; 364 matnd->dim[1].size = mat->cols; 365 matnd->dim[1].step = CV_ELEM_SIZE(mat->type); 366 result = matnd; 367 } 368 369 return result; 370} 371 372 373// returns number of dimensions to iterate. 374/* 375Checks whether <count> arrays have equal type, sizes (mask is optional array 376that needs to have the same size, but 8uC1 or 8sC1 type). 377Returns number of dimensions to iterate through: 3780 means that all arrays are continuous, 3791 means that all arrays are vectors of continuous arrays etc. 380and the size of largest common continuous part of the arrays 381*/ 382CV_IMPL int 383cvInitNArrayIterator( int count, CvArr** arrs, 384 const CvArr* mask, CvMatND* stubs, 385 CvNArrayIterator* iterator, int flags ) 386{ 387 int dims = -1; 388 int i, j, size, dim0 = -1; 389 int64 step; 390 CvMatND* hdr0 = 0; 391 392 if( count < 1 || count > CV_MAX_ARR ) 393 CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" ); 394 395 if( !arrs || !stubs ) 396 CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); 397 398 if( !iterator ) 399 CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" ); 400 401 for( i = 0; i <= count; i++ ) 402 { 403 const CvArr* arr = i < count ? arrs[i] : mask; 404 CvMatND* hdr; 405 406 if( !arr ) 407 { 408 if( i < count ) 409 CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" ); 410 break; 411 } 412 413 if( CV_IS_MATND( arr )) 414 hdr = (CvMatND*)arr; 415 else 416 { 417 int coi = 0; 418 hdr = cvGetMatND( arr, stubs + i, &coi ); 419 if( coi != 0 ) 420 CV_Error( CV_BadCOI, "COI set is not allowed here" ); 421 } 422 423 iterator->hdr[i] = hdr; 424 425 if( i > 0 ) 426 { 427 if( hdr->dims != hdr0->dims ) 428 CV_Error( CV_StsUnmatchedSizes, 429 "Number of dimensions is the same for all arrays" ); 430 431 if( i < count ) 432 { 433 switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK)) 434 { 435 case 0: 436 if( !CV_ARE_TYPES_EQ( hdr, hdr0 )) 437 CV_Error( CV_StsUnmatchedFormats, 438 "Data type is not the same for all arrays" ); 439 break; 440 case CV_NO_DEPTH_CHECK: 441 if( !CV_ARE_CNS_EQ( hdr, hdr0 )) 442 CV_Error( CV_StsUnmatchedFormats, 443 "Number of channels is not the same for all arrays" ); 444 break; 445 case CV_NO_CN_CHECK: 446 if( !CV_ARE_CNS_EQ( hdr, hdr0 )) 447 CV_Error( CV_StsUnmatchedFormats, 448 "Depth is not the same for all arrays" ); 449 break; 450 } 451 } 452 else 453 { 454 if( !CV_IS_MASK_ARR( hdr )) 455 CV_Error( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" ); 456 } 457 458 if( !(flags & CV_NO_SIZE_CHECK) ) 459 { 460 for( j = 0; j < hdr->dims; j++ ) 461 if( hdr->dim[j].size != hdr0->dim[j].size ) 462 CV_Error( CV_StsUnmatchedSizes, 463 "Dimension sizes are the same for all arrays" ); 464 } 465 } 466 else 467 hdr0 = hdr; 468 469 step = CV_ELEM_SIZE(hdr->type); 470 for( j = hdr->dims - 1; j > dim0; j-- ) 471 { 472 if( step != hdr->dim[j].step ) 473 break; 474 step *= hdr->dim[j].size; 475 } 476 477 if( j == dim0 && step > INT_MAX ) 478 j++; 479 480 if( j > dim0 ) 481 dim0 = j; 482 483 iterator->hdr[i] = (CvMatND*)hdr; 484 iterator->ptr[i] = (uchar*)hdr->data.ptr; 485 } 486 487 size = 1; 488 for( j = hdr0->dims - 1; j > dim0; j-- ) 489 size *= hdr0->dim[j].size; 490 491 dims = dim0 + 1; 492 iterator->dims = dims; 493 iterator->count = count; 494 iterator->size = cvSize(size,1); 495 496 for( i = 0; i < dims; i++ ) 497 iterator->stack[i] = hdr0->dim[i].size; 498 499 return dims; 500} 501 502 503// returns zero value if iteration is finished, non-zero otherwise 504CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator ) 505{ 506 assert( iterator != 0 ); 507 int i, dims; 508 509 for( dims = iterator->dims; dims > 0; dims-- ) 510 { 511 for( i = 0; i < iterator->count; i++ ) 512 iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step; 513 514 if( --iterator->stack[dims-1] > 0 ) 515 break; 516 517 const int size = iterator->hdr[0]->dim[dims-1].size; 518 519 for( i = 0; i < iterator->count; i++ ) 520 iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step; 521 522 iterator->stack[dims-1] = size; 523 } 524 525 return dims > 0; 526} 527 528 529/****************************************************************************************\ 530* CvSparseMat creation and basic operations * 531\****************************************************************************************/ 532 533 534// Creates CvMatND and underlying data 535CV_IMPL CvSparseMat* 536cvCreateSparseMat( int dims, const int* sizes, int type ) 537{ 538 type = CV_MAT_TYPE( type ); 539 int pix_size1 = CV_ELEM_SIZE1(type); 540 int pix_size = pix_size1*CV_MAT_CN(type); 541 int i, size; 542 CvMemStorage* storage; 543 544 if( pix_size == 0 ) 545 CV_Error( CV_StsUnsupportedFormat, "invalid array data type" ); 546 547 if( dims <= 0 || dims > CV_MAX_DIM_HEAP ) 548 CV_Error( CV_StsOutOfRange, "bad number of dimensions" ); 549 550 if( !sizes ) 551 CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" ); 552 553 for( i = 0; i < dims; i++ ) 554 { 555 if( sizes[i] <= 0 ) 556 CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" ); 557 } 558 559 CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0])); 560 561 arr->type = CV_SPARSE_MAT_MAGIC_VAL | type; 562 arr->dims = dims; 563 arr->refcount = 0; 564 arr->hdr_refcount = 1; 565 memcpy( arr->size, sizes, dims*sizeof(sizes[0])); 566 567 arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1); 568 arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int)); 569 size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem)); 570 571 storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK ); 572 arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage ); 573 574 arr->hashsize = CV_SPARSE_HASH_SIZE0; 575 size = arr->hashsize*sizeof(arr->hashtable[0]); 576 577 arr->hashtable = (void**)cvAlloc( size ); 578 memset( arr->hashtable, 0, size ); 579 580 return arr; 581} 582 583 584// Creates CvMatND and underlying data 585CV_IMPL void 586cvReleaseSparseMat( CvSparseMat** array ) 587{ 588 if( !array ) 589 CV_Error( CV_HeaderIsNull, "" ); 590 591 if( *array ) 592 { 593 CvSparseMat* arr = *array; 594 595 if( !CV_IS_SPARSE_MAT_HDR(arr) ) 596 CV_Error( CV_StsBadFlag, "" ); 597 598 *array = 0; 599 600 CvMemStorage* storage = arr->heap->storage; 601 cvReleaseMemStorage( &storage ); 602 cvFree( &arr->hashtable ); 603 cvFree( &arr ); 604 } 605} 606 607 608// Creates CvMatND and underlying data 609CV_IMPL CvSparseMat* 610cvCloneSparseMat( const CvSparseMat* src ) 611{ 612 if( !CV_IS_SPARSE_MAT_HDR(src) ) 613 CV_Error( CV_StsBadArg, "Invalid sparse array header" ); 614 615 CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type ); 616 cvCopy( src, dst ); 617 return dst; 618} 619 620 621CvSparseNode* 622cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator ) 623{ 624 CvSparseNode* node = 0; 625 int idx; 626 627 if( !CV_IS_SPARSE_MAT( mat )) 628 CV_Error( CV_StsBadArg, "Invalid sparse matrix header" ); 629 630 if( !iterator ) 631 CV_Error( CV_StsNullPtr, "NULL iterator pointer" ); 632 633 iterator->mat = (CvSparseMat*)mat; 634 iterator->node = 0; 635 636 for( idx = 0; idx < mat->hashsize; idx++ ) 637 if( mat->hashtable[idx] ) 638 { 639 node = iterator->node = (CvSparseNode*)mat->hashtable[idx]; 640 break; 641 } 642 643 iterator->curidx = idx; 644 return node; 645} 646 647#define ICV_SPARSE_MAT_HASH_MULTIPLIER cv::SparseMat::HASH_SCALE 648 649static uchar* 650icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type, 651 int create_node, unsigned* precalc_hashval ) 652{ 653 uchar* ptr = 0; 654 int i, tabidx; 655 unsigned hashval = 0; 656 CvSparseNode *node; 657 assert( CV_IS_SPARSE_MAT( mat )); 658 659 if( !precalc_hashval ) 660 { 661 for( i = 0; i < mat->dims; i++ ) 662 { 663 int t = idx[i]; 664 if( (unsigned)t >= (unsigned)mat->size[i] ) 665 CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); 666 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; 667 } 668 } 669 else 670 { 671 hashval = *precalc_hashval; 672 } 673 674 tabidx = hashval & (mat->hashsize - 1); 675 hashval &= INT_MAX; 676 677 if( create_node >= -1 ) 678 { 679 for( node = (CvSparseNode*)mat->hashtable[tabidx]; 680 node != 0; node = node->next ) 681 { 682 if( node->hashval == hashval ) 683 { 684 int* nodeidx = CV_NODE_IDX(mat,node); 685 for( i = 0; i < mat->dims; i++ ) 686 if( idx[i] != nodeidx[i] ) 687 break; 688 if( i == mat->dims ) 689 { 690 ptr = (uchar*)CV_NODE_VAL(mat,node); 691 break; 692 } 693 } 694 } 695 } 696 697 if( !ptr && create_node ) 698 { 699 if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO ) 700 { 701 void** newtable; 702 int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0); 703 int newrawsize = newsize*sizeof(newtable[0]); 704 705 CvSparseMatIterator iterator; 706 assert( (newsize & (newsize - 1)) == 0 ); 707 708 // resize hash table 709 newtable = (void**)cvAlloc( newrawsize ); 710 memset( newtable, 0, newrawsize ); 711 712 node = cvInitSparseMatIterator( mat, &iterator ); 713 while( node ) 714 { 715 CvSparseNode* next = cvGetNextSparseNode( &iterator ); 716 int newidx = node->hashval & (newsize - 1); 717 node->next = (CvSparseNode*)newtable[newidx]; 718 newtable[newidx] = node; 719 node = next; 720 } 721 722 cvFree( &mat->hashtable ); 723 mat->hashtable = newtable; 724 mat->hashsize = newsize; 725 tabidx = hashval & (newsize - 1); 726 } 727 728 node = (CvSparseNode*)cvSetNew( mat->heap ); 729 node->hashval = hashval; 730 node->next = (CvSparseNode*)mat->hashtable[tabidx]; 731 mat->hashtable[tabidx] = node; 732 memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0])); 733 ptr = (uchar*)CV_NODE_VAL(mat,node); 734 if( create_node > 0 ) 735 memset( ptr, 0, CV_ELEM_SIZE(mat->type)); 736 } 737 738 if( _type ) 739 *_type = CV_MAT_TYPE(mat->type); 740 741 return ptr; 742} 743 744 745static void 746icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval ) 747{ 748 int i, tabidx; 749 unsigned hashval = 0; 750 CvSparseNode *node, *prev = 0; 751 assert( CV_IS_SPARSE_MAT( mat )); 752 753 if( !precalc_hashval ) 754 { 755 for( i = 0; i < mat->dims; i++ ) 756 { 757 int t = idx[i]; 758 if( (unsigned)t >= (unsigned)mat->size[i] ) 759 CV_Error( CV_StsOutOfRange, "One of indices is out of range" ); 760 hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t; 761 } 762 } 763 else 764 { 765 hashval = *precalc_hashval; 766 } 767 768 tabidx = hashval & (mat->hashsize - 1); 769 hashval &= INT_MAX; 770 771 for( node = (CvSparseNode*)mat->hashtable[tabidx]; 772 node != 0; prev = node, node = node->next ) 773 { 774 if( node->hashval == hashval ) 775 { 776 int* nodeidx = CV_NODE_IDX(mat,node); 777 for( i = 0; i < mat->dims; i++ ) 778 if( idx[i] != nodeidx[i] ) 779 break; 780 if( i == mat->dims ) 781 break; 782 } 783 } 784 785 if( node ) 786 { 787 if( prev ) 788 prev->next = node->next; 789 else 790 mat->hashtable[tabidx] = node->next; 791 cvSetRemoveByPtr( mat->heap, node ); 792 } 793} 794 795 796/****************************************************************************************\ 797* Common for multiple array types operations * 798\****************************************************************************************/ 799 800// Allocates underlying array data 801CV_IMPL void 802cvCreateData( CvArr* arr ) 803{ 804 if( CV_IS_MAT_HDR_Z( arr )) 805 { 806 size_t step, total_size; 807 CvMat* mat = (CvMat*)arr; 808 step = mat->step; 809 810 if( mat->rows == 0 || mat->cols == 0 ) 811 return; 812 813 if( mat->data.ptr != 0 ) 814 CV_Error( CV_StsError, "Data is already allocated" ); 815 816 if( step == 0 ) 817 step = CV_ELEM_SIZE(mat->type)*mat->cols; 818 819 int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN; 820 total_size = (size_t)_total_size; 821 if(_total_size != (int64)total_size) 822 CV_Error(CV_StsNoMem, "Too big buffer is allocated" ); 823 mat->refcount = (int*)cvAlloc( (size_t)total_size ); 824 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); 825 *mat->refcount = 1; 826 } 827 else if( CV_IS_IMAGE_HDR(arr)) 828 { 829 IplImage* img = (IplImage*)arr; 830 831 if( img->imageData != 0 ) 832 CV_Error( CV_StsError, "Data is already allocated" ); 833 834 if( !CvIPL.allocateData ) 835 { 836 img->imageData = img->imageDataOrigin = 837 (char*)cvAlloc( (size_t)img->imageSize ); 838 } 839 else 840 { 841 int depth = img->depth; 842 int width = img->width; 843 844 if( img->depth == IPL_DEPTH_32F || img->depth == IPL_DEPTH_64F ) 845 { 846 img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double); 847 img->depth = IPL_DEPTH_8U; 848 } 849 850 CvIPL.allocateData( img, 0, 0 ); 851 852 img->width = width; 853 img->depth = depth; 854 } 855 } 856 else if( CV_IS_MATND_HDR( arr )) 857 { 858 CvMatND* mat = (CvMatND*)arr; 859 size_t total_size = CV_ELEM_SIZE(mat->type); 860 861 if( mat->dim[0].size == 0 ) 862 return; 863 864 if( mat->data.ptr != 0 ) 865 CV_Error( CV_StsError, "Data is already allocated" ); 866 867 if( CV_IS_MAT_CONT( mat->type )) 868 { 869 total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ? 870 (size_t)mat->dim[0].step : total_size); 871 } 872 else 873 { 874 int i; 875 for( i = mat->dims - 1; i >= 0; i-- ) 876 { 877 size_t size = (size_t)mat->dim[i].step*mat->dim[i].size; 878 879 if( total_size < size ) 880 total_size = size; 881 } 882 } 883 884 mat->refcount = (int*)cvAlloc( total_size + 885 sizeof(int) + CV_MALLOC_ALIGN ); 886 mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN ); 887 *mat->refcount = 1; 888 } 889 else 890 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 891} 892 893 894// Assigns external data to array 895CV_IMPL void 896cvSetData( CvArr* arr, void* data, int step ) 897{ 898 int pix_size, min_step; 899 900 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) ) 901 cvReleaseData( arr ); 902 903 if( CV_IS_MAT_HDR( arr )) 904 { 905 CvMat* mat = (CvMat*)arr; 906 907 int type = CV_MAT_TYPE(mat->type); 908 pix_size = CV_ELEM_SIZE(type); 909 min_step = mat->cols*pix_size; 910 911 if( step != CV_AUTOSTEP && step != 0 ) 912 { 913 if( step < min_step && data != 0 ) 914 CV_Error( CV_BadStep, "" ); 915 mat->step = step; 916 } 917 else 918 mat->step = min_step; 919 920 mat->data.ptr = (uchar*)data; 921 mat->type = CV_MAT_MAGIC_VAL | type | 922 (mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0); 923 icvCheckHuge( mat ); 924 } 925 else if( CV_IS_IMAGE_HDR( arr )) 926 { 927 IplImage* img = (IplImage*)arr; 928 929 pix_size = ((img->depth & 255) >> 3)*img->nChannels; 930 min_step = img->width*pix_size; 931 932 if( step != CV_AUTOSTEP && img->height > 1 ) 933 { 934 if( step < min_step && data != 0 ) 935 CV_Error( CV_BadStep, "" ); 936 img->widthStep = step; 937 } 938 else 939 { 940 img->widthStep = min_step; 941 } 942 943 img->imageSize = img->widthStep * img->height; 944 img->imageData = img->imageDataOrigin = (char*)data; 945 946 if( (((int)(size_t)data | step) & 7) == 0 && 947 cvAlign(img->width * pix_size, 8) == step ) 948 img->align = 8; 949 else 950 img->align = 4; 951 } 952 else if( CV_IS_MATND_HDR( arr )) 953 { 954 CvMatND* mat = (CvMatND*)arr; 955 int i; 956 int64 cur_step; 957 958 if( step != CV_AUTOSTEP ) 959 CV_Error( CV_BadStep, 960 "For multidimensional array only CV_AUTOSTEP is allowed here" ); 961 962 mat->data.ptr = (uchar*)data; 963 cur_step = CV_ELEM_SIZE(mat->type); 964 965 for( i = mat->dims - 1; i >= 0; i-- ) 966 { 967 if( cur_step > INT_MAX ) 968 CV_Error( CV_StsOutOfRange, "The array is too big" ); 969 mat->dim[i].step = (int)cur_step; 970 cur_step *= mat->dim[i].size; 971 } 972 } 973 else 974 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 975} 976 977 978// Deallocates array's data 979CV_IMPL void 980cvReleaseData( CvArr* arr ) 981{ 982 if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr )) 983 { 984 CvMat* mat = (CvMat*)arr; 985 cvDecRefData( mat ); 986 } 987 else if( CV_IS_IMAGE_HDR( arr )) 988 { 989 IplImage* img = (IplImage*)arr; 990 991 if( !CvIPL.deallocate ) 992 { 993 char* ptr = img->imageDataOrigin; 994 img->imageData = img->imageDataOrigin = 0; 995 cvFree( &ptr ); 996 } 997 else 998 { 999 CvIPL.deallocate( img, IPL_IMAGE_DATA ); 1000 } 1001 } 1002 else 1003 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1004} 1005 1006 1007// Retrieves essential information about image ROI or CvMat data 1008CV_IMPL void 1009cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size ) 1010{ 1011 if( CV_IS_MAT( arr )) 1012 { 1013 CvMat *mat = (CvMat*)arr; 1014 1015 if( step ) 1016 *step = mat->step; 1017 1018 if( data ) 1019 *data = mat->data.ptr; 1020 1021 if( roi_size ) 1022 *roi_size = cvGetMatSize( mat ); 1023 } 1024 else if( CV_IS_IMAGE( arr )) 1025 { 1026 IplImage* img = (IplImage*)arr; 1027 1028 if( step ) 1029 *step = img->widthStep; 1030 1031 if( data ) 1032 *data = cvPtr2D( img, 0, 0 ); 1033 1034 if( roi_size ) 1035 { 1036 if( img->roi ) 1037 { 1038 *roi_size = cvSize( img->roi->width, img->roi->height ); 1039 } 1040 else 1041 { 1042 *roi_size = cvSize( img->width, img->height ); 1043 } 1044 } 1045 } 1046 else if( CV_IS_MATND( arr )) 1047 { 1048 CvMatND* mat = (CvMatND*)arr; 1049 1050 if( !CV_IS_MAT_CONT( mat->type )) 1051 CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); 1052 1053 if( data ) 1054 *data = mat->data.ptr; 1055 1056 if( roi_size || step ) 1057 { 1058 if( roi_size ) 1059 { 1060 int size1 = mat->dim[0].size, size2 = 1; 1061 1062 if( mat->dims > 2 ) 1063 { 1064 int i; 1065 for( i = 1; i < mat->dims; i++ ) 1066 size1 *= mat->dim[i].size; 1067 } 1068 else 1069 size2 = mat->dim[1].size; 1070 1071 roi_size->width = size2; 1072 roi_size->height = size1; 1073 } 1074 1075 if( step ) 1076 *step = mat->dim[0].step; 1077 } 1078 } 1079 else 1080 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1081} 1082 1083 1084CV_IMPL int 1085cvGetElemType( const CvArr* arr ) 1086{ 1087 int type = -1; 1088 if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr)) 1089 type = CV_MAT_TYPE( ((CvMat*)arr)->type ); 1090 else if( CV_IS_IMAGE(arr)) 1091 { 1092 IplImage* img = (IplImage*)arr; 1093 type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels ); 1094 } 1095 else 1096 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1097 1098 return type; 1099} 1100 1101 1102// Returns a number of array dimensions 1103CV_IMPL int 1104cvGetDims( const CvArr* arr, int* sizes ) 1105{ 1106 int dims = -1; 1107 if( CV_IS_MAT_HDR( arr )) 1108 { 1109 CvMat* mat = (CvMat*)arr; 1110 1111 dims = 2; 1112 if( sizes ) 1113 { 1114 sizes[0] = mat->rows; 1115 sizes[1] = mat->cols; 1116 } 1117 } 1118 else if( CV_IS_IMAGE( arr )) 1119 { 1120 IplImage* img = (IplImage*)arr; 1121 dims = 2; 1122 1123 if( sizes ) 1124 { 1125 sizes[0] = img->height; 1126 sizes[1] = img->width; 1127 } 1128 } 1129 else if( CV_IS_MATND_HDR( arr )) 1130 { 1131 CvMatND* mat = (CvMatND*)arr; 1132 dims = mat->dims; 1133 1134 if( sizes ) 1135 { 1136 int i; 1137 for( i = 0; i < dims; i++ ) 1138 sizes[i] = mat->dim[i].size; 1139 } 1140 } 1141 else if( CV_IS_SPARSE_MAT_HDR( arr )) 1142 { 1143 CvSparseMat* mat = (CvSparseMat*)arr; 1144 dims = mat->dims; 1145 1146 if( sizes ) 1147 memcpy( sizes, mat->size, dims*sizeof(sizes[0])); 1148 } 1149 else 1150 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1151 1152 return dims; 1153} 1154 1155 1156// Returns the size of particular array dimension 1157CV_IMPL int 1158cvGetDimSize( const CvArr* arr, int index ) 1159{ 1160 int size = -1; 1161 1162 if( CV_IS_MAT( arr )) 1163 { 1164 CvMat *mat = (CvMat*)arr; 1165 1166 switch( index ) 1167 { 1168 case 0: 1169 size = mat->rows; 1170 break; 1171 case 1: 1172 size = mat->cols; 1173 break; 1174 default: 1175 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 1176 } 1177 } 1178 else if( CV_IS_IMAGE( arr )) 1179 { 1180 IplImage* img = (IplImage*)arr; 1181 1182 switch( index ) 1183 { 1184 case 0: 1185 size = !img->roi ? img->height : img->roi->height; 1186 break; 1187 case 1: 1188 size = !img->roi ? img->width : img->roi->width; 1189 break; 1190 default: 1191 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 1192 } 1193 } 1194 else if( CV_IS_MATND_HDR( arr )) 1195 { 1196 CvMatND* mat = (CvMatND*)arr; 1197 1198 if( (unsigned)index >= (unsigned)mat->dims ) 1199 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 1200 1201 size = mat->dim[index].size; 1202 } 1203 else if( CV_IS_SPARSE_MAT_HDR( arr )) 1204 { 1205 CvSparseMat* mat = (CvSparseMat*)arr; 1206 1207 if( (unsigned)index >= (unsigned)mat->dims ) 1208 CV_Error( CV_StsOutOfRange, "bad dimension index" ); 1209 1210 size = mat->size[index]; 1211 } 1212 else 1213 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1214 1215 return size; 1216} 1217 1218 1219// Returns the size of CvMat or IplImage 1220CV_IMPL CvSize 1221cvGetSize( const CvArr* arr ) 1222{ 1223 CvSize size; 1224 1225 if( CV_IS_MAT_HDR_Z( arr )) 1226 { 1227 CvMat *mat = (CvMat*)arr; 1228 1229 size.width = mat->cols; 1230 size.height = mat->rows; 1231 } 1232 else if( CV_IS_IMAGE_HDR( arr )) 1233 { 1234 IplImage* img = (IplImage*)arr; 1235 1236 if( img->roi ) 1237 { 1238 size.width = img->roi->width; 1239 size.height = img->roi->height; 1240 } 1241 else 1242 { 1243 size.width = img->width; 1244 size.height = img->height; 1245 } 1246 } 1247 else 1248 CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" ); 1249 1250 return size; 1251} 1252 1253 1254// Selects sub-array (no data is copied) 1255CV_IMPL CvMat* 1256cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ) 1257{ 1258 CvMat* res = 0; 1259 CvMat stub, *mat = (CvMat*)arr; 1260 1261 if( !CV_IS_MAT( mat )) 1262 mat = cvGetMat( mat, &stub ); 1263 1264 if( !submat ) 1265 CV_Error( CV_StsNullPtr, "" ); 1266 1267 if( (rect.x|rect.y|rect.width|rect.height) < 0 ) 1268 CV_Error( CV_StsBadSize, "" ); 1269 1270 if( rect.x + rect.width > mat->cols || 1271 rect.y + rect.height > mat->rows ) 1272 CV_Error( CV_StsBadSize, "" ); 1273 1274 { 1275 /* 1276 int* refcount = mat->refcount; 1277 1278 if( refcount ) 1279 ++*refcount; 1280 1281 cvDecRefData( submat ); 1282 */ 1283 submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step + 1284 rect.x*CV_ELEM_SIZE(mat->type); 1285 submat->step = mat->step; 1286 submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) | 1287 (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0); 1288 submat->rows = rect.height; 1289 submat->cols = rect.width; 1290 submat->refcount = 0; 1291 res = submat; 1292 } 1293 1294 return res; 1295} 1296 1297 1298// Selects array's row span. 1299CV_IMPL CvMat* 1300cvGetRows( const CvArr* arr, CvMat* submat, 1301 int start_row, int end_row, int delta_row ) 1302{ 1303 CvMat* res = 0; 1304 CvMat stub, *mat = (CvMat*)arr; 1305 1306 if( !CV_IS_MAT( mat )) 1307 mat = cvGetMat( mat, &stub ); 1308 1309 if( !submat ) 1310 CV_Error( CV_StsNullPtr, "" ); 1311 1312 if( (unsigned)start_row >= (unsigned)mat->rows || 1313 (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 ) 1314 CV_Error( CV_StsOutOfRange, "" ); 1315 1316 { 1317 /* 1318 int* refcount = mat->refcount; 1319 1320 if( refcount ) 1321 ++*refcount; 1322 1323 cvDecRefData( submat ); 1324 */ 1325 if( delta_row == 1 ) 1326 { 1327 submat->rows = end_row - start_row; 1328 submat->step = mat->step; 1329 } 1330 else 1331 { 1332 submat->rows = (end_row - start_row + delta_row - 1)/delta_row; 1333 submat->step = mat->step * delta_row; 1334 } 1335 1336 submat->cols = mat->cols; 1337 submat->step &= submat->rows > 1 ? -1 : 0; 1338 submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step; 1339 submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) & 1340 (delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1); 1341 submat->refcount = 0; 1342 submat->hdr_refcount = 0; 1343 res = submat; 1344 } 1345 1346 return res; 1347} 1348 1349 1350// Selects array's column span. 1351CV_IMPL CvMat* 1352cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ) 1353{ 1354 CvMat* res = 0; 1355 CvMat stub, *mat = (CvMat*)arr; 1356 int cols; 1357 1358 if( !CV_IS_MAT( mat )) 1359 mat = cvGetMat( mat, &stub ); 1360 1361 if( !submat ) 1362 CV_Error( CV_StsNullPtr, "" ); 1363 1364 cols = mat->cols; 1365 if( (unsigned)start_col >= (unsigned)cols || 1366 (unsigned)end_col > (unsigned)cols ) 1367 CV_Error( CV_StsOutOfRange, "" ); 1368 1369 { 1370 /* 1371 int* refcount = mat->refcount; 1372 1373 if( refcount ) 1374 ++*refcount; 1375 1376 cvDecRefData( submat ); 1377 */ 1378 submat->rows = mat->rows; 1379 submat->cols = end_col - start_col; 1380 submat->step = mat->step; 1381 submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type); 1382 submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1); 1383 submat->refcount = 0; 1384 submat->hdr_refcount = 0; 1385 res = submat; 1386 } 1387 1388 return res; 1389} 1390 1391 1392// Selects array diagonal 1393CV_IMPL CvMat* 1394cvGetDiag( const CvArr* arr, CvMat* submat, int diag ) 1395{ 1396 CvMat* res = 0; 1397 CvMat stub, *mat = (CvMat*)arr; 1398 int len, pix_size; 1399 1400 if( !CV_IS_MAT( mat )) 1401 mat = cvGetMat( mat, &stub ); 1402 1403 if( !submat ) 1404 CV_Error( CV_StsNullPtr, "" ); 1405 1406 pix_size = CV_ELEM_SIZE(mat->type); 1407 1408 /*{ 1409 int* refcount = mat->refcount; 1410 1411 if( refcount ) 1412 ++*refcount; 1413 1414 cvDecRefData( submat ); 1415 }*/ 1416 1417 if( diag >= 0 ) 1418 { 1419 len = mat->cols - diag; 1420 1421 if( len <= 0 ) 1422 CV_Error( CV_StsOutOfRange, "" ); 1423 1424 len = CV_IMIN( len, mat->rows ); 1425 submat->data.ptr = mat->data.ptr + diag*pix_size; 1426 } 1427 else 1428 { 1429 len = mat->rows + diag; 1430 1431 if( len <= 0 ) 1432 CV_Error( CV_StsOutOfRange, "" ); 1433 1434 len = CV_IMIN( len, mat->cols ); 1435 submat->data.ptr = mat->data.ptr - diag*mat->step; 1436 } 1437 1438 submat->rows = len; 1439 submat->cols = 1; 1440 submat->step = mat->step + (submat->rows > 1 ? pix_size : 0); 1441 submat->type = mat->type; 1442 if( submat->rows > 1 ) 1443 submat->type &= ~CV_MAT_CONT_FLAG; 1444 else 1445 submat->type |= CV_MAT_CONT_FLAG; 1446 submat->refcount = 0; 1447 submat->hdr_refcount = 0; 1448 res = submat; 1449 1450 return res; 1451} 1452 1453 1454/****************************************************************************************\ 1455* Operations on CvScalar and accessing array elements * 1456\****************************************************************************************/ 1457 1458// Converts CvScalar to specified type 1459CV_IMPL void 1460cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 ) 1461{ 1462 type = CV_MAT_TYPE(type); 1463 int cn = CV_MAT_CN( type ); 1464 int depth = type & CV_MAT_DEPTH_MASK; 1465 1466 assert( scalar && data ); 1467 if( (unsigned)(cn - 1) >= 4 ) 1468 CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); 1469 1470 switch( depth ) 1471 { 1472 case CV_8UC1: 1473 while( cn-- ) 1474 { 1475 int t = cvRound( scalar->val[cn] ); 1476 ((uchar*)data)[cn] = cv::saturate_cast<uchar>(t); 1477 } 1478 break; 1479 case CV_8SC1: 1480 while( cn-- ) 1481 { 1482 int t = cvRound( scalar->val[cn] ); 1483 ((char*)data)[cn] = cv::saturate_cast<schar>(t); 1484 } 1485 break; 1486 case CV_16UC1: 1487 while( cn-- ) 1488 { 1489 int t = cvRound( scalar->val[cn] ); 1490 ((ushort*)data)[cn] = cv::saturate_cast<ushort>(t); 1491 } 1492 break; 1493 case CV_16SC1: 1494 while( cn-- ) 1495 { 1496 int t = cvRound( scalar->val[cn] ); 1497 ((short*)data)[cn] = cv::saturate_cast<short>(t); 1498 } 1499 break; 1500 case CV_32SC1: 1501 while( cn-- ) 1502 ((int*)data)[cn] = cvRound( scalar->val[cn] ); 1503 break; 1504 case CV_32FC1: 1505 while( cn-- ) 1506 ((float*)data)[cn] = (float)(scalar->val[cn]); 1507 break; 1508 case CV_64FC1: 1509 while( cn-- ) 1510 ((double*)data)[cn] = (double)(scalar->val[cn]); 1511 break; 1512 default: 1513 assert(0); 1514 CV_Error( CV_BadDepth, "" ); 1515 } 1516 1517 if( extend_to_12 ) 1518 { 1519 int pix_size = CV_ELEM_SIZE(type); 1520 int offset = CV_ELEM_SIZE1(depth)*12; 1521 1522 do 1523 { 1524 offset -= pix_size; 1525 memcpy((char*)data + offset, data, pix_size); 1526 } 1527 while( offset > pix_size ); 1528 } 1529} 1530 1531 1532// Converts data of specified type to CvScalar 1533CV_IMPL void 1534cvRawDataToScalar( const void* data, int flags, CvScalar* scalar ) 1535{ 1536 int cn = CV_MAT_CN( flags ); 1537 1538 assert( scalar && data ); 1539 1540 if( (unsigned)(cn - 1) >= 4 ) 1541 CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); 1542 1543 memset( scalar->val, 0, sizeof(scalar->val)); 1544 1545 switch( CV_MAT_DEPTH( flags )) 1546 { 1547 case CV_8U: 1548 while( cn-- ) 1549 scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]); 1550 break; 1551 case CV_8S: 1552 while( cn-- ) 1553 scalar->val[cn] = CV_8TO32F(((char*)data)[cn]); 1554 break; 1555 case CV_16U: 1556 while( cn-- ) 1557 scalar->val[cn] = ((ushort*)data)[cn]; 1558 break; 1559 case CV_16S: 1560 while( cn-- ) 1561 scalar->val[cn] = ((short*)data)[cn]; 1562 break; 1563 case CV_32S: 1564 while( cn-- ) 1565 scalar->val[cn] = ((int*)data)[cn]; 1566 break; 1567 case CV_32F: 1568 while( cn-- ) 1569 scalar->val[cn] = ((float*)data)[cn]; 1570 break; 1571 case CV_64F: 1572 while( cn-- ) 1573 scalar->val[cn] = ((double*)data)[cn]; 1574 break; 1575 default: 1576 assert(0); 1577 CV_Error( CV_BadDepth, "" ); 1578 } 1579} 1580 1581 1582static double icvGetReal( const void* data, int type ) 1583{ 1584 switch( type ) 1585 { 1586 case CV_8U: 1587 return *(uchar*)data; 1588 case CV_8S: 1589 return *(char*)data; 1590 case CV_16U: 1591 return *(ushort*)data; 1592 case CV_16S: 1593 return *(short*)data; 1594 case CV_32S: 1595 return *(int*)data; 1596 case CV_32F: 1597 return *(float*)data; 1598 case CV_64F: 1599 return *(double*)data; 1600 } 1601 1602 return 0; 1603} 1604 1605 1606static void icvSetReal( double value, const void* data, int type ) 1607{ 1608 if( type < CV_32F ) 1609 { 1610 int ivalue = cvRound(value); 1611 switch( type ) 1612 { 1613 case CV_8U: 1614 *(uchar*)data = cv::saturate_cast<uchar>(ivalue); 1615 break; 1616 case CV_8S: 1617 *(schar*)data = cv::saturate_cast<schar>(ivalue); 1618 break; 1619 case CV_16U: 1620 *(ushort*)data = cv::saturate_cast<ushort>(ivalue); 1621 break; 1622 case CV_16S: 1623 *(short*)data = cv::saturate_cast<short>(ivalue); 1624 break; 1625 case CV_32S: 1626 *(int*)data = cv::saturate_cast<int>(ivalue); 1627 break; 1628 } 1629 } 1630 else 1631 { 1632 switch( type ) 1633 { 1634 case CV_32F: 1635 *(float*)data = (float)value; 1636 break; 1637 case CV_64F: 1638 *(double*)data = value; 1639 break; 1640 } 1641 } 1642} 1643 1644 1645// Returns pointer to specified element of array (linear index is used) 1646CV_IMPL uchar* 1647cvPtr1D( const CvArr* arr, int idx, int* _type ) 1648{ 1649 uchar* ptr = 0; 1650 if( CV_IS_MAT( arr )) 1651 { 1652 CvMat* mat = (CvMat*)arr; 1653 1654 int type = CV_MAT_TYPE(mat->type); 1655 int pix_size = CV_ELEM_SIZE(type); 1656 1657 if( _type ) 1658 *_type = type; 1659 1660 // the first part is mul-free sufficient check 1661 // that the index is within the matrix 1662 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 1663 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 1664 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1665 1666 if( CV_IS_MAT_CONT(mat->type)) 1667 { 1668 ptr = mat->data.ptr + (size_t)idx*pix_size; 1669 } 1670 else 1671 { 1672 int row, col; 1673 if( mat->cols == 1 ) 1674 row = idx, col = 0; 1675 else 1676 row = idx/mat->cols, col = idx - row*mat->cols; 1677 ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size; 1678 } 1679 } 1680 else if( CV_IS_IMAGE_HDR( arr )) 1681 { 1682 IplImage* img = (IplImage*)arr; 1683 int width = !img->roi ? img->width : img->roi->width; 1684 int y = idx/width, x = idx - y*width; 1685 1686 ptr = cvPtr2D( arr, y, x, _type ); 1687 } 1688 else if( CV_IS_MATND( arr )) 1689 { 1690 CvMatND* mat = (CvMatND*)arr; 1691 int j, type = CV_MAT_TYPE(mat->type); 1692 size_t size = mat->dim[0].size; 1693 1694 if( _type ) 1695 *_type = type; 1696 1697 for( j = 1; j < mat->dims; j++ ) 1698 size *= mat->dim[j].size; 1699 1700 if((unsigned)idx >= (unsigned)size ) 1701 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1702 1703 if( CV_IS_MAT_CONT(mat->type)) 1704 { 1705 int pix_size = CV_ELEM_SIZE(type); 1706 ptr = mat->data.ptr + (size_t)idx*pix_size; 1707 } 1708 else 1709 { 1710 ptr = mat->data.ptr; 1711 for( j = mat->dims - 1; j >= 0; j-- ) 1712 { 1713 int sz = mat->dim[j].size; 1714 if( sz ) 1715 { 1716 int t = idx/sz; 1717 ptr += (idx - t*sz)*mat->dim[j].step; 1718 idx = t; 1719 } 1720 } 1721 } 1722 } 1723 else if( CV_IS_SPARSE_MAT( arr )) 1724 { 1725 CvSparseMat* m = (CvSparseMat*)arr; 1726 if( m->dims == 1 ) 1727 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 ); 1728 else 1729 { 1730 int i, n = m->dims; 1731 CV_DbgAssert( n <= CV_MAX_DIM_HEAP ); 1732 int _idx[CV_MAX_DIM_HEAP]; 1733 1734 for( i = n - 1; i >= 0; i-- ) 1735 { 1736 int t = idx / m->size[i]; 1737 _idx[i] = idx - t*m->size[i]; 1738 idx = t; 1739 } 1740 ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 ); 1741 } 1742 } 1743 else 1744 { 1745 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1746 } 1747 1748 return ptr; 1749} 1750 1751 1752// Returns pointer to specified element of 2d array 1753CV_IMPL uchar* 1754cvPtr2D( const CvArr* arr, int y, int x, int* _type ) 1755{ 1756 uchar* ptr = 0; 1757 if( CV_IS_MAT( arr )) 1758 { 1759 CvMat* mat = (CvMat*)arr; 1760 int type; 1761 1762 if( (unsigned)y >= (unsigned)(mat->rows) || 1763 (unsigned)x >= (unsigned)(mat->cols) ) 1764 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1765 1766 type = CV_MAT_TYPE(mat->type); 1767 if( _type ) 1768 *_type = type; 1769 1770 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 1771 } 1772 else if( CV_IS_IMAGE( arr )) 1773 { 1774 IplImage* img = (IplImage*)arr; 1775 int pix_size = (img->depth & 255) >> 3; 1776 int width, height; 1777 ptr = (uchar*)img->imageData; 1778 1779 if( img->dataOrder == 0 ) 1780 pix_size *= img->nChannels; 1781 1782 if( img->roi ) 1783 { 1784 width = img->roi->width; 1785 height = img->roi->height; 1786 1787 ptr += img->roi->yOffset*img->widthStep + 1788 img->roi->xOffset*pix_size; 1789 1790 if( img->dataOrder ) 1791 { 1792 int coi = img->roi->coi; 1793 if( !coi ) 1794 CV_Error( CV_BadCOI, 1795 "COI must be non-null in case of planar images" ); 1796 ptr += (coi - 1)*img->imageSize; 1797 } 1798 } 1799 else 1800 { 1801 width = img->width; 1802 height = img->height; 1803 } 1804 1805 if( (unsigned)y >= (unsigned)height || 1806 (unsigned)x >= (unsigned)width ) 1807 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1808 1809 ptr += y*img->widthStep + x*pix_size; 1810 1811 if( _type ) 1812 { 1813 int type = IPL2CV_DEPTH(img->depth); 1814 if( type < 0 || (unsigned)(img->nChannels - 1) > 3 ) 1815 CV_Error( CV_StsUnsupportedFormat, "" ); 1816 1817 *_type = CV_MAKETYPE( type, img->nChannels ); 1818 } 1819 } 1820 else if( CV_IS_MATND( arr )) 1821 { 1822 CvMatND* mat = (CvMatND*)arr; 1823 1824 if( mat->dims != 2 || 1825 (unsigned)y >= (unsigned)(mat->dim[0].size) || 1826 (unsigned)x >= (unsigned)(mat->dim[1].size) ) 1827 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1828 1829 ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step; 1830 if( _type ) 1831 *_type = CV_MAT_TYPE(mat->type); 1832 } 1833 else if( CV_IS_SPARSE_MAT( arr )) 1834 { 1835 int idx[] = { y, x }; 1836 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 ); 1837 } 1838 else 1839 { 1840 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1841 } 1842 1843 return ptr; 1844} 1845 1846 1847// Returns pointer to specified element of 3d array 1848CV_IMPL uchar* 1849cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type ) 1850{ 1851 uchar* ptr = 0; 1852 if( CV_IS_MATND( arr )) 1853 { 1854 CvMatND* mat = (CvMatND*)arr; 1855 1856 if( mat->dims != 3 || 1857 (unsigned)z >= (unsigned)(mat->dim[0].size) || 1858 (unsigned)y >= (unsigned)(mat->dim[1].size) || 1859 (unsigned)x >= (unsigned)(mat->dim[2].size) ) 1860 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1861 1862 ptr = mat->data.ptr + (size_t)z*mat->dim[0].step + 1863 (size_t)y*mat->dim[1].step + x*mat->dim[2].step; 1864 1865 if( _type ) 1866 *_type = CV_MAT_TYPE(mat->type); 1867 } 1868 else if( CV_IS_SPARSE_MAT( arr )) 1869 { 1870 int idx[] = { z, y, x }; 1871 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 ); 1872 } 1873 else 1874 { 1875 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1876 } 1877 1878 return ptr; 1879} 1880 1881 1882// Returns pointer to specified element of n-d array 1883CV_IMPL uchar* 1884cvPtrND( const CvArr* arr, const int* idx, int* _type, 1885 int create_node, unsigned* precalc_hashval ) 1886{ 1887 uchar* ptr = 0; 1888 if( !idx ) 1889 CV_Error( CV_StsNullPtr, "NULL pointer to indices" ); 1890 1891 if( CV_IS_SPARSE_MAT( arr )) 1892 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, 1893 _type, create_node, precalc_hashval ); 1894 else if( CV_IS_MATND( arr )) 1895 { 1896 CvMatND* mat = (CvMatND*)arr; 1897 int i; 1898 ptr = mat->data.ptr; 1899 1900 for( i = 0; i < mat->dims; i++ ) 1901 { 1902 if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) ) 1903 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1904 ptr += (size_t)idx[i]*mat->dim[i].step; 1905 } 1906 1907 if( _type ) 1908 *_type = CV_MAT_TYPE(mat->type); 1909 } 1910 else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) ) 1911 ptr = cvPtr2D( arr, idx[0], idx[1], _type ); 1912 else 1913 CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" ); 1914 1915 return ptr; 1916} 1917 1918 1919// Returns specifed element of n-D array given linear index 1920CV_IMPL CvScalar 1921cvGet1D( const CvArr* arr, int idx ) 1922{ 1923 CvScalar scalar(0); 1924 int type = 0; 1925 uchar* ptr; 1926 1927 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 1928 { 1929 CvMat* mat = (CvMat*)arr; 1930 1931 type = CV_MAT_TYPE(mat->type); 1932 int pix_size = CV_ELEM_SIZE(type); 1933 1934 // the first part is mul-free sufficient check 1935 // that the index is within the matrix 1936 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 1937 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 1938 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1939 1940 ptr = mat->data.ptr + (size_t)idx*pix_size; 1941 } 1942 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 1943 ptr = cvPtr1D( arr, idx, &type ); 1944 else 1945 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 ); 1946 1947 if( ptr ) 1948 cvRawDataToScalar( ptr, type, &scalar ); 1949 1950 return scalar; 1951} 1952 1953 1954// Returns specifed element of 2D array 1955CV_IMPL CvScalar 1956cvGet2D( const CvArr* arr, int y, int x ) 1957{ 1958 CvScalar scalar(0); 1959 int type = 0; 1960 uchar* ptr; 1961 1962 if( CV_IS_MAT( arr )) 1963 { 1964 CvMat* mat = (CvMat*)arr; 1965 1966 if( (unsigned)y >= (unsigned)(mat->rows) || 1967 (unsigned)x >= (unsigned)(mat->cols) ) 1968 CV_Error( CV_StsOutOfRange, "index is out of range" ); 1969 1970 type = CV_MAT_TYPE(mat->type); 1971 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 1972 } 1973 else if( !CV_IS_SPARSE_MAT( arr )) 1974 ptr = cvPtr2D( arr, y, x, &type ); 1975 else 1976 { 1977 int idx[] = { y, x }; 1978 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 1979 } 1980 1981 if( ptr ) 1982 cvRawDataToScalar( ptr, type, &scalar ); 1983 1984 return scalar; 1985} 1986 1987 1988// Returns specifed element of 3D array 1989CV_IMPL CvScalar 1990cvGet3D( const CvArr* arr, int z, int y, int x ) 1991{ 1992 CvScalar scalar(0); 1993 int type = 0; 1994 uchar* ptr; 1995 1996 if( !CV_IS_SPARSE_MAT( arr )) 1997 ptr = cvPtr3D( arr, z, y, x, &type ); 1998 else 1999 { 2000 int idx[] = { z, y, x }; 2001 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 2002 } 2003 2004 if( ptr ) 2005 cvRawDataToScalar( ptr, type, &scalar ); 2006 return scalar; 2007} 2008 2009 2010// Returns specifed element of nD array 2011CV_IMPL CvScalar 2012cvGetND( const CvArr* arr, const int* idx ) 2013{ 2014 CvScalar scalar(0); 2015 int type = 0; 2016 uchar* ptr; 2017 2018 if( !CV_IS_SPARSE_MAT( arr )) 2019 ptr = cvPtrND( arr, idx, &type ); 2020 else 2021 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 2022 2023 if( ptr ) 2024 cvRawDataToScalar( ptr, type, &scalar ); 2025 2026 return scalar; 2027} 2028 2029 2030// Returns specifed element of n-D array given linear index 2031CV_IMPL double 2032cvGetReal1D( const CvArr* arr, int idx ) 2033{ 2034 double value = 0; 2035 int type = 0; 2036 uchar* ptr; 2037 2038 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 2039 { 2040 CvMat* mat = (CvMat*)arr; 2041 2042 type = CV_MAT_TYPE(mat->type); 2043 int pix_size = CV_ELEM_SIZE(type); 2044 2045 // the first part is mul-free sufficient check 2046 // that the index is within the matrix 2047 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 2048 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 2049 CV_Error( CV_StsOutOfRange, "index is out of range" ); 2050 2051 ptr = mat->data.ptr + (size_t)idx*pix_size; 2052 } 2053 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 2054 ptr = cvPtr1D( arr, idx, &type ); 2055 else 2056 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 ); 2057 2058 if( ptr ) 2059 { 2060 if( CV_MAT_CN( type ) > 1 ) 2061 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 2062 2063 value = icvGetReal( ptr, type ); 2064 } 2065 return value; 2066} 2067 2068 2069// Returns specifed element of 2D array 2070CV_IMPL double 2071cvGetReal2D( const CvArr* arr, int y, int x ) 2072{ 2073 double value = 0; 2074 int type = 0; 2075 uchar* ptr; 2076 2077 if( CV_IS_MAT( arr )) 2078 { 2079 CvMat* mat = (CvMat*)arr; 2080 2081 if( (unsigned)y >= (unsigned)(mat->rows) || 2082 (unsigned)x >= (unsigned)(mat->cols) ) 2083 CV_Error( CV_StsOutOfRange, "index is out of range" ); 2084 2085 type = CV_MAT_TYPE(mat->type); 2086 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 2087 } 2088 else if( !CV_IS_SPARSE_MAT( arr )) 2089 ptr = cvPtr2D( arr, y, x, &type ); 2090 else 2091 { 2092 int idx[] = { y, x }; 2093 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 2094 } 2095 2096 if( ptr ) 2097 { 2098 if( CV_MAT_CN( type ) > 1 ) 2099 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 2100 2101 value = icvGetReal( ptr, type ); 2102 } 2103 2104 return value; 2105} 2106 2107 2108// Returns specifed element of 3D array 2109CV_IMPL double 2110cvGetReal3D( const CvArr* arr, int z, int y, int x ) 2111{ 2112 double value = 0; 2113 int type = 0; 2114 uchar* ptr; 2115 2116 if( !CV_IS_SPARSE_MAT( arr )) 2117 ptr = cvPtr3D( arr, z, y, x, &type ); 2118 else 2119 { 2120 int idx[] = { z, y, x }; 2121 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 2122 } 2123 2124 if( ptr ) 2125 { 2126 if( CV_MAT_CN( type ) > 1 ) 2127 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 2128 2129 value = icvGetReal( ptr, type ); 2130 } 2131 2132 return value; 2133} 2134 2135 2136// Returns specifed element of nD array 2137CV_IMPL double 2138cvGetRealND( const CvArr* arr, const int* idx ) 2139{ 2140 double value = 0; 2141 int type = 0; 2142 uchar* ptr; 2143 2144 if( !CV_IS_SPARSE_MAT( arr )) 2145 ptr = cvPtrND( arr, idx, &type ); 2146 else 2147 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 ); 2148 2149 if( ptr ) 2150 { 2151 if( CV_MAT_CN( type ) > 1 ) 2152 CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" ); 2153 2154 value = icvGetReal( ptr, type ); 2155 } 2156 2157 return value; 2158} 2159 2160 2161// Assigns new value to specifed element of nD array given linear index 2162CV_IMPL void 2163cvSet1D( CvArr* arr, int idx, CvScalar scalar ) 2164{ 2165 int type = 0; 2166 uchar* ptr; 2167 2168 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 2169 { 2170 CvMat* mat = (CvMat*)arr; 2171 2172 type = CV_MAT_TYPE(mat->type); 2173 int pix_size = CV_ELEM_SIZE(type); 2174 2175 // the first part is mul-free sufficient check 2176 // that the index is within the matrix 2177 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 2178 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 2179 CV_Error( CV_StsOutOfRange, "index is out of range" ); 2180 2181 ptr = mat->data.ptr + (size_t)idx*pix_size; 2182 } 2183 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 2184 ptr = cvPtr1D( arr, idx, &type ); 2185 else 2186 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); 2187 2188 cvScalarToRawData( &scalar, ptr, type ); 2189} 2190 2191 2192// Assigns new value to specifed element of 2D array 2193CV_IMPL void 2194cvSet2D( CvArr* arr, int y, int x, CvScalar scalar ) 2195{ 2196 int type = 0; 2197 uchar* ptr; 2198 2199 if( CV_IS_MAT( arr )) 2200 { 2201 CvMat* mat = (CvMat*)arr; 2202 2203 if( (unsigned)y >= (unsigned)(mat->rows) || 2204 (unsigned)x >= (unsigned)(mat->cols) ) 2205 CV_Error( CV_StsOutOfRange, "index is out of range" ); 2206 2207 type = CV_MAT_TYPE(mat->type); 2208 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 2209 } 2210 else if( !CV_IS_SPARSE_MAT( arr )) 2211 ptr = cvPtr2D( arr, y, x, &type ); 2212 else 2213 { 2214 int idx[] = { y, x }; 2215 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 2216 } 2217 cvScalarToRawData( &scalar, ptr, type ); 2218} 2219 2220 2221// Assigns new value to specifed element of 3D array 2222CV_IMPL void 2223cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar ) 2224{ 2225 int type = 0; 2226 uchar* ptr; 2227 2228 if( !CV_IS_SPARSE_MAT( arr )) 2229 ptr = cvPtr3D( arr, z, y, x, &type ); 2230 else 2231 { 2232 int idx[] = { z, y, x }; 2233 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 2234 } 2235 cvScalarToRawData( &scalar, ptr, type ); 2236} 2237 2238 2239// Assigns new value to specifed element of nD array 2240CV_IMPL void 2241cvSetND( CvArr* arr, const int* idx, CvScalar scalar ) 2242{ 2243 int type = 0; 2244 uchar* ptr; 2245 2246 if( !CV_IS_SPARSE_MAT( arr )) 2247 ptr = cvPtrND( arr, idx, &type ); 2248 else 2249 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 2250 cvScalarToRawData( &scalar, ptr, type ); 2251} 2252 2253 2254CV_IMPL void 2255cvSetReal1D( CvArr* arr, int idx, double value ) 2256{ 2257 int type = 0; 2258 uchar* ptr; 2259 2260 if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type )) 2261 { 2262 CvMat* mat = (CvMat*)arr; 2263 2264 type = CV_MAT_TYPE(mat->type); 2265 int pix_size = CV_ELEM_SIZE(type); 2266 2267 // the first part is mul-free sufficient check 2268 // that the index is within the matrix 2269 if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) && 2270 (unsigned)idx >= (unsigned)(mat->rows*mat->cols)) 2271 CV_Error( CV_StsOutOfRange, "index is out of range" ); 2272 2273 ptr = mat->data.ptr + (size_t)idx*pix_size; 2274 } 2275 else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 ) 2276 ptr = cvPtr1D( arr, idx, &type ); 2277 else 2278 ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 ); 2279 2280 if( CV_MAT_CN( type ) > 1 ) 2281 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 2282 2283 if( ptr ) 2284 icvSetReal( value, ptr, type ); 2285} 2286 2287 2288CV_IMPL void 2289cvSetReal2D( CvArr* arr, int y, int x, double value ) 2290{ 2291 int type = 0; 2292 uchar* ptr; 2293 2294 if( CV_IS_MAT( arr )) 2295 { 2296 CvMat* mat = (CvMat*)arr; 2297 2298 if( (unsigned)y >= (unsigned)(mat->rows) || 2299 (unsigned)x >= (unsigned)(mat->cols) ) 2300 CV_Error( CV_StsOutOfRange, "index is out of range" ); 2301 2302 type = CV_MAT_TYPE(mat->type); 2303 ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type); 2304 } 2305 else if( !CV_IS_SPARSE_MAT( arr )) 2306 { 2307 ptr = cvPtr2D( arr, y, x, &type ); 2308 } 2309 else 2310 { 2311 int idx[] = { y, x }; 2312 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 2313 } 2314 if( CV_MAT_CN( type ) > 1 ) 2315 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 2316 2317 if( ptr ) 2318 icvSetReal( value, ptr, type ); 2319} 2320 2321 2322CV_IMPL void 2323cvSetReal3D( CvArr* arr, int z, int y, int x, double value ) 2324{ 2325 int type = 0; 2326 uchar* ptr; 2327 2328 if( !CV_IS_SPARSE_MAT( arr )) 2329 ptr = cvPtr3D( arr, z, y, x, &type ); 2330 else 2331 { 2332 int idx[] = { z, y, x }; 2333 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 2334 } 2335 if( CV_MAT_CN( type ) > 1 ) 2336 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 2337 2338 if( ptr ) 2339 icvSetReal( value, ptr, type ); 2340} 2341 2342 2343CV_IMPL void 2344cvSetRealND( CvArr* arr, const int* idx, double value ) 2345{ 2346 int type = 0; 2347 uchar* ptr; 2348 2349 if( !CV_IS_SPARSE_MAT( arr )) 2350 ptr = cvPtrND( arr, idx, &type ); 2351 else 2352 ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 ); 2353 2354 if( CV_MAT_CN( type ) > 1 ) 2355 CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" ); 2356 2357 if( ptr ) 2358 icvSetReal( value, ptr, type ); 2359} 2360 2361 2362CV_IMPL void 2363cvClearND( CvArr* arr, const int* idx ) 2364{ 2365 if( !CV_IS_SPARSE_MAT( arr )) 2366 { 2367 int type; 2368 uchar* ptr; 2369 ptr = cvPtrND( arr, idx, &type ); 2370 if( ptr ) 2371 memset( ptr, 0, CV_ELEM_SIZE(type) ); 2372 } 2373 else 2374 icvDeleteNode( (CvSparseMat*)arr, idx, 0 ); 2375} 2376 2377 2378/****************************************************************************************\ 2379* Conversion to CvMat or IplImage * 2380\****************************************************************************************/ 2381 2382// convert array (CvMat or IplImage) to CvMat 2383CV_IMPL CvMat* 2384cvGetMat( const CvArr* array, CvMat* mat, 2385 int* pCOI, int allowND ) 2386{ 2387 CvMat* result = 0; 2388 CvMat* src = (CvMat*)array; 2389 int coi = 0; 2390 2391 if( !mat || !src ) 2392 CV_Error( CV_StsNullPtr, "NULL array pointer is passed" ); 2393 2394 if( CV_IS_MAT_HDR(src)) 2395 { 2396 if( !src->data.ptr ) 2397 CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" ); 2398 2399 result = (CvMat*)src; 2400 } 2401 else if( CV_IS_IMAGE_HDR(src) ) 2402 { 2403 const IplImage* img = (const IplImage*)src; 2404 int depth, order; 2405 2406 if( img->imageData == 0 ) 2407 CV_Error( CV_StsNullPtr, "The image has NULL data pointer" ); 2408 2409 depth = IPL2CV_DEPTH( img->depth ); 2410 if( depth < 0 ) 2411 CV_Error( CV_BadDepth, "" ); 2412 2413 order = img->dataOrder & (img->nChannels > 1 ? -1 : 0); 2414 2415 if( img->roi ) 2416 { 2417 if( order == IPL_DATA_ORDER_PLANE ) 2418 { 2419 int type = depth; 2420 2421 if( img->roi->coi == 0 ) 2422 CV_Error( CV_StsBadFlag, 2423 "Images with planar data layout should be used with COI selected" ); 2424 2425 cvInitMatHeader( mat, img->roi->height, 2426 img->roi->width, type, 2427 img->imageData + (img->roi->coi-1)*img->imageSize + 2428 img->roi->yOffset*img->widthStep + 2429 img->roi->xOffset*CV_ELEM_SIZE(type), 2430 img->widthStep ); 2431 } 2432 else /* pixel order */ 2433 { 2434 int type = CV_MAKETYPE( depth, img->nChannels ); 2435 coi = img->roi->coi; 2436 2437 if( img->nChannels > CV_CN_MAX ) 2438 CV_Error( CV_BadNumChannels, 2439 "The image is interleaved and has over CV_CN_MAX channels" ); 2440 2441 cvInitMatHeader( mat, img->roi->height, img->roi->width, 2442 type, img->imageData + 2443 img->roi->yOffset*img->widthStep + 2444 img->roi->xOffset*CV_ELEM_SIZE(type), 2445 img->widthStep ); 2446 } 2447 } 2448 else 2449 { 2450 int type = CV_MAKETYPE( depth, img->nChannels ); 2451 2452 if( order != IPL_DATA_ORDER_PIXEL ) 2453 CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" ); 2454 2455 cvInitMatHeader( mat, img->height, img->width, type, 2456 img->imageData, img->widthStep ); 2457 } 2458 2459 result = mat; 2460 } 2461 else if( allowND && CV_IS_MATND_HDR(src) ) 2462 { 2463 CvMatND* matnd = (CvMatND*)src; 2464 int size1 = matnd->dim[0].size, size2 = 1; 2465 2466 if( !src->data.ptr ) 2467 CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" ); 2468 2469 if( !CV_IS_MAT_CONT( matnd->type )) 2470 CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" ); 2471 2472 if( matnd->dims > 2 ) 2473 { 2474 int i; 2475 for( i = 1; i < matnd->dims; i++ ) 2476 size2 *= matnd->dim[i].size; 2477 } 2478 else 2479 size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size; 2480 2481 mat->refcount = 0; 2482 mat->hdr_refcount = 0; 2483 mat->data.ptr = matnd->data.ptr; 2484 mat->rows = size1; 2485 mat->cols = size2; 2486 mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG; 2487 mat->step = size2*CV_ELEM_SIZE(matnd->type); 2488 mat->step &= size1 > 1 ? -1 : 0; 2489 2490 icvCheckHuge( mat ); 2491 result = mat; 2492 } 2493 else 2494 CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" ); 2495 2496 if( pCOI ) 2497 *pCOI = coi; 2498 2499 return result; 2500} 2501 2502 2503CV_IMPL CvArr* 2504cvReshapeMatND( const CvArr* arr, 2505 int sizeof_header, CvArr* _header, 2506 int new_cn, int new_dims, int* new_sizes ) 2507{ 2508 CvArr* result = 0; 2509 int dims, coi = 0; 2510 2511 if( !arr || !_header ) 2512 CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" ); 2513 2514 if( new_cn == 0 && new_dims == 0 ) 2515 CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" ); 2516 2517 dims = cvGetDims( arr ); 2518 2519 if( new_dims == 0 ) 2520 { 2521 new_sizes = 0; 2522 new_dims = dims; 2523 } 2524 else if( new_dims == 1 ) 2525 { 2526 new_sizes = 0; 2527 } 2528 else 2529 { 2530 if( new_dims <= 0 || new_dims > CV_MAX_DIM ) 2531 CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" ); 2532 if( !new_sizes ) 2533 CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" ); 2534 } 2535 2536 if( new_dims <= 2 ) 2537 { 2538 CvMat* mat = (CvMat*)arr; 2539 CvMat header; 2540 int* refcount = 0; 2541 int hdr_refcount = 0; 2542 int total_width, new_rows, cn; 2543 2544 if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND) ) 2545 CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" ); 2546 2547 if( mat == (CvMat*)_header ) 2548 { 2549 refcount = mat->refcount; 2550 hdr_refcount = mat->hdr_refcount; 2551 } 2552 2553 if( !CV_IS_MAT( mat )) 2554 mat = cvGetMat( mat, &header, &coi, 1 ); 2555 2556 cn = CV_MAT_CN( mat->type ); 2557 total_width = mat->cols * cn; 2558 2559 if( new_cn == 0 ) 2560 new_cn = cn; 2561 2562 if( new_sizes ) 2563 new_rows = new_sizes[0]; 2564 else if( new_dims == 1 ) 2565 new_rows = total_width*mat->rows/new_cn; 2566 else 2567 { 2568 new_rows = mat->rows; 2569 if( new_cn > total_width ) 2570 new_rows = mat->rows * total_width / new_cn; 2571 } 2572 2573 if( new_rows != mat->rows ) 2574 { 2575 int total_size = total_width * mat->rows; 2576 2577 if( !CV_IS_MAT_CONT( mat->type )) 2578 CV_Error( CV_BadStep, 2579 "The matrix is not continuous so the number of rows can not be changed" ); 2580 2581 total_width = total_size / new_rows; 2582 2583 if( total_width * new_rows != total_size ) 2584 CV_Error( CV_StsBadArg, "The total number of matrix elements " 2585 "is not divisible by the new number of rows" ); 2586 } 2587 2588 header.rows = new_rows; 2589 header.cols = total_width / new_cn; 2590 2591 if( header.cols * new_cn != total_width || 2592 (new_sizes && header.cols != new_sizes[1]) ) 2593 CV_Error( CV_StsBadArg, "The total matrix width is not " 2594 "divisible by the new number of columns" ); 2595 2596 header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); 2597 header.step = header.cols * CV_ELEM_SIZE(mat->type); 2598 header.step &= new_rows > 1 ? -1 : 0; 2599 header.refcount = refcount; 2600 header.hdr_refcount = hdr_refcount; 2601 2602 if( sizeof_header == sizeof(CvMat) ) 2603 *(CvMat*)_header = header; 2604 else 2605 { 2606 CvMatND* __header = (CvMatND*)_header; 2607 cvGetMatND(&header, __header, 0); 2608 if( new_dims > 0 ) 2609 __header->dims = new_dims; 2610 } 2611 } 2612 else 2613 { 2614 CvMatND* header = (CvMatND*)_header; 2615 2616 if( sizeof_header != sizeof(CvMatND)) 2617 CV_Error( CV_StsBadSize, "The output header should be CvMatND" ); 2618 2619 if( !new_sizes ) 2620 { 2621 if( !CV_IS_MATND( arr )) 2622 CV_Error( CV_StsBadArg, "The input array must be CvMatND" ); 2623 2624 { 2625 CvMatND* mat = (CvMatND*)arr; 2626 assert( new_cn > 0 ); 2627 int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type); 2628 int new_size = last_dim_size/new_cn; 2629 2630 if( new_size*new_cn != last_dim_size ) 2631 CV_Error( CV_StsBadArg, 2632 "The last dimension full size is not divisible by new number of channels"); 2633 2634 if( mat != header ) 2635 { 2636 memcpy( header, mat, sizeof(*header)); 2637 header->refcount = 0; 2638 header->hdr_refcount = 0; 2639 } 2640 2641 header->dim[header->dims-1].size = new_size; 2642 header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn); 2643 } 2644 } 2645 else 2646 { 2647 CvMatND stub; 2648 CvMatND* mat = (CvMatND*)arr; 2649 int i, size1, size2; 2650 int step; 2651 2652 if( new_cn != 0 ) 2653 CV_Error( CV_StsBadArg, 2654 "Simultaneous change of shape and number of channels is not supported. " 2655 "Do it by 2 separate calls" ); 2656 2657 if( !CV_IS_MATND( mat )) 2658 { 2659 cvGetMatND( mat, &stub, &coi ); 2660 mat = &stub; 2661 } 2662 2663 if( CV_IS_MAT_CONT( mat->type )) 2664 CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" ); 2665 2666 size1 = mat->dim[0].size; 2667 for( i = 1; i < dims; i++ ) 2668 size1 *= mat->dim[i].size; 2669 2670 size2 = 1; 2671 for( i = 0; i < new_dims; i++ ) 2672 { 2673 if( new_sizes[i] <= 0 ) 2674 CV_Error( CV_StsBadSize, 2675 "One of new dimension sizes is non-positive" ); 2676 size2 *= new_sizes[i]; 2677 } 2678 2679 if( size1 != size2 ) 2680 CV_Error( CV_StsBadSize, 2681 "Number of elements in the original and reshaped array is different" ); 2682 2683 if( header != mat ) 2684 { 2685 header->refcount = 0; 2686 header->hdr_refcount = 0; 2687 } 2688 2689 header->dims = new_dims; 2690 header->type = mat->type; 2691 header->data.ptr = mat->data.ptr; 2692 step = CV_ELEM_SIZE(header->type); 2693 2694 for( i = new_dims - 1; i >= 0; i-- ) 2695 { 2696 header->dim[i].size = new_sizes[i]; 2697 header->dim[i].step = step; 2698 step *= new_sizes[i]; 2699 } 2700 } 2701 } 2702 2703 if( coi ) 2704 CV_Error( CV_BadCOI, "COI is not supported by this operation" ); 2705 2706 result = _header; 2707 return result; 2708} 2709 2710 2711CV_IMPL CvMat* 2712cvReshape( const CvArr* array, CvMat* header, 2713 int new_cn, int new_rows ) 2714{ 2715 CvMat* result = 0; 2716 CvMat *mat = (CvMat*)array; 2717 int total_width, new_width; 2718 2719 if( !header ) 2720 CV_Error( CV_StsNullPtr, "" ); 2721 2722 if( !CV_IS_MAT( mat )) 2723 { 2724 int coi = 0; 2725 mat = cvGetMat( mat, header, &coi, 1 ); 2726 if( coi ) 2727 CV_Error( CV_BadCOI, "COI is not supported" ); 2728 } 2729 2730 if( new_cn == 0 ) 2731 new_cn = CV_MAT_CN(mat->type); 2732 else if( (unsigned)(new_cn - 1) > 3 ) 2733 CV_Error( CV_BadNumChannels, "" ); 2734 2735 if( mat != header ) 2736 { 2737 int hdr_refcount = header->hdr_refcount; 2738 *header = *mat; 2739 header->refcount = 0; 2740 header->hdr_refcount = hdr_refcount; 2741 } 2742 2743 total_width = mat->cols * CV_MAT_CN( mat->type ); 2744 2745 if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 ) 2746 new_rows = mat->rows * total_width / new_cn; 2747 2748 if( new_rows == 0 || new_rows == mat->rows ) 2749 { 2750 header->rows = mat->rows; 2751 header->step = mat->step; 2752 } 2753 else 2754 { 2755 int total_size = total_width * mat->rows; 2756 if( !CV_IS_MAT_CONT( mat->type )) 2757 CV_Error( CV_BadStep, 2758 "The matrix is not continuous, thus its number of rows can not be changed" ); 2759 2760 if( (unsigned)new_rows > (unsigned)total_size ) 2761 CV_Error( CV_StsOutOfRange, "Bad new number of rows" ); 2762 2763 total_width = total_size / new_rows; 2764 2765 if( total_width * new_rows != total_size ) 2766 CV_Error( CV_StsBadArg, "The total number of matrix elements " 2767 "is not divisible by the new number of rows" ); 2768 2769 header->rows = new_rows; 2770 header->step = total_width * CV_ELEM_SIZE1(mat->type); 2771 } 2772 2773 new_width = total_width / new_cn; 2774 2775 if( new_width * new_cn != total_width ) 2776 CV_Error( CV_BadNumChannels, 2777 "The total width is not divisible by the new number of channels" ); 2778 2779 header->cols = new_width; 2780 header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn); 2781 2782 result = header; 2783 return result; 2784} 2785 2786 2787// convert array (CvMat or IplImage) to IplImage 2788CV_IMPL IplImage* 2789cvGetImage( const CvArr* array, IplImage* img ) 2790{ 2791 IplImage* result = 0; 2792 const IplImage* src = (const IplImage*)array; 2793 2794 if( !img ) 2795 CV_Error( CV_StsNullPtr, "" ); 2796 2797 if( !CV_IS_IMAGE_HDR(src) ) 2798 { 2799 const CvMat* mat = (const CvMat*)src; 2800 2801 if( !CV_IS_MAT_HDR(mat)) 2802 CV_Error( CV_StsBadFlag, "" ); 2803 2804 if( mat->data.ptr == 0 ) 2805 CV_Error( CV_StsNullPtr, "" ); 2806 2807 int depth = cvIplDepth(mat->type); 2808 2809 cvInitImageHeader( img, cvSize(mat->cols, mat->rows), 2810 depth, CV_MAT_CN(mat->type) ); 2811 cvSetData( img, mat->data.ptr, mat->step ); 2812 2813 result = img; 2814 } 2815 else 2816 { 2817 result = (IplImage*)src; 2818 } 2819 2820 return result; 2821} 2822 2823 2824/****************************************************************************************\ 2825* IplImage-specific functions * 2826\****************************************************************************************/ 2827 2828static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height ) 2829{ 2830 IplROI *roi = 0; 2831 if( !CvIPL.createROI ) 2832 { 2833 roi = (IplROI*)cvAlloc( sizeof(*roi)); 2834 2835 roi->coi = coi; 2836 roi->xOffset = xOffset; 2837 roi->yOffset = yOffset; 2838 roi->width = width; 2839 roi->height = height; 2840 } 2841 else 2842 { 2843 roi = CvIPL.createROI( coi, xOffset, yOffset, width, height ); 2844 } 2845 2846 return roi; 2847} 2848 2849static void 2850icvGetColorModel( int nchannels, const char** colorModel, const char** channelSeq ) 2851{ 2852 static const char* tab[][2] = 2853 { 2854 {"GRAY", "GRAY"}, 2855 {"",""}, 2856 {"RGB","BGR"}, 2857 {"RGB","BGRA"} 2858 }; 2859 2860 nchannels--; 2861 *colorModel = *channelSeq = ""; 2862 2863 if( (unsigned)nchannels <= 3 ) 2864 { 2865 *colorModel = tab[nchannels][0]; 2866 *channelSeq = tab[nchannels][1]; 2867 } 2868} 2869 2870 2871// create IplImage header 2872CV_IMPL IplImage * 2873cvCreateImageHeader( CvSize size, int depth, int channels ) 2874{ 2875 IplImage *img = 0; 2876 2877 if( !CvIPL.createHeader ) 2878 { 2879 img = (IplImage *)cvAlloc( sizeof( *img )); 2880 cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL, 2881 CV_DEFAULT_IMAGE_ROW_ALIGN ); 2882 } 2883 else 2884 { 2885 const char *colorModel, *channelSeq; 2886 2887 icvGetColorModel( channels, &colorModel, &channelSeq ); 2888 2889 img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq, 2890 IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, 2891 CV_DEFAULT_IMAGE_ROW_ALIGN, 2892 size.width, size.height, 0, 0, 0, 0 ); 2893 } 2894 2895 return img; 2896} 2897 2898 2899// create IplImage header and allocate underlying data 2900CV_IMPL IplImage * 2901cvCreateImage( CvSize size, int depth, int channels ) 2902{ 2903 IplImage *img = cvCreateImageHeader( size, depth, channels ); 2904 assert( img ); 2905 cvCreateData( img ); 2906 2907 return img; 2908} 2909 2910 2911// initialize IplImage header, allocated by the user 2912CV_IMPL IplImage* 2913cvInitImageHeader( IplImage * image, CvSize size, int depth, 2914 int channels, int origin, int align ) 2915{ 2916 const char *colorModel, *channelSeq; 2917 2918 if( !image ) 2919 CV_Error( CV_HeaderIsNull, "null pointer to header" ); 2920 2921 memset( image, 0, sizeof( *image )); 2922 image->nSize = sizeof( *image ); 2923 2924 icvGetColorModel( channels, &colorModel, &channelSeq ); 2925 strncpy( image->colorModel, colorModel, 4 ); 2926 strncpy( image->channelSeq, channelSeq, 4 ); 2927 2928 if( size.width < 0 || size.height < 0 ) 2929 CV_Error( CV_BadROISize, "Bad input roi" ); 2930 2931 if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U && 2932 depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U && 2933 depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S && 2934 depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) || 2935 channels < 0 ) 2936 CV_Error( CV_BadDepth, "Unsupported format" ); 2937 if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL ) 2938 CV_Error( CV_BadOrigin, "Bad input origin" ); 2939 2940 if( align != 4 && align != 8 ) 2941 CV_Error( CV_BadAlign, "Bad input align" ); 2942 2943 image->width = size.width; 2944 image->height = size.height; 2945 2946 if( image->roi ) 2947 { 2948 image->roi->coi = 0; 2949 image->roi->xOffset = image->roi->yOffset = 0; 2950 image->roi->width = size.width; 2951 image->roi->height = size.height; 2952 } 2953 2954 image->nChannels = MAX( channels, 1 ); 2955 image->depth = depth; 2956 image->align = align; 2957 image->widthStep = (((image->width * image->nChannels * 2958 (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1)); 2959 image->origin = origin; 2960 image->imageSize = image->widthStep * image->height; 2961 2962 return image; 2963} 2964 2965 2966CV_IMPL void 2967cvReleaseImageHeader( IplImage** image ) 2968{ 2969 if( !image ) 2970 CV_Error( CV_StsNullPtr, "" ); 2971 2972 if( *image ) 2973 { 2974 IplImage* img = *image; 2975 *image = 0; 2976 2977 if( !CvIPL.deallocate ) 2978 { 2979 cvFree( &img->roi ); 2980 cvFree( &img ); 2981 } 2982 else 2983 { 2984 CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI ); 2985 } 2986 } 2987} 2988 2989 2990CV_IMPL void 2991cvReleaseImage( IplImage ** image ) 2992{ 2993 if( !image ) 2994 CV_Error( CV_StsNullPtr, "" ); 2995 2996 if( *image ) 2997 { 2998 IplImage* img = *image; 2999 *image = 0; 3000 3001 cvReleaseData( img ); 3002 cvReleaseImageHeader( &img ); 3003 } 3004} 3005 3006 3007CV_IMPL void 3008cvSetImageROI( IplImage* image, CvRect rect ) 3009{ 3010 if( !image ) 3011 CV_Error( CV_HeaderIsNull, "" ); 3012 3013 // allow zero ROI width or height 3014 CV_Assert( rect.width >= 0 && rect.height >= 0 && 3015 rect.x < image->width && rect.y < image->height && 3016 rect.x + rect.width >= (int)(rect.width > 0) && 3017 rect.y + rect.height >= (int)(rect.height > 0) ); 3018 3019 rect.width += rect.x; 3020 rect.height += rect.y; 3021 3022 rect.x = std::max(rect.x, 0); 3023 rect.y = std::max(rect.y, 0); 3024 rect.width = std::min(rect.width, image->width); 3025 rect.height = std::min(rect.height, image->height); 3026 3027 rect.width -= rect.x; 3028 rect.height -= rect.y; 3029 3030 if( image->roi ) 3031 { 3032 image->roi->xOffset = rect.x; 3033 image->roi->yOffset = rect.y; 3034 image->roi->width = rect.width; 3035 image->roi->height = rect.height; 3036 } 3037 else 3038 image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height ); 3039} 3040 3041 3042CV_IMPL void 3043cvResetImageROI( IplImage* image ) 3044{ 3045 if( !image ) 3046 CV_Error( CV_HeaderIsNull, "" ); 3047 3048 if( image->roi ) 3049 { 3050 if( !CvIPL.deallocate ) 3051 { 3052 cvFree( &image->roi ); 3053 } 3054 else 3055 { 3056 CvIPL.deallocate( image, IPL_IMAGE_ROI ); 3057 image->roi = 0; 3058 } 3059 } 3060} 3061 3062 3063CV_IMPL CvRect 3064cvGetImageROI( const IplImage* img ) 3065{ 3066 CvRect rect; 3067 if( !img ) 3068 CV_Error( CV_StsNullPtr, "Null pointer to image" ); 3069 3070 if( img->roi ) 3071 rect = cvRect( img->roi->xOffset, img->roi->yOffset, 3072 img->roi->width, img->roi->height ); 3073 else 3074 rect = cvRect( 0, 0, img->width, img->height ); 3075 3076 return rect; 3077} 3078 3079 3080CV_IMPL void 3081cvSetImageCOI( IplImage* image, int coi ) 3082{ 3083 if( !image ) 3084 CV_Error( CV_HeaderIsNull, "" ); 3085 3086 if( (unsigned)coi > (unsigned)(image->nChannels) ) 3087 CV_Error( CV_BadCOI, "" ); 3088 3089 if( image->roi || coi != 0 ) 3090 { 3091 if( image->roi ) 3092 { 3093 image->roi->coi = coi; 3094 } 3095 else 3096 { 3097 image->roi = icvCreateROI( coi, 0, 0, image->width, image->height ); 3098 } 3099 } 3100} 3101 3102 3103CV_IMPL int 3104cvGetImageCOI( const IplImage* image ) 3105{ 3106 if( !image ) 3107 CV_Error( CV_HeaderIsNull, "" ); 3108 3109 return image->roi ? image->roi->coi : 0; 3110} 3111 3112 3113CV_IMPL IplImage* 3114cvCloneImage( const IplImage* src ) 3115{ 3116 IplImage* dst = 0; 3117 3118 if( !CV_IS_IMAGE_HDR( src )) 3119 CV_Error( CV_StsBadArg, "Bad image header" ); 3120 3121 if( !CvIPL.cloneImage ) 3122 { 3123 dst = (IplImage*)cvAlloc( sizeof(*dst)); 3124 3125 memcpy( dst, src, sizeof(*src)); 3126 dst->imageData = dst->imageDataOrigin = 0; 3127 dst->roi = 0; 3128 3129 if( src->roi ) 3130 { 3131 dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset, 3132 src->roi->yOffset, src->roi->width, src->roi->height ); 3133 } 3134 3135 if( src->imageData ) 3136 { 3137 int size = src->imageSize; 3138 cvCreateData( dst ); 3139 memcpy( dst->imageData, src->imageData, size ); 3140 } 3141 } 3142 else 3143 dst = CvIPL.cloneImage( src ); 3144 3145 return dst; 3146} 3147 3148 3149/****************************************************************************************\ 3150* Additional operations on CvTermCriteria * 3151\****************************************************************************************/ 3152 3153CV_IMPL CvTermCriteria 3154cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, 3155 int default_max_iters ) 3156{ 3157 CvTermCriteria crit; 3158 3159 crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS; 3160 crit.max_iter = default_max_iters; 3161 crit.epsilon = (float)default_eps; 3162 3163 if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 ) 3164 CV_Error( CV_StsBadArg, 3165 "Unknown type of term criteria" ); 3166 3167 if( (criteria.type & CV_TERMCRIT_ITER) != 0 ) 3168 { 3169 if( criteria.max_iter <= 0 ) 3170 CV_Error( CV_StsBadArg, 3171 "Iterations flag is set and maximum number of iterations is <= 0" ); 3172 crit.max_iter = criteria.max_iter; 3173 } 3174 3175 if( (criteria.type & CV_TERMCRIT_EPS) != 0 ) 3176 { 3177 if( criteria.epsilon < 0 ) 3178 CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" ); 3179 3180 crit.epsilon = criteria.epsilon; 3181 } 3182 3183 if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 ) 3184 CV_Error( CV_StsBadArg, 3185 "Neither accuracy nor maximum iterations " 3186 "number flags are set in criteria type" ); 3187 3188 crit.epsilon = (float)MAX( 0, crit.epsilon ); 3189 crit.max_iter = MAX( 1, crit.max_iter ); 3190 3191 return crit; 3192} 3193 3194namespace cv 3195{ 3196 3197template<> void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const 3198{ cvReleaseMat(&obj); } 3199 3200template<> void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const 3201{ cvReleaseImage(&obj); } 3202 3203template<> void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const 3204{ cvReleaseMatND(&obj); } 3205 3206template<> void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const 3207{ cvReleaseSparseMat(&obj); } 3208 3209template<> void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const 3210{ cvReleaseMemStorage(&obj); } 3211 3212template<> void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const 3213{ cvReleaseFileStorage(&obj); } 3214 3215} 3216 3217/* End of file. */ 3218