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 basic operations: cvCopy, cvSet 45// 46// */ 47 48#include "_cxcore.h" 49 50///////////////////////////////////////////////////////////////////////////////////////// 51// // 52// L/L COPY & SET FUNCTIONS // 53// // 54///////////////////////////////////////////////////////////////////////////////////////// 55 56 57IPCVAPI_IMPL( CvStatus, icvCopy_8u_C1R, ( const uchar* src, int srcstep, 58 uchar* dst, int dststep, CvSize size ), 59 (src, srcstep, dst, dststep, size) ) 60{ 61 for( ; size.height--; src += srcstep, dst += dststep ) 62 memcpy( dst, src, size.width ); 63 64 return CV_OK; 65} 66 67 68static CvStatus CV_STDCALL 69icvSet_8u_C1R( uchar* dst, int dst_step, CvSize size, 70 const void* scalar, int pix_size ) 71{ 72 int copy_len = 12*pix_size; 73 uchar* dst_limit = dst + size.width; 74 75 if( size.height-- ) 76 { 77 while( dst + copy_len <= dst_limit ) 78 { 79 memcpy( dst, scalar, copy_len ); 80 dst += copy_len; 81 } 82 83 memcpy( dst, scalar, dst_limit - dst ); 84 } 85 86 if( size.height ) 87 { 88 dst = dst_limit - size.width + dst_step; 89 90 for( ; size.height--; dst += dst_step ) 91 memcpy( dst, dst - dst_step, size.width ); 92 } 93 94 return CV_OK; 95} 96 97 98///////////////////////////////////////////////////////////////////////////////////////// 99// // 100// L/L COPY WITH MASK FUNCTIONS // 101// // 102///////////////////////////////////////////////////////////////////////////////////////// 103 104 105#define ICV_DEF_COPY_MASK_C1_CASE( type ) \ 106 for( i = 0; i <= size.width-2; i += 2 ) \ 107 { \ 108 if( mask[i] ) \ 109 dst[i] = src[i]; \ 110 if( mask[i+1] ) \ 111 dst[i+1] = src[i+1]; \ 112 } \ 113 \ 114 for( ; i < size.width; i++ ) \ 115 { \ 116 if( mask[i] ) \ 117 dst[i] = src[i]; \ 118 } 119 120#define ICV_DEF_COPY_MASK_C3_CASE( type ) \ 121 for( i = 0; i < size.width; i++ ) \ 122 if( mask[i] ) \ 123 { \ 124 type t0 = src[i*3]; \ 125 type t1 = src[i*3+1]; \ 126 type t2 = src[i*3+2]; \ 127 \ 128 dst[i*3] = t0; \ 129 dst[i*3+1] = t1; \ 130 dst[i*3+2] = t2; \ 131 } 132 133 134 135#define ICV_DEF_COPY_MASK_C4_CASE( type ) \ 136 for( i = 0; i < size.width; i++ ) \ 137 if( mask[i] ) \ 138 { \ 139 type t0 = src[i*4]; \ 140 type t1 = src[i*4+1]; \ 141 dst[i*4] = t0; \ 142 dst[i*4+1] = t1; \ 143 \ 144 t0 = src[i*4+2]; \ 145 t1 = src[i*4+3]; \ 146 dst[i*4+2] = t0; \ 147 dst[i*4+3] = t1; \ 148 } 149 150 151#define ICV_DEF_COPY_MASK_2D( name, type, cn ) \ 152IPCVAPI_IMPL( CvStatus, \ 153name,( const type* src, int srcstep, type* dst, int dststep,\ 154 CvSize size, const uchar* mask, int maskstep ), \ 155 (src, srcstep, dst, dststep, size, mask, maskstep)) \ 156{ \ 157 srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]); \ 158 for( ; size.height--; src += srcstep, \ 159 dst += dststep, mask += maskstep ) \ 160 { \ 161 int i; \ 162 ICV_DEF_COPY_MASK_C##cn##_CASE( type ) \ 163 } \ 164 \ 165 return CV_OK; \ 166} 167 168 169#define ICV_DEF_SET_MASK_C1_CASE( type ) \ 170 for( i = 0; i <= size.width-2; i += 2 ) \ 171 { \ 172 if( mask[i] ) \ 173 dst[i] = s0; \ 174 if( mask[i+1] ) \ 175 dst[i+1] = s0; \ 176 } \ 177 \ 178 for( ; i < size.width; i++ ) \ 179 { \ 180 if( mask[i] ) \ 181 dst[i] = s0; \ 182 } 183 184 185#define ICV_DEF_SET_MASK_C3_CASE( type ) \ 186 for( i = 0; i < size.width; i++ ) \ 187 if( mask[i] ) \ 188 { \ 189 dst[i*3] = s0; \ 190 dst[i*3+1] = s1; \ 191 dst[i*3+2] = s2; \ 192 } 193 194#define ICV_DEF_SET_MASK_C4_CASE( type ) \ 195 for( i = 0; i < size.width; i++ ) \ 196 if( mask[i] ) \ 197 { \ 198 dst[i*4] = s0; \ 199 dst[i*4+1] = s1; \ 200 dst[i*4+2] = s2; \ 201 dst[i*4+3] = s3; \ 202 } 203 204#define ICV_DEF_SET_MASK_2D( name, type, cn ) \ 205IPCVAPI_IMPL( CvStatus, \ 206name,( type* dst, int dststep, \ 207 const uchar* mask, int maskstep, \ 208 CvSize size, const type* scalar ), \ 209 (dst, dststep, mask, maskstep, size, scalar))\ 210{ \ 211 CV_UN_ENTRY_C##cn( type ); \ 212 dststep /= sizeof(dst[0]); \ 213 \ 214 for( ; size.height--; mask += maskstep, \ 215 dst += dststep ) \ 216 { \ 217 int i; \ 218 ICV_DEF_SET_MASK_C##cn##_CASE( type ) \ 219 } \ 220 \ 221 return CV_OK; \ 222} 223 224 225ICV_DEF_SET_MASK_2D( icvSet_8u_C1MR, uchar, 1 ) 226ICV_DEF_SET_MASK_2D( icvSet_16s_C1MR, ushort, 1 ) 227ICV_DEF_SET_MASK_2D( icvSet_8u_C3MR, uchar, 3 ) 228ICV_DEF_SET_MASK_2D( icvSet_8u_C4MR, int, 1 ) 229ICV_DEF_SET_MASK_2D( icvSet_16s_C3MR, ushort, 3 ) 230ICV_DEF_SET_MASK_2D( icvSet_16s_C4MR, int64, 1 ) 231ICV_DEF_SET_MASK_2D( icvSet_32f_C3MR, int, 3 ) 232ICV_DEF_SET_MASK_2D( icvSet_32f_C4MR, int, 4 ) 233ICV_DEF_SET_MASK_2D( icvSet_64s_C3MR, int64, 3 ) 234ICV_DEF_SET_MASK_2D( icvSet_64s_C4MR, int64, 4 ) 235 236ICV_DEF_COPY_MASK_2D( icvCopy_8u_C1MR, uchar, 1 ) 237ICV_DEF_COPY_MASK_2D( icvCopy_16s_C1MR, ushort, 1 ) 238ICV_DEF_COPY_MASK_2D( icvCopy_8u_C3MR, uchar, 3 ) 239ICV_DEF_COPY_MASK_2D( icvCopy_8u_C4MR, int, 1 ) 240ICV_DEF_COPY_MASK_2D( icvCopy_16s_C3MR, ushort, 3 ) 241ICV_DEF_COPY_MASK_2D( icvCopy_16s_C4MR, int64, 1 ) 242ICV_DEF_COPY_MASK_2D( icvCopy_32f_C3MR, int, 3 ) 243ICV_DEF_COPY_MASK_2D( icvCopy_32f_C4MR, int, 4 ) 244ICV_DEF_COPY_MASK_2D( icvCopy_64s_C3MR, int64, 3 ) 245ICV_DEF_COPY_MASK_2D( icvCopy_64s_C4MR, int64, 4 ) 246 247#define CV_DEF_INIT_COPYSET_TAB_2D( FUNCNAME, FLAG ) \ 248static void icvInit##FUNCNAME##FLAG##Table( CvBtFuncTable* table ) \ 249{ \ 250 table->fn_2d[1] = (void*)icv##FUNCNAME##_8u_C1##FLAG; \ 251 table->fn_2d[2] = (void*)icv##FUNCNAME##_16s_C1##FLAG; \ 252 table->fn_2d[3] = (void*)icv##FUNCNAME##_8u_C3##FLAG; \ 253 table->fn_2d[4] = (void*)icv##FUNCNAME##_8u_C4##FLAG; \ 254 table->fn_2d[6] = (void*)icv##FUNCNAME##_16s_C3##FLAG; \ 255 table->fn_2d[8] = (void*)icv##FUNCNAME##_16s_C4##FLAG; \ 256 table->fn_2d[12] = (void*)icv##FUNCNAME##_32f_C3##FLAG; \ 257 table->fn_2d[16] = (void*)icv##FUNCNAME##_32f_C4##FLAG; \ 258 table->fn_2d[24] = (void*)icv##FUNCNAME##_64s_C3##FLAG; \ 259 table->fn_2d[32] = (void*)icv##FUNCNAME##_64s_C4##FLAG; \ 260} 261 262CV_DEF_INIT_COPYSET_TAB_2D( Set, MR ) 263CV_DEF_INIT_COPYSET_TAB_2D( Copy, MR ) 264 265///////////////////////////////////////////////////////////////////////////////////////// 266// // 267// H/L COPY & SET FUNCTIONS // 268// // 269///////////////////////////////////////////////////////////////////////////////////////// 270 271 272CvCopyMaskFunc 273icvGetCopyMaskFunc( int elem_size ) 274{ 275 static CvBtFuncTable copym_tab; 276 static int inittab = 0; 277 278 if( !inittab ) 279 { 280 icvInitCopyMRTable( ©m_tab ); 281 inittab = 1; 282 } 283 return (CvCopyMaskFunc)copym_tab.fn_2d[elem_size]; 284} 285 286 287/* dst = src */ 288CV_IMPL void 289cvCopy( const void* srcarr, void* dstarr, const void* maskarr ) 290{ 291 CV_FUNCNAME( "cvCopy" ); 292 293 __BEGIN__; 294 295 int pix_size; 296 CvMat srcstub, *src = (CvMat*)srcarr; 297 CvMat dststub, *dst = (CvMat*)dstarr; 298 CvSize size; 299 300 if( !CV_IS_MAT(src) || !CV_IS_MAT(dst) ) 301 { 302 if( CV_IS_SPARSE_MAT(src) && CV_IS_SPARSE_MAT(dst)) 303 { 304 CvSparseMat* src1 = (CvSparseMat*)src; 305 CvSparseMat* dst1 = (CvSparseMat*)dst; 306 CvSparseMatIterator iterator; 307 CvSparseNode* node; 308 309 dst1->dims = src1->dims; 310 memcpy( dst1->size, src1->size, src1->dims*sizeof(src1->size[0])); 311 dst1->valoffset = src1->valoffset; 312 dst1->idxoffset = src1->idxoffset; 313 cvClearSet( dst1->heap ); 314 315 if( src1->heap->active_count >= dst1->hashsize*CV_SPARSE_HASH_RATIO ) 316 { 317 CV_CALL( cvFree( &dst1->hashtable )); 318 dst1->hashsize = src1->hashsize; 319 CV_CALL( dst1->hashtable = 320 (void**)cvAlloc( dst1->hashsize*sizeof(dst1->hashtable[0]))); 321 } 322 323 memset( dst1->hashtable, 0, dst1->hashsize*sizeof(dst1->hashtable[0])); 324 325 for( node = cvInitSparseMatIterator( src1, &iterator ); 326 node != 0; node = cvGetNextSparseNode( &iterator )) 327 { 328 CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap ); 329 int tabidx = node->hashval & (dst1->hashsize - 1); 330 CV_MEMCPY_AUTO( node_copy, node, dst1->heap->elem_size ); 331 node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx]; 332 dst1->hashtable[tabidx] = node_copy; 333 } 334 EXIT; 335 } 336 else if( CV_IS_MATND(src) || CV_IS_MATND(dst) ) 337 { 338 CvArr* arrs[] = { src, dst }; 339 CvMatND stubs[3]; 340 CvNArrayIterator iterator; 341 342 CV_CALL( cvInitNArrayIterator( 2, arrs, maskarr, stubs, &iterator )); 343 pix_size = CV_ELEM_SIZE(iterator.hdr[0]->type); 344 345 if( !maskarr ) 346 { 347 iterator.size.width *= pix_size; 348 if( iterator.size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double)) 349 { 350 do 351 { 352 memcpy( iterator.ptr[1], iterator.ptr[0], iterator.size.width ); 353 } 354 while( cvNextNArraySlice( &iterator )); 355 } 356 else 357 { 358 do 359 { 360 icvCopy_8u_C1R( iterator.ptr[0], CV_STUB_STEP, 361 iterator.ptr[1], CV_STUB_STEP, iterator.size ); 362 } 363 while( cvNextNArraySlice( &iterator )); 364 } 365 } 366 else 367 { 368 CvCopyMaskFunc func = icvGetCopyMaskFunc( pix_size ); 369 if( !func ) 370 CV_ERROR( CV_StsUnsupportedFormat, "" ); 371 372 do 373 { 374 func( iterator.ptr[0], CV_STUB_STEP, 375 iterator.ptr[1], CV_STUB_STEP, 376 iterator.size, 377 iterator.ptr[2], CV_STUB_STEP ); 378 } 379 while( cvNextNArraySlice( &iterator )); 380 } 381 EXIT; 382 } 383 else 384 { 385 int coi1 = 0, coi2 = 0; 386 CV_CALL( src = cvGetMat( src, &srcstub, &coi1 )); 387 CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 )); 388 389 if( coi1 ) 390 { 391 CvArr* planes[] = { 0, 0, 0, 0 }; 392 393 if( maskarr ) 394 CV_ERROR( CV_StsBadArg, "COI + mask are not supported" ); 395 396 planes[coi1-1] = dst; 397 CV_CALL( cvSplit( src, planes[0], planes[1], planes[2], planes[3] )); 398 EXIT; 399 } 400 else if( coi2 ) 401 { 402 CvArr* planes[] = { 0, 0, 0, 0 }; 403 404 if( maskarr ) 405 CV_ERROR( CV_StsBadArg, "COI + mask are not supported" ); 406 407 planes[coi2-1] = src; 408 CV_CALL( cvMerge( planes[0], planes[1], planes[2], planes[3], dst )); 409 EXIT; 410 } 411 } 412 } 413 414 if( !CV_ARE_TYPES_EQ( src, dst )) 415 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 416 417 if( !CV_ARE_SIZES_EQ( src, dst )) 418 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 419 420 size = cvGetMatSize( src ); 421 pix_size = CV_ELEM_SIZE(src->type); 422 423 if( !maskarr ) 424 { 425 int src_step = src->step, dst_step = dst->step; 426 size.width *= pix_size; 427 if( CV_IS_MAT_CONT( src->type & dst->type ) && (src_step == dst_step) && (src_step == src->width * pix_size)) 428 { 429 size.width *= size.height; 430 431 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE* 432 CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double)) 433 { 434 memcpy( dst->data.ptr, src->data.ptr, size.width ); 435 EXIT; 436 } 437 438 size.height = 1; 439 src_step = dst_step = CV_STUB_STEP; 440 } 441 442 if( src->data.ptr != dst->data.ptr ) 443 icvCopy_8u_C1R( src->data.ptr, src_step, 444 dst->data.ptr, dst_step, size ); 445 } 446 else 447 { 448 CvCopyMaskFunc func = icvGetCopyMaskFunc(pix_size); 449 CvMat maskstub, *mask = (CvMat*)maskarr; 450 int src_step = src->step; 451 int dst_step = dst->step; 452 int mask_step; 453 454 if( !CV_IS_MAT( mask )) 455 CV_CALL( mask = cvGetMat( mask, &maskstub )); 456 if( !CV_IS_MASK_ARR( mask )) 457 CV_ERROR( CV_StsBadMask, "" ); 458 459 if( !CV_ARE_SIZES_EQ( src, mask )) 460 CV_ERROR( CV_StsUnmatchedSizes, "" ); 461 462 mask_step = mask->step; 463 464 if( CV_IS_MAT_CONT( src->type & dst->type & mask->type )) 465 { 466 size.width *= size.height; 467 size.height = 1; 468 src_step = dst_step = mask_step = CV_STUB_STEP; 469 } 470 471 if( !func ) 472 CV_ERROR( CV_StsUnsupportedFormat, "" ); 473 474 IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr, dst_step, 475 size, mask->data.ptr, mask_step )); 476 } 477 478 __END__; 479} 480 481 482/* dst(idx) = value */ 483CV_IMPL void 484cvSet( void* arr, CvScalar value, const void* maskarr ) 485{ 486 static CvBtFuncTable setm_tab; 487 static int inittab = 0; 488 489 CV_FUNCNAME( "cvSet" ); 490 491 __BEGIN__; 492 493 CvMat stub, *mat = (CvMat*)arr; 494 int pix_size, type; 495 double buf[12]; 496 int mat_step; 497 CvSize size; 498 499 if( !value.val[0] && !value.val[1] && 500 !value.val[2] && !value.val[3] && !maskarr ) 501 { 502 cvZero( arr ); 503 EXIT; 504 } 505 506 if( !CV_IS_MAT(mat)) 507 { 508 if( CV_IS_MATND(mat)) 509 { 510 CvMatND nstub; 511 CvNArrayIterator iterator; 512 int pix_size1; 513 514 CV_CALL( cvInitNArrayIterator( 1, &arr, maskarr, &nstub, &iterator )); 515 516 type = CV_MAT_TYPE(iterator.hdr[0]->type); 517 pix_size1 = CV_ELEM_SIZE1(type); 518 pix_size = pix_size1*CV_MAT_CN(type); 519 520 CV_CALL( cvScalarToRawData( &value, buf, type, maskarr == 0 )); 521 522 if( !maskarr ) 523 { 524 iterator.size.width *= pix_size; 525 do 526 { 527 icvSet_8u_C1R( iterator.ptr[0], CV_STUB_STEP, 528 iterator.size, buf, pix_size1 ); 529 } 530 while( cvNextNArraySlice( &iterator )); 531 } 532 else 533 { 534 CvFunc2D_2A1P func = (CvFunc2D_2A1P)(setm_tab.fn_2d[pix_size]); 535 if( !func ) 536 CV_ERROR( CV_StsUnsupportedFormat, "" ); 537 538 do 539 { 540 func( iterator.ptr[0], CV_STUB_STEP, 541 iterator.ptr[1], CV_STUB_STEP, 542 iterator.size, buf ); 543 } 544 while( cvNextNArraySlice( &iterator )); 545 } 546 EXIT; 547 } 548 else 549 { 550 int coi = 0; 551 CV_CALL( mat = cvGetMat( mat, &stub, &coi )); 552 553 if( coi != 0 ) 554 CV_ERROR( CV_BadCOI, "" ); 555 } 556 } 557 558 type = CV_MAT_TYPE( mat->type ); 559 pix_size = CV_ELEM_SIZE(type); 560 size = cvGetMatSize( mat ); 561 mat_step = mat->step; 562 563 if( !maskarr ) 564 { 565 if( CV_IS_MAT_CONT( mat->type )) 566 { 567 size.width *= size.height; 568 569 if( size.width <= (int)(CV_MAX_INLINE_MAT_OP_SIZE*sizeof(double))) 570 { 571 if( type == CV_32FC1 ) 572 { 573 float* dstdata = (float*)(mat->data.ptr); 574 float val = (float)value.val[0]; 575 576 do 577 { 578 dstdata[size.width-1] = val; 579 } 580 while( --size.width ); 581 582 EXIT; 583 } 584 585 if( type == CV_64FC1 ) 586 { 587 double* dstdata = (double*)(mat->data.ptr); 588 double val = value.val[0]; 589 590 do 591 { 592 dstdata[size.width-1] = val; 593 } 594 while( --size.width ); 595 596 EXIT; 597 } 598 } 599 600 mat_step = CV_STUB_STEP; 601 size.height = 1; 602 } 603 604 size.width *= pix_size; 605 CV_CALL( cvScalarToRawData( &value, buf, type, 1 )); 606 607 IPPI_CALL( icvSet_8u_C1R( mat->data.ptr, mat_step, size, buf, 608 CV_ELEM_SIZE1(type))); 609 } 610 else 611 { 612 CvFunc2D_2A1P func; 613 CvMat maskstub, *mask = (CvMat*)maskarr; 614 int mask_step; 615 616 CV_CALL( mask = cvGetMat( mask, &maskstub )); 617 618 if( !CV_IS_MASK_ARR( mask )) 619 CV_ERROR( CV_StsBadMask, "" ); 620 621 if( !inittab ) 622 { 623 icvInitSetMRTable( &setm_tab ); 624 inittab = 1; 625 } 626 627 if( !CV_ARE_SIZES_EQ( mat, mask )) 628 CV_ERROR( CV_StsUnmatchedSizes, "" ); 629 630 mask_step = mask->step; 631 632 if( CV_IS_MAT_CONT( mat->type & mask->type )) 633 { 634 size.width *= size.height; 635 mat_step = mask_step = CV_STUB_STEP; 636 size.height = 1; 637 } 638 639 func = (CvFunc2D_2A1P)(setm_tab.fn_2d[pix_size]); 640 if( !func ) 641 CV_ERROR( CV_StsUnsupportedFormat, "" ); 642 643 CV_CALL( cvScalarToRawData( &value, buf, type, 0 )); 644 645 IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr, 646 mask_step, size, buf )); 647 } 648 649 __END__; 650} 651 652 653/****************************************************************************************\ 654* Clearing * 655\****************************************************************************************/ 656 657icvSetByte_8u_C1R_t icvSetByte_8u_C1R_p = 0; 658 659CvStatus CV_STDCALL 660icvSetZero_8u_C1R( uchar* dst, int dststep, CvSize size ) 661{ 662 if( size.width + size.height > 256 && icvSetByte_8u_C1R_p ) 663 return icvSetByte_8u_C1R_p( 0, dst, dststep, size ); 664 665 for( ; size.height--; dst += dststep ) 666 memset( dst, 0, size.width ); 667 668 return CV_OK; 669} 670 671CV_IMPL void 672cvSetZero( CvArr* arr ) 673{ 674 CV_FUNCNAME( "cvSetZero" ); 675 676 __BEGIN__; 677 678 CvMat stub, *mat = (CvMat*)arr; 679 CvSize size; 680 int mat_step; 681 682 if( !CV_IS_MAT( mat )) 683 { 684 if( CV_IS_MATND(mat)) 685 { 686 CvMatND nstub; 687 CvNArrayIterator iterator; 688 689 CV_CALL( cvInitNArrayIterator( 1, &arr, 0, &nstub, &iterator )); 690 iterator.size.width *= CV_ELEM_SIZE(iterator.hdr[0]->type); 691 692 if( iterator.size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double) ) 693 { 694 do 695 { 696 memset( iterator.ptr[0], 0, iterator.size.width ); 697 } 698 while( cvNextNArraySlice( &iterator )); 699 } 700 else 701 { 702 do 703 { 704 icvSetZero_8u_C1R( iterator.ptr[0], CV_STUB_STEP, iterator.size ); 705 } 706 while( cvNextNArraySlice( &iterator )); 707 } 708 EXIT; 709 } 710 else if( CV_IS_SPARSE_MAT(mat)) 711 { 712 CvSparseMat* mat1 = (CvSparseMat*)mat; 713 cvClearSet( mat1->heap ); 714 if( mat1->hashtable ) 715 memset( mat1->hashtable, 0, mat1->hashsize*sizeof(mat1->hashtable[0])); 716 EXIT; 717 } 718 else 719 { 720 int coi = 0; 721 CV_CALL( mat = cvGetMat( mat, &stub, &coi )); 722 if( coi != 0 ) 723 CV_ERROR( CV_BadCOI, "coi is not supported" ); 724 } 725 } 726 727 size = cvGetMatSize( mat ); 728 size.width *= CV_ELEM_SIZE(mat->type); 729 mat_step = mat->step; 730 731 if( CV_IS_MAT_CONT( mat->type )) 732 { 733 size.width *= size.height; 734 735 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double) ) 736 { 737 memset( mat->data.ptr, 0, size.width ); 738 EXIT; 739 } 740 741 mat_step = CV_STUB_STEP; 742 size.height = 1; 743 } 744 745 IPPI_CALL( icvSetZero_8u_C1R( mat->data.ptr, mat_step, size )); 746 747 __END__; 748} 749 750 751/****************************************************************************************\ 752* Flipping * 753\****************************************************************************************/ 754 755#define ICV_DEF_FLIP_HZ_CASE_C1( type ) \ 756 for( i = 0; i < (len+1)/2; i++ ) \ 757 { \ 758 type t0 = src[i]; \ 759 type t1 = src[len - i - 1]; \ 760 dst[i] = t1; \ 761 dst[len - i - 1] = t0; \ 762 } 763 764 765#define ICV_DEF_FLIP_HZ_CASE_C3( type ) \ 766 for( i = 0; i < (len+1)/2; i++ ) \ 767 { \ 768 type t0 = src[i*3]; \ 769 type t1 = src[(len - i)*3 - 3]; \ 770 dst[i*3] = t1; \ 771 dst[(len - i)*3 - 3] = t0; \ 772 t0 = src[i*3 + 1]; \ 773 t1 = src[(len - i)*3 - 2]; \ 774 dst[i*3 + 1] = t1; \ 775 dst[(len - i)*3 - 2] = t0; \ 776 t0 = src[i*3 + 2]; \ 777 t1 = src[(len - i)*3 - 1]; \ 778 dst[i*3 + 2] = t1; \ 779 dst[(len - i)*3 - 1] = t0; \ 780 } 781 782 783#define ICV_DEF_FLIP_HZ_CASE_C4( type ) \ 784 for( i = 0; i < (len+1)/2; i++ ) \ 785 { \ 786 type t0 = src[i*4]; \ 787 type t1 = src[(len - i)*4 - 4]; \ 788 dst[i*4] = t1; \ 789 dst[(len - i)*4 - 4] = t0; \ 790 t0 = src[i*4 + 1]; \ 791 t1 = src[(len - i)*4 - 3]; \ 792 dst[i*4 + 1] = t1; \ 793 dst[(len - i)*4 - 3] = t0; \ 794 t0 = src[i*4 + 2]; \ 795 t1 = src[(len - i)*4 - 2]; \ 796 dst[i*4 + 2] = t1; \ 797 dst[(len - i)*4 - 2] = t0; \ 798 t0 = src[i*4 + 3]; \ 799 t1 = src[(len - i)*4 - 1]; \ 800 dst[i*4 + 3] = t1; \ 801 dst[(len - i)*4 - 1] = t0; \ 802 } 803 804 805#define ICV_DEF_FLIP_HZ_FUNC( flavor, arrtype, cn ) \ 806static CvStatus CV_STDCALL \ 807icvFlipHorz_##flavor( const arrtype* src, int srcstep, \ 808 arrtype* dst, int dststep, CvSize size ) \ 809{ \ 810 int i, len = size.width; \ 811 srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]); \ 812 \ 813 for( ; size.height--; src += srcstep, dst += dststep ) \ 814 { \ 815 ICV_DEF_FLIP_HZ_CASE_C##cn( arrtype ) \ 816 } \ 817 \ 818 return CV_OK; \ 819} 820 821 822ICV_DEF_FLIP_HZ_FUNC( 8u_C1R, uchar, 1 ) 823ICV_DEF_FLIP_HZ_FUNC( 8u_C2R, ushort, 1 ) 824ICV_DEF_FLIP_HZ_FUNC( 8u_C3R, uchar, 3 ) 825ICV_DEF_FLIP_HZ_FUNC( 16u_C2R, int, 1 ) 826ICV_DEF_FLIP_HZ_FUNC( 16u_C3R, ushort, 3 ) 827ICV_DEF_FLIP_HZ_FUNC( 32s_C2R, int64, 1 ) 828ICV_DEF_FLIP_HZ_FUNC( 32s_C3R, int, 3 ) 829ICV_DEF_FLIP_HZ_FUNC( 64s_C2R, int, 4 ) 830ICV_DEF_FLIP_HZ_FUNC( 64s_C3R, int64, 3 ) 831ICV_DEF_FLIP_HZ_FUNC( 64s_C4R, int64, 4 ) 832 833CV_DEF_INIT_PIXSIZE_TAB_2D( FlipHorz, R ) 834 835 836static CvStatus 837icvFlipVert_8u_C1R( const uchar* src, int srcstep, 838 uchar* dst, int dststep, CvSize size ) 839{ 840 int y, i; 841 const uchar* src1 = src + (size.height - 1)*srcstep; 842 uchar* dst1 = dst + (size.height - 1)*dststep; 843 844 for( y = 0; y < (size.height + 1)/2; y++, src += srcstep, src1 -= srcstep, 845 dst += dststep, dst1 -= dststep ) 846 { 847 i = 0; 848 if( ((size_t)(src)|(size_t)(dst)|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 ) 849 { 850 for( ; i <= size.width - 16; i += 16 ) 851 { 852 int t0 = ((int*)(src + i))[0]; 853 int t1 = ((int*)(src1 + i))[0]; 854 855 ((int*)(dst + i))[0] = t1; 856 ((int*)(dst1 + i))[0] = t0; 857 858 t0 = ((int*)(src + i))[1]; 859 t1 = ((int*)(src1 + i))[1]; 860 861 ((int*)(dst + i))[1] = t1; 862 ((int*)(dst1 + i))[1] = t0; 863 864 t0 = ((int*)(src + i))[2]; 865 t1 = ((int*)(src1 + i))[2]; 866 867 ((int*)(dst + i))[2] = t1; 868 ((int*)(dst1 + i))[2] = t0; 869 870 t0 = ((int*)(src + i))[3]; 871 t1 = ((int*)(src1 + i))[3]; 872 873 ((int*)(dst + i))[3] = t1; 874 ((int*)(dst1 + i))[3] = t0; 875 } 876 877 for( ; i <= size.width - 4; i += 4 ) 878 { 879 int t0 = ((int*)(src + i))[0]; 880 int t1 = ((int*)(src1 + i))[0]; 881 882 ((int*)(dst + i))[0] = t1; 883 ((int*)(dst1 + i))[0] = t0; 884 } 885 } 886 887 for( ; i < size.width; i++ ) 888 { 889 uchar t0 = src[i]; 890 uchar t1 = src1[i]; 891 892 dst[i] = t1; 893 dst1[i] = t0; 894 } 895 } 896 897 return CV_OK; 898} 899 900 901CV_IMPL void 902cvFlip( const CvArr* srcarr, CvArr* dstarr, int flip_mode ) 903{ 904 static CvBtFuncTable tab; 905 static int inittab = 0; 906 907 CV_FUNCNAME( "cvFlip" ); 908 909 __BEGIN__; 910 911 CvMat sstub, *src = (CvMat*)srcarr; 912 CvMat dstub, *dst = (CvMat*)dstarr; 913 CvSize size; 914 CvFunc2D_2A func = 0; 915 int pix_size; 916 917 if( !inittab ) 918 { 919 icvInitFlipHorzRTable( &tab ); 920 inittab = 1; 921 } 922 923 if( !CV_IS_MAT( src )) 924 { 925 int coi = 0; 926 CV_CALL( src = cvGetMat( src, &sstub, &coi )); 927 if( coi != 0 ) 928 CV_ERROR( CV_BadCOI, "coi is not supported" ); 929 } 930 931 if( !dst ) 932 dst = src; 933 else if( !CV_IS_MAT( dst )) 934 { 935 int coi = 0; 936 CV_CALL( dst = cvGetMat( dst, &dstub, &coi )); 937 if( coi != 0 ) 938 CV_ERROR( CV_BadCOI, "coi is not supported" ); 939 } 940 941 if( !CV_ARE_TYPES_EQ( src, dst )) 942 CV_ERROR( CV_StsUnmatchedFormats, "" ); 943 944 if( !CV_ARE_SIZES_EQ( src, dst )) 945 CV_ERROR( CV_StsUnmatchedSizes, "" ); 946 947 size = cvGetMatSize( src ); 948 pix_size = CV_ELEM_SIZE( src->type ); 949 950 if( flip_mode == 0 ) 951 { 952 size.width *= pix_size; 953 954 IPPI_CALL( icvFlipVert_8u_C1R( src->data.ptr, src->step, 955 dst->data.ptr, dst->step, size )); 956 } 957 else 958 { 959 int inplace = src->data.ptr == dst->data.ptr; 960 uchar* dst_data = dst->data.ptr; 961 int dst_step = dst->step; 962 963 func = (CvFunc2D_2A)(tab.fn_2d[pix_size]); 964 965 if( !func ) 966 CV_ERROR( CV_StsUnsupportedFormat, "" ); 967 968 if( flip_mode < 0 && !inplace ) 969 { 970 dst_data += dst_step * (dst->height - 1); 971 dst_step = -dst_step; 972 } 973 974 IPPI_CALL( func( src->data.ptr, src->step, dst_data, dst_step, size )); 975 976 if( flip_mode < 0 && inplace ) 977 { 978 size.width *= pix_size; 979 IPPI_CALL( icvFlipVert_8u_C1R( dst->data.ptr, dst->step, 980 dst->data.ptr, dst->step, size )); 981 } 982 } 983 984 __END__; 985} 986 987 988CV_IMPL void 989cvRepeat( const CvArr* srcarr, CvArr* dstarr ) 990{ 991 CV_FUNCNAME( "cvRepeat" ); 992 993 __BEGIN__; 994 995 CvMat sstub, *src = (CvMat*)srcarr; 996 CvMat dstub, *dst = (CvMat*)dstarr; 997 CvSize srcsize, dstsize; 998 int pix_size; 999 int x, y, k, l; 1000 1001 if( !CV_IS_MAT( src )) 1002 { 1003 int coi = 0; 1004 CV_CALL( src = cvGetMat( src, &sstub, &coi )); 1005 if( coi != 0 ) 1006 CV_ERROR( CV_BadCOI, "coi is not supported" ); 1007 } 1008 1009 if( !CV_IS_MAT( dst )) 1010 { 1011 int coi = 0; 1012 CV_CALL( dst = cvGetMat( dst, &dstub, &coi )); 1013 if( coi != 0 ) 1014 CV_ERROR( CV_BadCOI, "coi is not supported" ); 1015 } 1016 1017 if( !CV_ARE_TYPES_EQ( src, dst )) 1018 CV_ERROR( CV_StsUnmatchedFormats, "" ); 1019 1020 srcsize = cvGetMatSize( src ); 1021 dstsize = cvGetMatSize( dst ); 1022 pix_size = CV_ELEM_SIZE( src->type ); 1023 1024 for( y = 0, k = 0; y < dstsize.height; y++ ) 1025 { 1026 for( x = 0; x < dstsize.width; x += srcsize.width ) 1027 { 1028 l = srcsize.width; 1029 if( l > dstsize.width - x ) 1030 l = dstsize.width - x; 1031 memcpy( dst->data.ptr + y*dst->step + x*pix_size, 1032 src->data.ptr + k*src->step, l*pix_size ); 1033 } 1034 if( ++k == srcsize.height ) 1035 k = 0; 1036 } 1037 1038 __END__; 1039} 1040 1041/* End of file. */ 1042 1043