1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*M///////////////////////////////////////////////////////////////////////////////////////
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  By downloading, copying, installing or using the software you agree to this license.
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  If you do not agree to this license, do not download, install,
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  copy or use the software.
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                        Intel License Agreement
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                For Open Source Computer Vision Library
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2000, Intel Corporation, all rights reserved.
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Third party copyrights are property of their respective owners.
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Redistribution and use in source and binary forms, with or without modification,
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// are permitted provided that the following conditions are met:
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's of source code must retain the above copyright notice,
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer.
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's in binary form must reproduce the above copyright notice,
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer in the documentation
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     and/or other materials provided with the distribution.
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * The name of Intel Corporation may not be used to endorse or promote products
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     derived from this software without specific prior written permission.
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// This software is provided by the copyright holders and contributors "as is" and
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// any express or implied warranties, including, but not limited to, the implied
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// warranties of merchantability and fitness for a particular purpose are disclaimed.
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// In no event shall the Intel Corporation or contributors be liable for any direct,
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// indirect, incidental, special, exemplary, or consequential damages
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// (including, but not limited to, procurement of substitute goods or services;
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// loss of use, data, or profits; or business interruption) however caused
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and on any theory of liability, whether in contract, strict liability,
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// or tort (including negligence or otherwise) arising in any way out of
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the use of this software, even if advised of the possibility of such damage.
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//M*/
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* ////////////////////////////////////////////////////////////////////
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  CvMat comparison functions: range checking, min, max
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// */
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "_cxcore.h"
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/****************************************************************************************\
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler*                                      InRange[S]                                        *
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler\****************************************************************************************/
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_C1( worktype, _toggle_macro_ )    \
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                               \
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                               \
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x]),                      \
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             a2 = src2[x], a3 = src3[x];                        \
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-(_toggle_macro_(a2) <= a1 &&               \
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     a1 < _toggle_macro_(a3));                  \
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_C2( worktype, _toggle_macro_ )        \
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x*2]),                        \
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             a2 = src2[x*2], a3 = src3[x*2];                        \
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int f = _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);    \
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*2+1]);                               \
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a2 = src2[x*2+1];                                               \
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a3 = src3[x*2+1];                                               \
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);       \
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-f;                                             \
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_C3( worktype, _toggle_macro_ )        \
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x*3]),                        \
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             a2 = src2[x*3], a3 = src3[x*3];                        \
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int f = _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);    \
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*3+1]);                               \
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a2 = src2[x*3+1];                                               \
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a3 = src3[x*3+1];                                               \
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);       \
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*3+2]);                               \
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a2 = src2[x*3+2];                                               \
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a3 = src3[x*3+2];                                               \
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);       \
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-f;                                             \
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_C4( worktype, _toggle_macro_ )        \
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x*4]),                        \
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             a2 = src2[x*4], a3 = src3[x*4];                        \
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int f = _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);    \
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*4+1]);                               \
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a2 = src2[x*4+1];                                               \
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a3 = src3[x*4+1];                                               \
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);       \
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*4+2]);                               \
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a2 = src2[x*4+2];                                               \
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a3 = src3[x*4+2];                                               \
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);       \
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*4+3]);                               \
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a2 = src2[x*4+3];                                               \
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a3 = src3[x*4+3];                                               \
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= _toggle_macro_(a2) <= a1 && a1 < _toggle_macro_(a3);       \
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-f;                                             \
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype,           \
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                               _toggle_macro_, cn )                 \
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic CvStatus CV_STDCALL                                          \
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslericvInRange_##flavor##_C##cn##R( const arrtype* src1, int step1,     \
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                const arrtype* src2, int step2,     \
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                const arrtype* src3, int step3,     \
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                uchar* dst, int step, CvSize size ) \
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    step1 /= sizeof(src1[0]); step2 /= sizeof(src2[0]);             \
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    step3 /= sizeof(src3[0]); step /= sizeof(dst[0]);               \
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                    \
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( ; size.height--; src1 += step1, src2 += step2,             \
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                          src3 += step3, dst += step )              \
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {                                                               \
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int x;                                                      \
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ICV_DEF_IN_RANGE_CASE_C##cn( worktype, _toggle_macro_ )     \
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }                                                               \
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                    \
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return CV_OK;                                                   \
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_CONST_C1( worktype, _toggle_macro_ )  \
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x]);                          \
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-(scalar[0] <= a1 && a1 < scalar[1]);           \
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_CONST_C2( worktype, _toggle_macro_ )  \
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x*2]);                        \
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int f = scalar[0] <= a1 && a1 < scalar[2];                      \
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*2+1]);                               \
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= scalar[1] <= a1 && a1 < scalar[3];                         \
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-f;                                             \
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_CONST_C3( worktype, _toggle_macro_ )  \
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x*3]);                        \
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int f = scalar[0] <= a1 && a1 < scalar[3];                      \
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*3+1]);                               \
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= scalar[1] <= a1 && a1 < scalar[4];                         \
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*3+2]);                               \
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= scalar[2] <= a1 && a1 < scalar[5];                         \
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-f;                                             \
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CASE_CONST_C4( worktype, _toggle_macro_ )  \
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfor( x = 0; x < size.width; x++ )                                   \
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    worktype a1 = _toggle_macro_(src1[x*4]);                        \
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int f = scalar[0] <= a1 && a1 < scalar[4];                      \
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*4+1]);                               \
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= scalar[1] <= a1 && a1 < scalar[5];                         \
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*4+2]);                               \
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= scalar[2] <= a1 && a1 < scalar[6];                         \
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    a1 = _toggle_macro_(src1[x*4+3]);                               \
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    f &= scalar[3] <= a1 && a1 < scalar[7];                         \
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst[x] = (uchar)-f;                                             \
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype,     \
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                     _toggle_macro_, cn )           \
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic CvStatus CV_STDCALL                                          \
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslericvInRangeC_##flavor##_C##cn##R( const arrtype* src1, int step1,    \
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 uchar* dst, int step, CvSize size, \
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                 const worktype* scalar )           \
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                                   \
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    step1 /= sizeof(src1[0]); step /= sizeof(dst[0]);               \
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                    \
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( ; size.height--; src1 += step1, dst += step )              \
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {                                                               \
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int x;                                                      \
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ICV_DEF_IN_RANGE_CASE_CONST_C##cn( worktype, _toggle_macro_)\
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }                                                               \
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                    \
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return CV_OK;                                                   \
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ICV_DEF_IN_RANGE_ALL( flavor, arrtype, worktype, _toggle_macro_ )   \
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 1 )       \
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 2 )       \
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 3 )       \
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_FUNC( flavor, arrtype, worktype, _toggle_macro_, 4 )       \
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                            \
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 1 ) \
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 2 ) \
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 3 ) \
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_CONST_FUNC( flavor, arrtype, worktype, _toggle_macro_, 4 )
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_ALL( 8u, uchar, int, CV_NOP )
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_ALL( 16u, ushort, int, CV_NOP )
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_ALL( 16s, short, int, CV_NOP )
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_ALL( 32s, int, int, CV_NOP )
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_ALL( 32f, float, float, CV_NOP )
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerICV_DEF_IN_RANGE_ALL( 64f, double, double, CV_NOP )
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRange_8s_C1R 0
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRange_8s_C2R 0
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRange_8s_C3R 0
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRange_8s_C4R 0
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRangeC_8s_C1R 0
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRangeC_8s_C2R 0
231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRangeC_8s_C3R 0
232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define icvInRangeC_8s_C4R 0
233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
234793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCV_DEF_INIT_BIG_FUNC_TAB_2D( InRange, R )
235793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCV_DEF_INIT_BIG_FUNC_TAB_2D( InRangeC, R )
236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef CvStatus (CV_STDCALL * CvInRangeCFunc)( const void* src, int srcstep,
238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                uchar* dst, int dststep,
239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                CvSize size, const void* scalar );
240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*************************************** InRange ****************************************/
242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
243793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCV_IMPL void
244793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslercvInRange( const void* srcarr1, const void* srcarr2,
245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           const void* srcarr3, void* dstarr )
246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    static CvBigFuncTable inrange_tab;
248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    static int inittab = 0;
249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_FUNCNAME( "cvInRange" );
251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    __BEGIN__;
253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int type, coi = 0;
255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int src1_step, src2_step, src3_step, dst_step;
256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvMat srcstub1, *src1 = (CvMat*)srcarr1;
257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvMat srcstub2, *src2 = (CvMat*)srcarr2;
258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvMat srcstub3, *src3 = (CvMat*)srcarr3;
259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvMat dststub,  *dst = (CvMat*)dstarr;
260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvSize size;
261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvFunc2D_4A func;
262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !inittab )
264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        icvInitInRangeRTable( &inrange_tab );
266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        inittab = 1;
267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_IS_MAT(src1) )
270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi ));
272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( coi != 0 )
273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_ERROR( CV_BadCOI, "" );
274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_IS_MAT(src2) )
277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi ));
279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( coi != 0 )
280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_ERROR( CV_BadCOI, "" );
281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_IS_MAT(src3) )
284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_CALL( src3 = cvGetMat( src3, &srcstub3, &coi ));
286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( coi != 0 )
287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_ERROR( CV_BadCOI, "" );
288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_IS_MAT(dst) )
291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( coi != 0 )
294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_ERROR( CV_BadCOI, "" );
295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_ARE_TYPES_EQ( src1, src2 ) ||
298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        !CV_ARE_TYPES_EQ( src1, src3 ) )
299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_IS_MASK_ARR( dst ))
302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_ERROR( CV_StsUnsupportedFormat, "Destination image should be 8uC1 or 8sC1");
303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !CV_ARE_SIZES_EQ( src1, src2 ) ||
305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        !CV_ARE_SIZES_EQ( src1, src3 ) ||
306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        !CV_ARE_SIZES_EQ( src1, dst ))
307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    type = CV_MAT_TYPE(src1->type);
310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size = cvGetMatSize( src1 );
311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( CV_IS_MAT_CONT( src1->type & src2->type & src3->type & dst->type ))
313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        size.width *= size.height;
315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        src1_step = src2_step = src3_step = dst_step = CV_STUB_STEP;
316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        size.height = 1;
317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        src1_step = src1->step;
321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        src2_step = src2->step;
322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        src3_step = src3->step;
323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        dst_step = dst->step;
324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( CV_MAT_CN(type) > 4 )
327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_ERROR( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
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
343CV_IMPL void
344cvInRangeS( 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_ )                   \
428for( 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                                                                        \
440for( ; 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_ )            \
449static CvStatus CV_STDCALL                                      \
450icv##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_ )     \
469for( 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                                                                \
481for( ; 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_)       \
490static CvStatus CV_STDCALL                                      \
491icv##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_ )            \
509ICV_DEF_CMP_FUNC( CV_GT, CmpGT, flavor, arrtype, worktype, _toggle_macro_ )     \
510ICV_DEF_CMP_FUNC( CV_EQ, CmpEQ, flavor, arrtype, worktype, _toggle_macro_ )     \
511ICV_DEF_CMP_CONST_FUNC( CV_GT, CmpGT, flavor, arrtype, worktype, _toggle_macro_)\
512ICV_DEF_CMP_CONST_FUNC( CV_GE, CmpGE, flavor, arrtype, worktype, _toggle_macro_)\
513ICV_DEF_CMP_CONST_FUNC( CV_EQ, CmpEQ, flavor, arrtype, worktype, _toggle_macro_)
514
515ICV_DEF_CMP_ALL( 8u, uchar, int, CV_NOP )
516ICV_DEF_CMP_ALL( 16u, ushort, int, CV_NOP )
517ICV_DEF_CMP_ALL( 16s, short, int, CV_NOP )
518ICV_DEF_CMP_ALL( 32s, int, int, CV_NOP )
519ICV_DEF_CMP_ALL( 32f, float, double, CV_NOP )
520ICV_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
528CV_DEF_INIT_FUNC_TAB_2D( CmpGT, C1R )
529CV_DEF_INIT_FUNC_TAB_2D( CmpEQ, C1R )
530CV_DEF_INIT_FUNC_TAB_2D( CmpGTC, C1R )
531CV_DEF_INIT_FUNC_TAB_2D( CmpGEC, C1R )
532CV_DEF_INIT_FUNC_TAB_2D( CmpEQC, C1R )
533
534icvCompare_8u_C1R_t icvCompare_8u_C1R_p = 0;
535icvCompare_16s_C1R_t icvCompare_16s_C1R_p = 0;
536icvCompare_32f_C1R_t icvCompare_32f_C1R_p = 0;
537
538icvCompareC_8u_C1R_t icvCompareC_8u_C1R_p = 0;
539icvCompareC_16s_C1R_t icvCompareC_16s_C1R_p = 0;
540icvCompareC_32f_C1R_t icvCompareC_32f_C1R_p = 0;
541
542icvThreshold_GT_8u_C1R_t icvThreshold_GT_8u_C1R_p = 0;
543icvThreshold_GT_16s_C1R_t icvThreshold_GT_16s_C1R_p = 0;
544icvThreshold_GT_32f_C1R_t icvThreshold_GT_32f_C1R_p = 0;
545
546icvThreshold_LT_8u_C1R_t icvThreshold_LT_8u_C1R_p = 0;
547icvThreshold_LT_16s_C1R_t icvThreshold_LT_16s_C1R_p = 0;
548icvThreshold_LT_32f_C1R_t icvThreshold_LT_32f_C1R_p = 0;
549
550/***************************************** cvCmp ****************************************/
551
552CV_IMPL void
553cvCmp( 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
692CV_IMPL void
693cvCmpS( 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_ )     \
850static CvStatus CV_STDCALL                                  \
851icv##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_)              \
897static CvStatus CV_STDCALL                                  \
898icv##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_ )                   \
938ICV_DEF_MINMAX_FUNC( _min_op_, Min, flavor, arrtype, worktype, _toggle_macro_ )    \
939ICV_DEF_MINMAX_FUNC( _max_op_, Max, flavor, arrtype, worktype, _toggle_macro_ )    \
940ICV_DEF_MINMAX_CONST_FUNC(_min_op_, Min, flavor, arrtype, worktype, _toggle_macro_)\
941ICV_DEF_MINMAX_CONST_FUNC(_max_op_, Max, flavor, arrtype, worktype, _toggle_macro_)
942
943ICV_DEF_MINMAX_ALL( 8u, uchar, int, CV_NOP, CV_MIN_8U, CV_MAX_8U )
944ICV_DEF_MINMAX_ALL( 16u, ushort, int, CV_NOP, CV_IMIN, CV_IMAX )
945ICV_DEF_MINMAX_ALL( 16s, short, int, CV_NOP, CV_IMIN, CV_IMAX )
946ICV_DEF_MINMAX_ALL( 32s, int, int, CV_NOP, CV_IMIN, CV_IMAX )
947ICV_DEF_MINMAX_ALL( 32f, int, int, CV_TOGGLE_FLT, CV_IMIN, CV_IMAX )
948ICV_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
955CV_DEF_INIT_FUNC_TAB_2D( Min, C1R )
956CV_DEF_INIT_FUNC_TAB_2D( Max, C1R )
957CV_DEF_INIT_FUNC_TAB_2D( MinC, C1R )
958CV_DEF_INIT_FUNC_TAB_2D( MaxC, C1R )
959
960/*********************************** cvMin & cvMax **************************************/
961
962static void
963icvMinMax( 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
1048CV_IMPL void
1049cvMin( const void* srcarr1, const void* srcarr2, void* dstarr )
1050{
1051    icvMinMax( srcarr1, srcarr2, dstarr, 0 );
1052}
1053
1054
1055CV_IMPL void
1056cvMax( const void* srcarr1, const void* srcarr2, void* dstarr )
1057{
1058    icvMinMax( srcarr1, srcarr2, dstarr, 1 );
1059}
1060
1061
1062/********************************* cvMinS / cvMaxS **************************************/
1063
1064static void
1065icvMinMaxS( 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
1231CV_IMPL void
1232cvMinS( const void* srcarr, double value, void* dstarr )
1233{
1234    icvMinMaxS( srcarr, value, dstarr, 0 );
1235}
1236
1237
1238CV_IMPL void
1239cvMaxS( 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)\
1250IPCVAPI_IMPL( CvStatus,                                 \
1251name,( 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)\
1298static CvStatus CV_STDCALL                              \
1299name( 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
1383ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_8u_C1R, uchar, int, CV_IABS, ICV_TO_8U )
1384ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_16u_C1R, ushort, int, CV_IABS, ICV_TO_16U )
1385ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_16s_C1R, short, int, CV_IABS, CV_CAST_16S )
1386ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_32s_C1R, int, int, CV_IABS, CV_CAST_32S )
1387ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_32f_C1R, float, float, fabs, CV_CAST_32F )
1388ICV_DEF_BIN_ABS_DIFF_2D( icvAbsDiff_64f_C1R, double, double, fabs, CV_CAST_64F )
1389
1390ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_8u_CnR, uchar, int, CV_IABS, CV_CAST_8U )
1391ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_16u_CnR, ushort, int, CV_IABS, CV_CAST_16U )
1392ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_16s_CnR, short, int, CV_IABS, CV_CAST_16S )
1393ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_32s_CnR, int, int, CV_IABS, CV_CAST_32S )
1394ICV_DEF_UN_ABS_DIFF_2D( icvAbsDiffC_32f_CnR, float, float, fabs, CV_CAST_32F )
1395ICV_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 )          \
1399static 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
1410ICV_INIT_MINI_FUNC_TAB_2D( AbsDiff, C1R )
1411ICV_INIT_MINI_FUNC_TAB_2D( AbsDiffC, CnR )
1412
1413
1414CV_IMPL  void
1415cvAbsDiff( 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
1488CV_IMPL void
1489cvAbsDiffS( 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