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
cvInRange(const void * srcarr1,const void * srcarr2,const void * srcarr3,void * dstarr)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
cvInRangeS(const void * srcarr,CvScalar lower,CvScalar upper,void * dstarr)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
cvCmp(const void * srcarr1,const void * srcarr2,void * dstarr,int cmp_op)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
cvCmpS(const void * srcarr,double value,void * dstarr,int cmp_op)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
CV_DEF_INIT_FUNC_TAB_2D(Min,C1R)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
cvMin(const void * srcarr1,const void * srcarr2,void * dstarr)1049 cvMin( const void* srcarr1, const void* srcarr2, void* dstarr )
1050 {
1051 icvMinMax( srcarr1, srcarr2, dstarr, 0 );
1052 }
1053
1054
1055 CV_IMPL void
cvMax(const void * srcarr1,const void * srcarr2,void * dstarr)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
icvMinMaxS(const void * srcarr,double value,void * dstarr,int is_max)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
cvMinS(const void * srcarr,double value,void * dstarr)1232 cvMinS( const void* srcarr, double value, void* dstarr )
1233 {
1234 icvMinMaxS( srcarr, value, dstarr, 0 );
1235 }
1236
1237
1238 CV_IMPL void
cvMaxS(const void * srcarr,double value,void * dstarr)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
ICV_DEF_BIN_ABS_DIFF_2D(icvAbsDiff_8u_C1R,uchar,int,CV_IABS,ICV_TO_8U)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
cvAbsDiffS(const void * srcarr,void * dstarr,CvScalar scalar)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