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 comparison functions: range checking, min, max 45 // 46 // */ 47 48 #include "_cxcore.h" 49 50 /****************************************************************************************\ 51 * InRange[S] * 52 \****************************************************************************************/ 53 54 #define ICV_DEF_IN_RANGE_CASE_C1( worktype, _toggle_macro_ ) \ 55 for( x = 0; x < size.width; x++ ) \ 56 { \ 57 worktype a1 = _toggle_macro_(src1[x]), \ 58 a2 = src2[x], a3 = src3[x]; \ 59 dst[x] = (uchar)-(_toggle_macro_(a2) <= a1 && \ 60 a1 < _toggle_macro_(a3)); \ 61 } 62 63 64 #define ICV_DEF_IN_RANGE_CASE_C2( worktype, _toggle_macro_ ) \ 65 for( x = 0; x < size.width; x++ ) \ 66 { \ 67 worktype a1 = _toggle_macro_(src1[x*2]), \ 68 a2 = src2[x*2], a3 = src3[x*2]; \ 69 int f = _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 70 a1 = _toggle_macro_(src1[x*2+1]); \ 71 a2 = src2[x*2+1]; \ 72 a3 = src3[x*2+1]; \ 73 f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 74 dst[x] = (uchar)-f; \ 75 } 76 77 78 #define ICV_DEF_IN_RANGE_CASE_C3( worktype, _toggle_macro_ ) \ 79 for( x = 0; x < size.width; x++ ) \ 80 { \ 81 worktype a1 = _toggle_macro_(src1[x*3]), \ 82 a2 = src2[x*3], a3 = src3[x*3]; \ 83 int f = _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 84 a1 = _toggle_macro_(src1[x*3+1]); \ 85 a2 = src2[x*3+1]; \ 86 a3 = src3[x*3+1]; \ 87 f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 88 a1 = _toggle_macro_(src1[x*3+2]); \ 89 a2 = src2[x*3+2]; \ 90 a3 = src3[x*3+2]; \ 91 f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 92 dst[x] = (uchar)-f; \ 93 } 94 95 96 #define ICV_DEF_IN_RANGE_CASE_C4( worktype, _toggle_macro_ ) \ 97 for( x = 0; x < size.width; x++ ) \ 98 { \ 99 worktype a1 = _toggle_macro_(src1[x*4]), \ 100 a2 = src2[x*4], a3 = src3[x*4]; \ 101 int f = _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 102 a1 = _toggle_macro_(src1[x*4+1]); \ 103 a2 = src2[x*4+1]; \ 104 a3 = src3[x*4+1]; \ 105 f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 106 a1 = _toggle_macro_(src1[x*4+2]); \ 107 a2 = src2[x*4+2]; \ 108 a3 = src3[x*4+2]; \ 109 f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 110 a1 = _toggle_macro_(src1[x*4+3]); \ 111 a2 = src2[x*4+3]; \ 112 a3 = src3[x*4+3]; \ 113 f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3); \ 114 dst[x] = (uchar)-f; \ 115 } 116 117 118 #define ICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, \ 119 _toggle_macro_, cn ) \ 120 static CvStatus CV_STDCALL \ 121 icvInRange_##flavor##_C##cn##R( const arrtype* src1, int step1, \ 122 const arrtype* src2, int step2, \ 123 const arrtype* src3, int step3, \ 124 uchar* dst, int step, CvSize size ) \ 125 { \ 126 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); \ 127 step3 /= sizeof(src3[0]); step /= sizeof(dst[0]); \ 128 \ 129 for( ; size.height--; src1 += step1, src2 += step2, \ 130 src3 += step3, dst += step ) \ 131 { \ 132 int x; \ 133 ICV_DEF_IN_RANGE_CASE_C##cn( worktype, _toggle_macro_ ) \ 134 } \ 135 \ 136 return CV_OK; \ 137 } 138 139 140 #define ICV_DEF_IN_RANGE_CASE_CONST_C1( worktype, _toggle_macro_ ) \ 141 for( x = 0; x < size.width; x++ ) \ 142 { \ 143 worktype a1 = _toggle_macro_(src1[x]); \ 144 dst[x] = (uchar)-(scalar[0] <= a1 && a1 < scalar[1]); \ 145 } 146 147 148 #define ICV_DEF_IN_RANGE_CASE_CONST_C2( worktype, _toggle_macro_ ) \ 149 for( x = 0; x < size.width; x++ ) \ 150 { \ 151 worktype a1 = _toggle_macro_(src1[x*2]); \ 152 int f = scalar[0] <= a1 && a1 < scalar[2]; \ 153 a1 = _toggle_macro_(src1[x*2+1]); \ 154 f &= scalar[1] <= a1 && a1 < scalar[3]; \ 155 dst[x] = (uchar)-f; \ 156 } 157 158 159 #define ICV_DEF_IN_RANGE_CASE_CONST_C3( worktype, _toggle_macro_ ) \ 160 for( x = 0; x < size.width; x++ ) \ 161 { \ 162 worktype a1 = _toggle_macro_(src1[x*3]); \ 163 int f = scalar[0] <= a1 && a1 < scalar[3]; \ 164 a1 = _toggle_macro_(src1[x*3+1]); \ 165 f &= scalar[1] <= a1 && a1 < scalar[4]; \ 166 a1 = _toggle_macro_(src1[x*3+2]); \ 167 f &= scalar[2] <= a1 && a1 < scalar[5]; \ 168 dst[x] = (uchar)-f; \ 169 } 170 171 172 #define ICV_DEF_IN_RANGE_CASE_CONST_C4( worktype, _toggle_macro_ ) \ 173 for( x = 0; x < size.width; x++ ) \ 174 { \ 175 worktype a1 = _toggle_macro_(src1[x*4]); \ 176 int f = scalar[0] <= a1 && a1 < scalar[4]; \ 177 a1 = _toggle_macro_(src1[x*4+1]); \ 178 f &= scalar[1] <= a1 && a1 < scalar[5]; \ 179 a1 = _toggle_macro_(src1[x*4+2]); \ 180 f &= scalar[2] <= a1 && a1 < scalar[6]; \ 181 a1 = _toggle_macro_(src1[x*4+3]); \ 182 f &= scalar[3] <= a1 && a1 < scalar[7]; \ 183 dst[x] = (uchar)-f; \ 184 } 185 186 187 #define ICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, \ 188 _toggle_macro_, cn ) \ 189 static CvStatus CV_STDCALL \ 190 icvInRangeC_##flavor##_C##cn##R( const arrtype* src1, int step1, \ 191 uchar* dst, int step, CvSize size, \ 192 const worktype* scalar ) \ 193 { \ 194 step1 /= sizeof(src1[0]); step /= sizeof(dst[0]); \ 195 \ 196 for( ; size.height--; src1 += step1, dst += step ) \ 197 { \ 198 int x; \ 199 ICV_DEF_IN_RANGE_CASE_CONST_C##cn( worktype, _toggle_macro_)\ 200 } \ 201 \ 202 return CV_OK; \ 203 } 204 205 206 #define ICV_DEF_IN_RANGE_ALL( flavor, arrtype, worktype, _toggle_macro_ ) \ 207 ICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 1 ) \ 208 ICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 2 ) \ 209 ICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 3 ) \ 210 ICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 4 ) \ 211 \ 212 ICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 1 ) \ 213 ICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 2 ) \ 214 ICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 3 ) \ 215 ICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 4 ) 216 217 ICV_DEF_IN_RANGE_ALL( 8u, uchar, int, CV_NOP ) 218 ICV_DEF_IN_RANGE_ALL( 16u, ushort, int, CV_NOP ) 219 ICV_DEF_IN_RANGE_ALL( 16s, short, int, CV_NOP ) 220 ICV_DEF_IN_RANGE_ALL( 32s, int, int, CV_NOP ) 221 ICV_DEF_IN_RANGE_ALL( 32f, float, float, CV_NOP ) 222 ICV_DEF_IN_RANGE_ALL( 64f, double, double, CV_NOP ) 223 224 #define icvInRange_8s_C1R 0 225 #define icvInRange_8s_C2R 0 226 #define icvInRange_8s_C3R 0 227 #define icvInRange_8s_C4R 0 228 229 #define icvInRangeC_8s_C1R 0 230 #define icvInRangeC_8s_C2R 0 231 #define icvInRangeC_8s_C3R 0 232 #define icvInRangeC_8s_C4R 0 233 234 CV_DEF_INIT_BIG_FUNC_TAB_2D( InRange, R ) 235 CV_DEF_INIT_BIG_FUNC_TAB_2D( InRangeC, R ) 236 237 typedef CvStatus (CV_STDCALL * CvInRangeCFunc)( const void* src, int srcstep, 238 uchar* dst, int dststep, 239 CvSize size, const void* scalar ); 240 241 /*************************************** InRange ****************************************/ 242 243 CV_IMPL void 244 cvInRange( const void* srcarr1, const void* srcarr2, 245 const void* srcarr3, void* dstarr ) 246 { 247 static CvBigFuncTable inrange_tab; 248 static int inittab = 0; 249 250 CV_FUNCNAME( "cvInRange" ); 251 252 __BEGIN__; 253 254 int type, coi = 0; 255 int src1_step, src2_step, src3_step, dst_step; 256 CvMat srcstub1, *src1 = (CvMat*)srcarr1; 257 CvMat srcstub2, *src2 = (CvMat*)srcarr2; 258 CvMat srcstub3, *src3 = (CvMat*)srcarr3; 259 CvMat dststub, *dst = (CvMat*)dstarr; 260 CvSize size; 261 CvFunc2D_4A func; 262 263 if( !inittab ) 264 { 265 icvInitInRangeRTable( &inrange_tab ); 266 inittab = 1; 267 } 268 269 if( !CV_IS_MAT(src1) ) 270 { 271 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi )); 272 if( coi != 0 ) 273 CV_ERROR( CV_BadCOI, "" ); 274 } 275 276 if( !CV_IS_MAT(src2) ) 277 { 278 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi )); 279 if( coi != 0 ) 280 CV_ERROR( CV_BadCOI, "" ); 281 } 282 283 if( !CV_IS_MAT(src3) ) 284 { 285 CV_CALL( src3 = cvGetMat( src3, &srcstub3, &coi )); 286 if( coi != 0 ) 287 CV_ERROR( CV_BadCOI, "" ); 288 } 289 290 if( !CV_IS_MAT(dst) ) 291 { 292 CV_CALL( dst = cvGetMat( dst, &dststub, &coi )); 293 if( coi != 0 ) 294 CV_ERROR( CV_BadCOI, "" ); 295 } 296 297 if( !CV_ARE_TYPES_EQ( src1, src2 ) || 298 !CV_ARE_TYPES_EQ( src1, src3 ) ) 299 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 300 301 if( !CV_IS_MASK_ARR( dst )) 302 CV_ERROR( CV_StsUnsupportedFormat, "Destination image should be 8uC1 or 8sC1"); 303 304 if( !CV_ARE_SIZES_EQ( src1, src2 ) || 305 !CV_ARE_SIZES_EQ( src1, src3 ) || 306 !CV_ARE_SIZES_EQ( src1, dst )) 307 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 308 309 type = CV_MAT_TYPE(src1->type); 310 size = cvGetMatSize( src1 ); 311 312 if( CV_IS_MAT_CONT( src1->type & src2->type & src3->type & dst->type )) 313 { 314 size.width *= size.height; 315 src1_step = src2_step = src3_step = dst_step = CV_STUB_STEP; 316 size.height = 1; 317 } 318 else 319 { 320 src1_step = src1->step; 321 src2_step = src2->step; 322 src3_step = src3->step; 323 dst_step = dst->step; 324 } 325 326 if( CV_MAT_CN(type) > 4 ) 327 CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); 328 329 func = (CvFunc2D_4A)(inrange_tab.fn_2d[type]); 330 331 if( !func ) 332 CV_ERROR( CV_StsUnsupportedFormat, "" ); 333 334 IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step, 335 src3->data.ptr, src3_step, dst->data.ptr, dst_step, size )); 336 337 __END__; 338 } 339 340 341 /************************************** InRangeS ****************************************/ 342 343 CV_IMPL void 344 cvInRangeS( const void* srcarr, CvScalar lower, CvScalar upper, void* dstarr ) 345 { 346 static CvBigFuncTable inrange_tab; 347 static int inittab = 0; 348 349 CV_FUNCNAME( "cvInRangeS" ); 350 351 __BEGIN__; 352 353 int sctype, type, coi = 0; 354 int src1_step, dst_step; 355 CvMat srcstub1, *src1 = (CvMat*)srcarr; 356 CvMat dststub, *dst = (CvMat*)dstarr; 357 CvSize size; 358 CvInRangeCFunc func; 359 double buf[8]; 360 361 if( !inittab ) 362 { 363 icvInitInRangeCRTable( &inrange_tab ); 364 inittab = 1; 365 } 366 367 if( !CV_IS_MAT(src1) ) 368 { 369 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi )); 370 if( coi != 0 ) 371 CV_ERROR( CV_BadCOI, "" ); 372 } 373 374 if( !CV_IS_MAT(dst) ) 375 { 376 CV_CALL( dst = cvGetMat( dst, &dststub, &coi )); 377 if( coi != 0 ) 378 CV_ERROR( CV_BadCOI, "" ); 379 } 380 381 if( !CV_IS_MASK_ARR( dst )) 382 CV_ERROR( CV_StsUnsupportedFormat, "Destination image should be 8uC1 or 8sC1"); 383 384 if( !CV_ARE_SIZES_EQ( src1, dst )) 385 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 386 387 sctype = type = CV_MAT_TYPE(src1->type); 388 if( CV_MAT_DEPTH(sctype) < CV_32S ) 389 sctype = (type & CV_MAT_CN_MASK) | CV_32SC1; 390 391 size = cvGetMatSize( src1 ); 392 393 if( CV_IS_MAT_CONT( src1->type & dst->type )) 394 { 395 size.width *= size.height; 396 src1_step = dst_step = CV_STUB_STEP; 397 size.height = 1; 398 } 399 else 400 { 401 src1_step = src1->step; 402 dst_step = dst->step; 403 } 404 405 if( CV_MAT_CN(type) > 4 ) 406 CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" ); 407 408 func = (CvInRangeCFunc)(inrange_tab.fn_2d[type]); 409 410 if( !func ) 411 CV_ERROR( CV_StsUnsupportedFormat, "" ); 412 413 cvScalarToRawData( &lower, buf, sctype, 0 ); 414 cvScalarToRawData( &upper, (char*)buf + CV_ELEM_SIZE(sctype), sctype, 0 ); 415 416 IPPI_CALL( func( src1->data.ptr, src1_step, dst->data.ptr, 417 dst_step, size, buf )); 418 419 __END__; 420 } 421 422 423 /****************************************************************************************\ 424 * Cmp * 425 \****************************************************************************************/ 426 427 #define ICV_DEF_CMP_CASE_C1( __op__, _toggle_macro_ ) \ 428 for( x = 0; x <= size.width - 4; x += 4 ) \ 429 { \ 430 int f0 = __op__( _toggle_macro_(src1[x]), _toggle_macro_(src2[x])); \ 431 int f1 = __op__( _toggle_macro_(src1[x+1]), _toggle_macro_(src2[x+1])); \ 432 dst[x] = (uchar)-f0; \ 433 dst[x+1] = (uchar)-f1; \ 434 f0 = __op__( _toggle_macro_(src1[x+2]), _toggle_macro_(src2[x+2])); \ 435 f1 = __op__( _toggle_macro_(src1[x+3]), _toggle_macro_(src2[x+3])); \ 436 dst[x+2] = (uchar)-f0; \ 437 dst[x+3] = (uchar)-f1; \ 438 } \ 439 \ 440 for( ; x < size.width; x++ ) \ 441 { \ 442 int f0 = __op__( _toggle_macro_(src1[x]), _toggle_macro_(src2[x])); \ 443 dst[x] = (uchar)-f0; \ 444 } 445 446 447 #define ICV_DEF_CMP_FUNC( __op__, name, flavor, arrtype, \ 448 worktype, _toggle_macro_ ) \ 449 static CvStatus CV_STDCALL \ 450 icv##name##_##flavor##_C1R( const arrtype* src1, int step1, \ 451 const arrtype* src2, int step2, \ 452 uchar* dst, int step, CvSize size ) \ 453 { \ 454 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); \ 455 step /= sizeof(dst[0]); \ 456 \ 457 for( ; size.height--; src1 += step1, src2 += step2, \ 458 dst += step ) \ 459 { \ 460 int x; \ 461 ICV_DEF_CMP_CASE_C1( __op__, _toggle_macro_ ) \ 462 } \ 463 \ 464 return CV_OK; \ 465 } 466 467 468 #define ICV_DEF_CMP_CONST_CASE_C1( __op__, _toggle_macro_ ) \ 469 for( x = 0; x <= size.width - 4; x += 4 ) \ 470 { \ 471 int f0 = __op__( _toggle_macro_(src1[x]), scalar ); \ 472 int f1 = __op__( _toggle_macro_(src1[x+1]), scalar ); \ 473 dst[x] = (uchar)-f0; \ 474 dst[x+1] = (uchar)-f1; \ 475 f0 = __op__( _toggle_macro_(src1[x+2]), scalar ); \ 476 f1 = __op__( _toggle_macro_(src1[x+3]), scalar ); \ 477 dst[x+2] = (uchar)-f0; \ 478 dst[x+3] = (uchar)-f1; \ 479 } \ 480 \ 481 for( ; x < size.width; x++ ) \ 482 { \ 483 int f0 = __op__( _toggle_macro_(src1[x]), scalar ); \ 484 dst[x] = (uchar)-f0; \ 485 } 486 487 488 #define ICV_DEF_CMP_CONST_FUNC( __op__, name, flavor, arrtype, \ 489 worktype, _toggle_macro_) \ 490 static CvStatus CV_STDCALL \ 491 icv##name##C_##flavor##_C1R( const arrtype* src1, int step1, \ 492 uchar* dst, int step, \ 493 CvSize size, worktype* pScalar ) \ 494 { \ 495 worktype scalar = *pScalar; \ 496 step1 /= sizeof(src1[0]); step /= sizeof(dst[0]); \ 497 \ 498 for( ; size.height--; src1 += step1, dst += step ) \ 499 { \ 500 int x; \ 501 ICV_DEF_CMP_CONST_CASE_C1( __op__, _toggle_macro_ ) \ 502 } \ 503 \ 504 return CV_OK; \ 505 } 506 507 508 #define ICV_DEF_CMP_ALL( flavor, arrtype, worktype, _toggle_macro_ ) \ 509 ICV_DEF_CMP_FUNC( CV_GT, CmpGT, flavor, arrtype, worktype, _toggle_macro_ ) \ 510 ICV_DEF_CMP_FUNC( CV_EQ, CmpEQ, flavor, arrtype, worktype, _toggle_macro_ ) \ 511 ICV_DEF_CMP_CONST_FUNC( CV_GT, CmpGT, flavor, arrtype, worktype, _toggle_macro_)\ 512 ICV_DEF_CMP_CONST_FUNC( CV_GE, CmpGE, flavor, arrtype, worktype, _toggle_macro_)\ 513 ICV_DEF_CMP_CONST_FUNC( CV_EQ, CmpEQ, flavor, arrtype, worktype, _toggle_macro_) 514 515 ICV_DEF_CMP_ALL( 8u, uchar, int, CV_NOP ) 516 ICV_DEF_CMP_ALL( 16u, ushort, int, CV_NOP ) 517 ICV_DEF_CMP_ALL( 16s, short, int, CV_NOP ) 518 ICV_DEF_CMP_ALL( 32s, int, int, CV_NOP ) 519 ICV_DEF_CMP_ALL( 32f, float, double, CV_NOP ) 520 ICV_DEF_CMP_ALL( 64f, double, double, CV_NOP ) 521 522 #define icvCmpGT_8s_C1R 0 523 #define icvCmpEQ_8s_C1R 0 524 #define icvCmpGTC_8s_C1R 0 525 #define icvCmpGEC_8s_C1R 0 526 #define icvCmpEQC_8s_C1R 0 527 528 CV_DEF_INIT_FUNC_TAB_2D( CmpGT, C1R ) 529 CV_DEF_INIT_FUNC_TAB_2D( CmpEQ, C1R ) 530 CV_DEF_INIT_FUNC_TAB_2D( CmpGTC, C1R ) 531 CV_DEF_INIT_FUNC_TAB_2D( CmpGEC, C1R ) 532 CV_DEF_INIT_FUNC_TAB_2D( CmpEQC, C1R ) 533 534 icvCompare_8u_C1R_t icvCompare_8u_C1R_p = 0; 535 icvCompare_16s_C1R_t icvCompare_16s_C1R_p = 0; 536 icvCompare_32f_C1R_t icvCompare_32f_C1R_p = 0; 537 538 icvCompareC_8u_C1R_t icvCompareC_8u_C1R_p = 0; 539 icvCompareC_16s_C1R_t icvCompareC_16s_C1R_p = 0; 540 icvCompareC_32f_C1R_t icvCompareC_32f_C1R_p = 0; 541 542 icvThreshold_GT_8u_C1R_t icvThreshold_GT_8u_C1R_p = 0; 543 icvThreshold_GT_16s_C1R_t icvThreshold_GT_16s_C1R_p = 0; 544 icvThreshold_GT_32f_C1R_t icvThreshold_GT_32f_C1R_p = 0; 545 546 icvThreshold_LT_8u_C1R_t icvThreshold_LT_8u_C1R_p = 0; 547 icvThreshold_LT_16s_C1R_t icvThreshold_LT_16s_C1R_p = 0; 548 icvThreshold_LT_32f_C1R_t icvThreshold_LT_32f_C1R_p = 0; 549 550 /***************************************** cvCmp ****************************************/ 551 552 CV_IMPL void 553 cvCmp( const void* srcarr1, const void* srcarr2, 554 void* dstarr, int cmp_op ) 555 { 556 static CvFuncTable cmp_tab[2]; 557 static int inittab = 0; 558 559 CV_FUNCNAME( "cvCmp" ); 560 561 __BEGIN__; 562 563 int type, coi = 0; 564 int invflag = 0; 565 CvCmpOp ipp_cmp_op; 566 int src1_step, src2_step, dst_step; 567 CvMat srcstub1, *src1 = (CvMat*)srcarr1; 568 CvMat srcstub2, *src2 = (CvMat*)srcarr2; 569 CvMat dststub, *dst = (CvMat*)dstarr; 570 CvMat *temp; 571 CvSize size; 572 CvFunc2D_3A func; 573 574 if( !inittab ) 575 { 576 icvInitCmpGTC1RTable( &cmp_tab[0] ); 577 icvInitCmpEQC1RTable( &cmp_tab[1] ); 578 inittab = 1; 579 } 580 581 if( !CV_IS_MAT(src1) ) 582 { 583 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi )); 584 if( coi != 0 ) 585 CV_ERROR( CV_BadCOI, "" ); 586 } 587 588 if( !CV_IS_MAT(src2) ) 589 { 590 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi )); 591 if( coi != 0 ) 592 CV_ERROR( CV_BadCOI, "" ); 593 } 594 595 if( !CV_IS_MAT(dst) ) 596 { 597 CV_CALL( dst = cvGetMat( dst, &dststub, &coi )); 598 if( coi != 0 ) 599 CV_ERROR( CV_BadCOI, "" ); 600 } 601 602 switch( cmp_op ) 603 { 604 case CV_CMP_GT: 605 case CV_CMP_EQ: 606 break; 607 case CV_CMP_GE: 608 CV_SWAP( src1, src2, temp ); 609 invflag = 1; 610 break; 611 case CV_CMP_LT: 612 CV_SWAP( src1, src2, temp ); 613 break; 614 case CV_CMP_LE: 615 invflag = 1; 616 break; 617 case CV_CMP_NE: 618 cmp_op = CV_CMP_EQ; 619 invflag = 1; 620 break; 621 default: 622 CV_ERROR( CV_StsBadArg, "Unknown comparison operation" ); 623 } 624 625 if( !CV_ARE_TYPES_EQ( src1, src2 ) ) 626 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 627 628 if( CV_MAT_CN( src1->type ) != 1 ) 629 CV_ERROR( CV_StsUnsupportedFormat, "Input arrays must be single-channel"); 630 631 if( !CV_IS_MASK_ARR( dst )) 632 CV_ERROR( CV_StsUnsupportedFormat, "Destination array should be 8uC1 or 8sC1"); 633 634 if( !CV_ARE_SIZES_EQ( src1, src2 ) || 635 !CV_ARE_SIZES_EQ( src1, dst )) 636 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 637 638 type = CV_MAT_TYPE(src1->type); 639 size = cvGetMatSize( src1 ); 640 641 if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type )) 642 { 643 size.width *= size.height; 644 src1_step = src2_step = dst_step = CV_STUB_STEP; 645 size.height = 1; 646 } 647 else 648 { 649 src1_step = src1->step; 650 src2_step = src2->step; 651 dst_step = dst->step; 652 } 653 654 func = (CvFunc2D_3A)(cmp_tab[cmp_op == CV_CMP_EQ].fn_2d[type]); 655 656 if( !func ) 657 CV_ERROR( CV_StsUnsupportedFormat, "" ); 658 659 ipp_cmp_op = cmp_op == CV_CMP_EQ ? cvCmpEq : cvCmpGreater; 660 661 if( type == CV_8U && icvCompare_8u_C1R_p ) 662 { 663 IPPI_CALL( icvCompare_8u_C1R_p( src1->data.ptr, src1_step, src2->data.ptr, 664 src2_step, dst->data.ptr, dst_step, size, ipp_cmp_op )); 665 } 666 else if( type == CV_16S && icvCompare_16s_C1R_p ) 667 { 668 IPPI_CALL( icvCompare_16s_C1R_p( src1->data.s, src1_step, src2->data.s, 669 src2_step, dst->data.s, dst_step, size, ipp_cmp_op )); 670 } 671 else if( type == CV_32F && icvCompare_32f_C1R_p ) 672 { 673 IPPI_CALL( icvCompare_32f_C1R_p( src1->data.fl, src1_step, src2->data.fl, 674 src2_step, dst->data.fl, dst_step, size, ipp_cmp_op )); 675 } 676 else 677 { 678 IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step, 679 dst->data.ptr, dst_step, size )); 680 } 681 682 if( invflag ) 683 IPPI_CALL( icvNot_8u_C1R( dst->data.ptr, dst_step, 684 dst->data.ptr, dst_step, size )); 685 686 __END__; 687 } 688 689 690 /*************************************** cvCmpS *****************************************/ 691 692 CV_IMPL void 693 cvCmpS( const void* srcarr, double value, void* dstarr, int cmp_op ) 694 { 695 static CvFuncTable cmps_tab[3]; 696 static int inittab = 0; 697 698 CV_FUNCNAME( "cvCmpS" ); 699 700 __BEGIN__; 701 702 int y, type, coi = 0; 703 int invflag = 0, ipp_cmp_op; 704 int src1_step, dst_step; 705 CvMat srcstub1, *src1 = (CvMat*)srcarr; 706 CvMat dststub, *dst = (CvMat*)dstarr; 707 CvSize size; 708 int ival = 0; 709 710 if( !inittab ) 711 { 712 icvInitCmpEQCC1RTable( &cmps_tab[CV_CMP_EQ] ); 713 icvInitCmpGTCC1RTable( &cmps_tab[CV_CMP_GT] ); 714 icvInitCmpGECC1RTable( &cmps_tab[CV_CMP_GE] ); 715 inittab = 1; 716 } 717 718 if( !CV_IS_MAT(src1) ) 719 { 720 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi )); 721 if( coi != 0 ) 722 CV_ERROR( CV_BadCOI, "" ); 723 } 724 725 if( !CV_IS_MAT(dst) ) 726 { 727 CV_CALL( dst = cvGetMat( dst, &dststub, &coi )); 728 if( coi != 0 ) 729 CV_ERROR( CV_BadCOI, "" ); 730 } 731 732 switch( cmp_op ) 733 { 734 case CV_CMP_GT: 735 case CV_CMP_EQ: 736 case CV_CMP_GE: 737 break; 738 case CV_CMP_LT: 739 invflag = 1; 740 cmp_op = CV_CMP_GE; 741 break; 742 case CV_CMP_LE: 743 invflag = 1; 744 cmp_op = CV_CMP_GT; 745 break; 746 case CV_CMP_NE: 747 invflag = 1; 748 cmp_op = CV_CMP_EQ; 749 break; 750 default: 751 CV_ERROR( CV_StsBadArg, "Unknown comparison operation" ); 752 } 753 754 if( !CV_IS_MASK_ARR( dst )) 755 CV_ERROR( CV_StsUnsupportedFormat, "Destination array should be 8uC1 or 8sC1"); 756 757 if( CV_MAT_CN( src1->type ) != 1 ) 758 CV_ERROR( CV_StsUnsupportedFormat, "Input array must be single-channel"); 759 760 if( !CV_ARE_SIZES_EQ( src1, dst )) 761 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 762 763 type = CV_MAT_TYPE(src1->type); 764 size = cvGetMatSize( src1 ); 765 766 if( CV_IS_MAT_CONT( src1->type & dst->type )) 767 { 768 size.width *= size.height; 769 src1_step = dst_step = CV_STUB_STEP; 770 size.height = 1; 771 } 772 else 773 { 774 src1_step = src1->step; 775 dst_step = dst->step; 776 } 777 778 if( CV_MAT_DEPTH(type) <= CV_32S ) 779 { 780 ival = cvRound(value); 781 if( type == CV_8U || type == CV_16S ) 782 { 783 int minval = type == CV_8U ? 0 : -32768; 784 int maxval = type == CV_8U ? 255 : 32767; 785 int fillval = -1; 786 if( ival < minval ) 787 fillval = cmp_op == CV_CMP_NE || cmp_op == CV_CMP_GE || cmp_op == CV_CMP_GT ? 255 : 0; 788 else if( ival > maxval ) 789 fillval = cmp_op == CV_CMP_NE || cmp_op == CV_CMP_LE || cmp_op == CV_CMP_LT ? 255 : 0; 790 if( fillval >= 0 ) 791 { 792 fillval ^= invflag ? 255 : 0; 793 for( y = 0; y < size.height; y++ ) 794 memset( dst->data.ptr + y*dst_step, fillval, size.width ); 795 EXIT; 796 } 797 } 798 } 799 800 ipp_cmp_op = cmp_op == CV_CMP_EQ ? cvCmpEq : 801 cmp_op == CV_CMP_GE ? cvCmpGreaterEq : cvCmpGreater; 802 if( type == CV_8U && icvCompare_8u_C1R_p ) 803 { 804 IPPI_CALL( icvCompareC_8u_C1R_p( src1->data.ptr, src1_step, (uchar)ival, 805 dst->data.ptr, dst_step, size, ipp_cmp_op )); 806 } 807 else if( type == CV_16S && icvCompare_16s_C1R_p ) 808 { 809 IPPI_CALL( icvCompareC_16s_C1R_p( src1->data.s, src1_step, (short)ival, 810 dst->data.s, dst_step, size, ipp_cmp_op )); 811 } 812 else if( type == CV_32F && icvCompare_32f_C1R_p ) 813 { 814 IPPI_CALL( icvCompareC_32f_C1R_p( src1->data.fl, src1_step, (float)value, 815 dst->data.fl, dst_step, size, ipp_cmp_op )); 816 } 817 else 818 { 819 CvFunc2D_2A1P func = (CvFunc2D_2A1P)(cmps_tab[cmp_op].fn_2d[type]); 820 if( !func ) 821 CV_ERROR( CV_StsUnsupportedFormat, "" ); 822 823 if( type <= CV_32S ) 824 { 825 IPPI_CALL( func( src1->data.ptr, src1_step, dst->data.ptr, 826 dst_step, size, &ival )); 827 } 828 else 829 { 830 IPPI_CALL( func( src1->data.ptr, src1_step, dst->data.ptr, 831 dst_step, size, &value )); 832 } 833 } 834 835 if( invflag ) 836 IPPI_CALL( icvNot_8u_C1R( dst->data.ptr, dst_step, 837 dst->data.ptr, dst_step, size )); 838 839 __END__; 840 } 841 842 843 /****************************************************************************************\ 844 * Min/Max * 845 \****************************************************************************************/ 846 847 848 #define ICV_DEF_MINMAX_FUNC( __op__, name, flavor, arrtype, \ 849 worktype, _toggle_macro_ ) \ 850 static CvStatus CV_STDCALL \ 851 icv##name##_##flavor##_C1R( const arrtype* src1, int step1, \ 852 const arrtype* src2, int step2, \ 853 arrtype* dst, int step, CvSize size ) \ 854 { \ 855 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); \ 856 step /= sizeof(dst[0]); \ 857 \ 858 for( ; size.height--; src1 += step1, \ 859 src2 += step2, dst += step ) \ 860 { \ 861 int x; \ 862 for( x = 0; x <= size.width - 4; x += 4 ) \ 863 { \ 864 worktype a0 = _toggle_macro_(src1[x]); \ 865 worktype b0 = _toggle_macro_(src2[x]); \ 866 worktype a1 = _toggle_macro_(src1[x+1]); \ 867 worktype b1 = _toggle_macro_(src2[x+1]); \ 868 a0 = __op__( a0, b0 ); \ 869 a1 = __op__( a1, b1 ); \ 870 dst[x] = (arrtype)_toggle_macro_(a0); \ 871 dst[x+1] = (arrtype)_toggle_macro_(a1); \ 872 a0 = _toggle_macro_(src1[x+2]); \ 873 b0 = _toggle_macro_(src2[x+2]); \ 874 a1 = _toggle_macro_(src1[x+3]); \ 875 b1 = _toggle_macro_(src2[x+3]); \ 876 a0 = __op__( a0, b0 ); \ 877 a1 = __op__( a1, b1 ); \ 878 dst[x+2] = (arrtype)_toggle_macro_(a0); \ 879 dst[x+3] = (arrtype)_toggle_macro_(a1); \ 880 } \ 881 \ 882 for( ; x < size.width; x++ ) \ 883 { \ 884 worktype a0 = _toggle_macro_(src1[x]); \ 885 worktype b0 = _toggle_macro_(src2[x]); \ 886 a0 = __op__( a0, b0 ); \ 887 dst[x] = (arrtype)_toggle_macro_(a0); \ 888 } \ 889 } \ 890 \ 891 return CV_OK; \ 892 } 893 894 895 #define ICV_DEF_MINMAX_CONST_FUNC( __op__, name, \ 896 flavor, arrtype, worktype, _toggle_macro_) \ 897 static CvStatus CV_STDCALL \ 898 icv##name##C_##flavor##_C1R( const arrtype* src1, int step1,\ 899 arrtype* dst, int step, \ 900 CvSize size, worktype* pScalar)\ 901 { \ 902 worktype scalar = _toggle_macro_(*pScalar); \ 903 step1 /= sizeof(src1[0]); step /= sizeof(dst[0]); \ 904 \ 905 for( ; size.height--; src1 += step1, dst += step ) \ 906 { \ 907 int x; \ 908 for( x = 0; x <= size.width - 4; x += 4 ) \ 909 { \ 910 worktype a0 = _toggle_macro_(src1[x]); \ 911 worktype a1 = _toggle_macro_(src1[x+1]); \ 912 a0 = __op__( a0, scalar ); \ 913 a1 = __op__( a1, scalar ); \ 914 dst[x] = (arrtype)_toggle_macro_(a0); \ 915 dst[x+1] = (arrtype)_toggle_macro_(a1); \ 916 a0 = _toggle_macro_(src1[x+2]); \ 917 a1 = _toggle_macro_(src1[x+3]); \ 918 a0 = __op__( a0, scalar ); \ 919 a1 = __op__( a1, scalar ); \ 920 dst[x+2] = (arrtype)_toggle_macro_(a0); \ 921 dst[x+3] = (arrtype)_toggle_macro_(a1); \ 922 } \ 923 \ 924 for( ; x < size.width; x++ ) \ 925 { \ 926 worktype a0 = _toggle_macro_(src1[x]); \ 927 a0 = __op__( a0, scalar ); \ 928 dst[x] = (arrtype)_toggle_macro_(a0); \ 929 } \ 930 } \ 931 \ 932 return CV_OK; \ 933 } 934 935 936 #define ICV_DEF_MINMAX_ALL( flavor, arrtype, worktype, \ 937 _toggle_macro_, _min_op_, _max_op_ ) \ 938 ICV_DEF_MINMAX_FUNC( _min_op_, Min, flavor, arrtype, worktype, _toggle_macro_ ) \ 939 ICV_DEF_MINMAX_FUNC( _max_op_, Max, flavor, arrtype, worktype, _toggle_macro_ ) \ 940 ICV_DEF_MINMAX_CONST_FUNC(_min_op_, Min, flavor, arrtype, worktype, _toggle_macro_)\ 941 ICV_DEF_MINMAX_CONST_FUNC(_max_op_, Max, flavor, arrtype, worktype, _toggle_macro_) 942 943 ICV_DEF_MINMAX_ALL( 8u, uchar, int, CV_NOP, CV_MIN_8U, CV_MAX_8U ) 944 ICV_DEF_MINMAX_ALL( 16u, ushort, int, CV_NOP, CV_IMIN, CV_IMAX ) 945 ICV_DEF_MINMAX_ALL( 16s, short, int, CV_NOP, CV_IMIN, CV_IMAX ) 946 ICV_DEF_MINMAX_ALL( 32s, int, int, CV_NOP, CV_IMIN, CV_IMAX ) 947 ICV_DEF_MINMAX_ALL( 32f, int, int, CV_TOGGLE_FLT, CV_IMIN, CV_IMAX ) 948 ICV_DEF_MINMAX_ALL( 64f, double, double, CV_NOP, MIN, MAX ) 949 950 #define icvMin_8s_C1R 0 951 #define icvMax_8s_C1R 0 952 #define icvMinC_8s_C1R 0 953 #define icvMaxC_8s_C1R 0 954 955 CV_DEF_INIT_FUNC_TAB_2D( Min, C1R ) 956 CV_DEF_INIT_FUNC_TAB_2D( Max, C1R ) 957 CV_DEF_INIT_FUNC_TAB_2D( MinC, C1R ) 958 CV_DEF_INIT_FUNC_TAB_2D( MaxC, C1R ) 959 960 /*********************************** cvMin & cvMax **************************************/ 961 962 static void 963 icvMinMax( const void* srcarr1, const void* srcarr2, 964 void* dstarr, int is_max ) 965 { 966 static CvFuncTable minmax_tab[2]; 967 static int inittab = 0; 968 969 CV_FUNCNAME( "icvMinMax" ); 970 971 __BEGIN__; 972 973 int type, coi = 0; 974 int src1_step, src2_step, dst_step; 975 CvMat srcstub1, *src1 = (CvMat*)srcarr1; 976 CvMat srcstub2, *src2 = (CvMat*)srcarr2; 977 CvMat dststub, *dst = (CvMat*)dstarr; 978 CvSize size; 979 CvFunc2D_3A func; 980 981 if( !inittab ) 982 { 983 icvInitMinC1RTable( &minmax_tab[0] ); 984 icvInitMaxC1RTable( &minmax_tab[1] ); 985 inittab = 1; 986 } 987 988 if( !CV_IS_MAT(src1) ) 989 { 990 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi )); 991 if( coi != 0 ) 992 CV_ERROR( CV_BadCOI, "" ); 993 } 994 995 if( !CV_IS_MAT(src2) ) 996 { 997 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi )); 998 if( coi != 0 ) 999 CV_ERROR( CV_BadCOI, "" ); 1000 } 1001 1002 if( !CV_IS_MAT(dst) ) 1003 { 1004 CV_CALL( dst = cvGetMat( dst, &dststub, &coi )); 1005 if( coi != 0 ) 1006 CV_ERROR( CV_BadCOI, "" ); 1007 } 1008 1009 if( !CV_ARE_TYPES_EQ( src1, src2 ) || 1010 !CV_ARE_TYPES_EQ( src1, dst )) 1011 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 1012 1013 if( CV_MAT_CN( src1->type ) != 1 ) 1014 CV_ERROR( CV_StsUnsupportedFormat, "Input arrays must be single-channel"); 1015 1016 if( !CV_ARE_SIZES_EQ( src1, src2 ) || 1017 !CV_ARE_SIZES_EQ( src1, dst )) 1018 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 1019 1020 type = CV_MAT_TYPE(src1->type); 1021 size = cvGetMatSize( src1 ); 1022 1023 if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type )) 1024 { 1025 size.width *= size.height; 1026 src1_step = src2_step = dst_step = CV_STUB_STEP; 1027 size.height = 1; 1028 } 1029 else 1030 { 1031 src1_step = src1->step; 1032 src2_step = src2->step; 1033 dst_step = dst->step; 1034 } 1035 1036 func = (CvFunc2D_3A)(minmax_tab[is_max != 0].fn_2d[type]); 1037 1038 if( !func ) 1039 CV_ERROR( CV_StsUnsupportedFormat, "" ); 1040 1041 IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step, 1042 dst->data.ptr, dst_step, size )); 1043 1044 __END__; 1045 } 1046 1047 1048 CV_IMPL void 1049 cvMin( const void* srcarr1, const void* srcarr2, void* dstarr ) 1050 { 1051 icvMinMax( srcarr1, srcarr2, dstarr, 0 ); 1052 } 1053 1054 1055 CV_IMPL void 1056 cvMax( const void* srcarr1, const void* srcarr2, void* dstarr ) 1057 { 1058 icvMinMax( srcarr1, srcarr2, dstarr, 1 ); 1059 } 1060 1061 1062 /********************************* cvMinS / cvMaxS **************************************/ 1063 1064 static void 1065 icvMinMaxS( const void* srcarr, double value, void* dstarr, int is_max ) 1066 { 1067 static CvFuncTable minmaxs_tab[2]; 1068 static int inittab = 0; 1069 1070 CV_FUNCNAME( "icvMinMaxS" ); 1071 1072 __BEGIN__; 1073 1074 int type, coi = 0; 1075 int src1_step, dst_step; 1076 CvMat srcstub1, *src1 = (CvMat*)srcarr; 1077 CvMat dststub, *dst = (CvMat*)dstarr; 1078 CvSize size; 1079 CvFunc2D_2A1P func; 1080 union 1081 { 1082 int i; 1083 float f; 1084 double d; 1085 } 1086 buf; 1087 1088 if( !inittab ) 1089 { 1090 icvInitMinCC1RTable( &minmaxs_tab[0] ); 1091 icvInitMaxCC1RTable( &minmaxs_tab[1] ); 1092 inittab = 1; 1093 } 1094 1095 if( !CV_IS_MAT(src1) ) 1096 { 1097 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi )); 1098 if( coi != 0 ) 1099 CV_ERROR( CV_BadCOI, "" ); 1100 } 1101 1102 if( !CV_IS_MAT(dst) ) 1103 { 1104 CV_CALL( dst = cvGetMat( dst, &dststub, &coi )); 1105 if( coi != 0 ) 1106 CV_ERROR( CV_BadCOI, "" ); 1107 } 1108 1109 if( !CV_ARE_TYPES_EQ( src1, dst )) 1110 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 1111 1112 if( CV_MAT_CN( src1->type ) != 1 ) 1113 CV_ERROR( CV_StsUnsupportedFormat, "Input array must be single-channel"); 1114 1115 if( !CV_ARE_SIZES_EQ( src1, dst )) 1116 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 1117 1118 type = CV_MAT_TYPE(src1->type); 1119 1120 if( CV_MAT_DEPTH(type) <= CV_32S ) 1121 { 1122 buf.i = cvRound(value); 1123 if( CV_MAT_DEPTH(type) == CV_8U ) 1124 buf.i = CV_CAST_8U(buf.i); 1125 else if( CV_MAT_DEPTH(type) == CV_8S ) 1126 buf.i = CV_CAST_8S(buf.i); 1127 else if( CV_MAT_DEPTH(type) == CV_16U ) 1128 buf.i = CV_CAST_16U(buf.i); 1129 else if( CV_MAT_DEPTH(type) == CV_16S ) 1130 buf.i = CV_CAST_16S(buf.i); 1131 } 1132 else if( CV_MAT_DEPTH(type) == CV_32F ) 1133 buf.f = (float)value; 1134 else 1135 buf.d = value; 1136 1137 size = cvGetMatSize( src1 ); 1138 1139 if( CV_IS_MAT_CONT( src1->type & dst->type )) 1140 { 1141 size.width *= size.height; 1142 src1_step = dst_step = CV_STUB_STEP; 1143 size.height = 1; 1144 } 1145 else 1146 { 1147 src1_step = src1->step; 1148 dst_step = dst->step; 1149 } 1150 1151 func = (CvFunc2D_2A1P)(minmaxs_tab[is_max].fn_2d[type]); 1152 1153 if( !func ) 1154 CV_ERROR( CV_StsUnsupportedFormat, "" ); 1155 1156 if( is_max ) 1157 { 1158 if( type == CV_8U && icvThreshold_LT_8u_C1R_p ) 1159 { 1160 IPPI_CALL( icvThreshold_LT_8u_C1R_p( src1->data.ptr, src1_step, dst->data.ptr, 1161 dst_step, size, (uchar)buf.i )); 1162 EXIT; 1163 } 1164 else if( type == CV_16S && icvThreshold_LT_16s_C1R_p ) 1165 { 1166 IPPI_CALL( icvThreshold_LT_16s_C1R_p( src1->data.s, src1_step, dst->data.s, 1167 dst_step, size, (short)buf.i )); 1168 EXIT; 1169 } 1170 else if( type == CV_32F && icvThreshold_LT_32f_C1R_p ) 1171 { 1172 IPPI_CALL( icvThreshold_LT_32f_C1R_p( src1->data.fl, src1_step, dst->data.fl, 1173 dst_step, size, buf.f )); 1174 EXIT; 1175 } 1176 } 1177 else 1178 { 1179 if( type == CV_8U && icvThreshold_GT_8u_C1R_p ) 1180 { 1181 IPPI_CALL( icvThreshold_GT_8u_C1R_p( src1->data.ptr, src1_step, dst->data.ptr, 1182 dst_step, size, (uchar)buf.i )); 1183 EXIT; 1184 } 1185 else if( type == CV_16S && icvThreshold_GT_16s_C1R_p ) 1186 { 1187 IPPI_CALL( icvThreshold_GT_16s_C1R_p( src1->data.s, src1_step, dst->data.s, 1188 dst_step, size, (short)buf.i )); 1189 EXIT; 1190 } 1191 else if( type == CV_32F && icvThreshold_GT_32f_C1R_p ) 1192 { 1193 IPPI_CALL( icvThreshold_GT_32f_C1R_p( src1->data.fl, src1_step, dst->data.fl, 1194 dst_step, size, buf.f )); 1195 EXIT; 1196 } 1197 } 1198 1199 if( type == CV_8U && size.width*size.height >= 1024 ) 1200 { 1201 int i; 1202 uchar tab[256]; 1203 CvMat _tab = cvMat( 1, 256, CV_8U, tab ); 1204 1205 if( is_max ) 1206 { 1207 for( i = 0; i < buf.i; i++ ) 1208 tab[i] = (uchar)buf.i; 1209 for( ; i < 256; i++ ) 1210 tab[i] = (uchar)i; 1211 } 1212 else 1213 { 1214 for( i = 0; i < buf.i; i++ ) 1215 tab[i] = (uchar)i; 1216 for( ; i < 256; i++ ) 1217 tab[i] = (uchar)buf.i; 1218 } 1219 1220 cvLUT( src1, dst, &_tab ); 1221 EXIT; 1222 } 1223 1224 IPPI_CALL( func( src1->data.ptr, src1_step, dst->data.ptr, 1225 dst_step, size, &buf )); 1226 1227 __END__; 1228 } 1229 1230 1231 CV_IMPL void 1232 cvMinS( const void* srcarr, double value, void* dstarr ) 1233 { 1234 icvMinMaxS( srcarr, value, dstarr, 0 ); 1235 } 1236 1237 1238 CV_IMPL void 1239 cvMaxS( const void* srcarr, double value, void* dstarr ) 1240 { 1241 icvMinMaxS( srcarr, value, dstarr, 1 ); 1242 } 1243 1244 1245 /****************************************************************************************\ 1246 * Absolute Difference * 1247 \****************************************************************************************/ 1248 1249 #define ICV_DEF_BIN_ABS_DIFF_2D(name, arrtype, temptype, abs_macro, cast_macro)\ 1250 IPCVAPI_IMPL( CvStatus, \ 1251 name,( const arrtype* src1, int step1, \ 1252 const arrtype* src2, int step2, \ 1253 arrtype* dst, int step, CvSize size ), \ 1254 (src1, step1, src2, step2, dst, step, size)) \ 1255 { \ 1256 step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]); \ 1257 step /= sizeof(dst[0]); \ 1258 \ 1259 for( ; size.height--; src1 += step1, src2 += step2, \ 1260 dst += step ) \ 1261 { \ 1262 int i; \ 1263 \ 1264 for( i = 0; i <= size.width - 4; i += 4 ) \ 1265 { \ 1266 temptype t0 = src1[i] - src2[i]; \ 1267 temptype t1 = src1[i+1] - src2[i+1]; \ 1268 \ 1269 t0 = (temptype)abs_macro(t0); \ 1270 t1 = (temptype)abs_macro(t1); \ 1271 \ 1272 dst[i] = cast_macro(t0); \ 1273 dst[i+1] = cast_macro(t1); \ 1274 \ 1275 t0 = src1[i+2] - src2[i+2]; \ 1276 t1 = src1[i+3] - src2[i+3]; \ 1277 \ 1278 t0 = (temptype)abs_macro(t0); \ 1279 t1 = (temptype)abs_macro(t1); \ 1280 \ 1281 dst[i+2] = cast_macro(t0); \ 1282 dst[i+3] = cast_macro(t1); \ 1283 } \ 1284 \ 1285 for( ; i < size.width; i++ ) \ 1286 { \ 1287 temptype t0 = src1[i] - src2[i]; \ 1288 t0 = (temptype)abs_macro(t0); \ 1289 dst[i] = cast_macro(t0); \ 1290 } \ 1291 } \ 1292 \ 1293 return CV_OK; \ 1294 } 1295 1296 1297 #define ICV_DEF_UN_ABS_DIFF_2D( name, arrtype, temptype, abs_macro, cast_macro)\ 1298 static CvStatus CV_STDCALL \ 1299 name( const arrtype* src0, int step1, \ 1300 arrtype* dst0, int step, \ 1301 CvSize size, const temptype* scalar ) \ 1302 { \ 1303 step1 /= sizeof(src0[0]); step /= sizeof(dst0[0]); \ 1304 \ 1305 for( ; size.height--; src0 += step1, dst0 += step ) \ 1306 { \ 1307 int i, len = size.width; \ 1308 const arrtype* src = src0; \ 1309 arrtype* dst = dst0; \ 1310 \ 1311 for( ; (len -= 12) >= 0; dst += 12, src += 12 ) \ 1312 { \ 1313 temptype t0 = src[0] - scalar[0]; \ 1314 temptype t1 = src[1] - scalar[1]; \ 1315 \ 1316 t0 = (temptype)abs_macro(t0); \ 1317 t1 = (temptype)abs_macro(t1); \ 1318 \ 1319 dst[0] = cast_macro( t0 ); \ 1320 dst[1] = cast_macro( t1 ); \ 1321 \ 1322 t0 = src[2] - scalar[2]; \ 1323 t1 = src[3] - scalar[3]; \ 1324 \ 1325 t0 = (temptype)abs_macro(t0); \ 1326 t1 = (temptype)abs_macro(t1); \ 1327 \ 1328 dst[2] = cast_macro( t0 ); \ 1329 dst[3] = cast_macro( t1 ); \ 1330 \ 1331 t0 = src[4] - scalar[4]; \ 1332 t1 = src[5] - scalar[5]; \ 1333 \ 1334 t0 = (temptype)abs_macro(t0); \ 1335 t1 = (temptype)abs_macro(t1); \ 1336 \ 1337 dst[4] = cast_macro( t0 ); \ 1338 dst[5] = cast_macro( t1 ); \ 1339 \ 1340 t0 = src[6] - scalar[6]; \ 1341 t1 = src[7] - scalar[7]; \ 1342 \ 1343 t0 = (temptype)abs_macro(t0); \ 1344 t1 = (temptype)abs_macro(t1); \ 1345 \ 1346 dst[6] = cast_macro( t0 ); \ 1347 dst[7] = cast_macro( t1 ); \ 1348 \ 1349 t0 = src[8] - scalar[8]; \ 1350 t1 = src[9] - scalar[9]; \ 1351 \ 1352 t0 = (temptype)abs_macro(t0); \ 1353 t1 = (temptype)abs_macro(t1); \ 1354 \ 1355 dst[8] = cast_macro( t0 ); \ 1356 dst[9] = cast_macro( t1 ); \ 1357 \ 1358 t0 = src[10] - scalar[10]; \ 1359 t1 = src[11] - scalar[11]; \ 1360 \ 1361 t0 = (temptype)abs_macro(t0); \ 1362 t1 = (temptype)abs_macro(t1); \ 1363 \ 1364 dst[10] = cast_macro( t0 ); \ 1365 dst[11] = cast_macro( t1 ); \ 1366 } \ 1367 \ 1368 for( (len) += 12, i = 0; i < (len); i++ ) \ 1369 { \ 1370 temptype t0 = src[i] - scalar[i]; \ 1371 t0 = (temptype)abs_macro(t0); \ 1372 dst[i] = cast_macro( t0 ); \ 1373 } \ 1374 } \ 1375 \ 1376 return CV_OK; \ 1377 } 1378 1379 1380 #define ICV_TO_8U(x) ((uchar)(x)) 1381 #define ICV_TO_16U(x) ((ushort)(x)) 1382 1383 ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_8u_C1R, uchar, int, CV_IABS, ICV_TO_8U ) 1384 ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_16u_C1R, ushort, int, CV_IABS, ICV_TO_16U ) 1385 ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_16s_C1R, short, int, CV_IABS, CV_CAST_16S ) 1386 ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_32s_C1R, int, int, CV_IABS, CV_CAST_32S ) 1387 ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_32f_C1R, float, float, fabs, CV_CAST_32F ) 1388 ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_64f_C1R, double, double, fabs, CV_CAST_64F ) 1389 1390 ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_8u_CnR, uchar, int, CV_IABS, CV_CAST_8U ) 1391 ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_16u_CnR, ushort, int, CV_IABS, CV_CAST_16U ) 1392 ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_16s_CnR, short, int, CV_IABS, CV_CAST_16S ) 1393 ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_32s_CnR, int, int, CV_IABS, CV_CAST_32S ) 1394 ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_32f_CnR, float, float, fabs, CV_CAST_32F ) 1395 ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_64f_CnR, double, double, fabs, CV_CAST_64F ) 1396 1397 1398 #define ICV_INIT_MINI_FUNC_TAB_2D( FUNCNAME, suffix ) \ 1399 static void icvInit##FUNCNAME##Table( CvFuncTable* tab ) \ 1400 { \ 1401 tab->fn_2d[CV_8U] = (void*)icv##FUNCNAME##_8u_##suffix; \ 1402 tab->fn_2d[CV_16U] = (void*)icv##FUNCNAME##_16u_##suffix; \ 1403 tab->fn_2d[CV_16S] = (void*)icv##FUNCNAME##_16s_##suffix; \ 1404 tab->fn_2d[CV_32S] = (void*)icv##FUNCNAME##_32s_##suffix; \ 1405 tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_##suffix; \ 1406 tab->fn_2d[CV_64F] = (void*)icv##FUNCNAME##_64f_##suffix; \ 1407 } 1408 1409 1410 ICV_INIT_MINI_FUNC_TAB_2D( AbsDiff, C1R ) 1411 ICV_INIT_MINI_FUNC_TAB_2D( AbsDiffC, CnR ) 1412 1413 1414 CV_IMPL void 1415 cvAbsDiff( const void* srcarr1, const void* srcarr2, void* dstarr ) 1416 { 1417 static CvFuncTable adiff_tab; 1418 static int inittab = 0; 1419 1420 CV_FUNCNAME( "cvAbsDiff" ); 1421 1422 __BEGIN__; 1423 1424 int coi1 = 0, coi2 = 0, coi3 = 0; 1425 CvMat srcstub1, *src1 = (CvMat*)srcarr1; 1426 CvMat srcstub2, *src2 = (CvMat*)srcarr2; 1427 CvMat dststub, *dst = (CvMat*)dstarr; 1428 int src1_step, src2_step, dst_step; 1429 CvSize size; 1430 int type; 1431 1432 if( !inittab ) 1433 { 1434 icvInitAbsDiffTable( &adiff_tab ); 1435 inittab = 1; 1436 } 1437 1438 CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi1 )); 1439 CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi2 )); 1440 CV_CALL( dst = cvGetMat( dst, &dststub, &coi3 )); 1441 1442 if( coi1 != 0 || coi2 != 0 || coi3 != 0 ) 1443 CV_ERROR( CV_BadCOI, "" ); 1444 1445 if( !CV_ARE_SIZES_EQ( src1, src2 ) ) 1446 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 1447 1448 size = cvGetMatSize( src1 ); 1449 type = CV_MAT_TYPE(src1->type); 1450 1451 if( !CV_ARE_SIZES_EQ( src1, dst )) 1452 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 1453 1454 if( !CV_ARE_TYPES_EQ( src1, src2 )) 1455 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 1456 1457 if( !CV_ARE_TYPES_EQ( src1, dst )) 1458 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 1459 1460 size.width *= CV_MAT_CN( type ); 1461 1462 src1_step = src1->step; 1463 src2_step = src2->step; 1464 dst_step = dst->step; 1465 1466 if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type )) 1467 { 1468 size.width *= size.height; 1469 size.height = 1; 1470 src1_step = src2_step = dst_step = CV_STUB_STEP; 1471 } 1472 1473 { 1474 CvFunc2D_3A func = (CvFunc2D_3A) 1475 (adiff_tab.fn_2d[CV_MAT_DEPTH(type)]); 1476 1477 if( !func ) 1478 CV_ERROR( CV_StsUnsupportedFormat, "" ); 1479 1480 IPPI_CALL( func( src1->data.ptr, src1_step, src2->data.ptr, src2_step, 1481 dst->data.ptr, dst_step, size )); 1482 } 1483 1484 __END__; 1485 } 1486 1487 1488 CV_IMPL void 1489 cvAbsDiffS( const void* srcarr, void* dstarr, CvScalar scalar ) 1490 { 1491 static CvFuncTable adiffs_tab; 1492 static int inittab = 0; 1493 1494 CV_FUNCNAME( "cvAbsDiffS" ); 1495 1496 __BEGIN__; 1497 1498 int coi1 = 0, coi2 = 0; 1499 int type, sctype; 1500 CvMat srcstub, *src = (CvMat*)srcarr; 1501 CvMat dststub, *dst = (CvMat*)dstarr; 1502 int src_step, dst_step; 1503 double buf[12]; 1504 CvSize size; 1505 1506 if( !inittab ) 1507 { 1508 icvInitAbsDiffCTable( &adiffs_tab ); 1509 inittab = 1; 1510 } 1511 1512 CV_CALL( src = cvGetMat( src, &srcstub, &coi1 )); 1513 CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 )); 1514 1515 if( coi1 != 0 || coi2 != 0 ) 1516 CV_ERROR( CV_BadCOI, "" ); 1517 1518 if( !CV_ARE_TYPES_EQ(src, dst) ) 1519 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats ); 1520 1521 if( !CV_ARE_SIZES_EQ(src, dst) ) 1522 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes ); 1523 1524 sctype = type = CV_MAT_TYPE( src->type ); 1525 if( CV_MAT_DEPTH(type) < CV_32S ) 1526 sctype = (type & CV_MAT_CN_MASK) | CV_32SC1; 1527 1528 size = cvGetMatSize( src ); 1529 size.width *= CV_MAT_CN( type ); 1530 1531 src_step = src->step; 1532 dst_step = dst->step; 1533 1534 if( CV_IS_MAT_CONT( src->type & dst->type )) 1535 { 1536 size.width *= size.height; 1537 size.height = 1; 1538 src_step = dst_step = CV_STUB_STEP; 1539 } 1540 1541 CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 1 )); 1542 1543 { 1544 CvFunc2D_2A1P func = (CvFunc2D_2A1P) 1545 (adiffs_tab.fn_2d[CV_MAT_DEPTH(type)]); 1546 1547 if( !func ) 1548 CV_ERROR( CV_StsUnsupportedFormat, "" ); 1549 1550 IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr, 1551 dst_step, size, buf )); 1552 } 1553 1554 __END__; 1555 } 1556 1557 /* End of file. */ 1558