1 /*
2  * By downloading, copying, installing or using the software you agree to this license.
3  * If you do not agree to this license, do not download, install,
4  * copy or use the software.
5  *
6  *
7  *                           License Agreement
8  *                For Open Source Computer Vision Library
9  *                        (3-clause BSD License)
10  *
11  * Copyright (C) 2016, NVIDIA Corporation, all rights reserved.
12  * Third party copyrights are property of their respective owners.
13  *
14  * Redistribution and use in source and binary forms, with or without modification,
15  * are permitted provided that the following conditions are met:
16  *
17  *   * Redistributions of source code must retain the above copyright notice,
18  *     this list of conditions and the following disclaimer.
19  *
20  *   * Redistributions in binary form must reproduce the above copyright notice,
21  *     this list of conditions and the following disclaimer in the documentation
22  *     and/or other materials provided with the distribution.
23  *
24  *   * Neither the names of the copyright holders nor the names of the contributors
25  *     may be used to endorse or promote products derived from this software
26  *     without specific prior written permission.
27  *
28  * This software is provided by the copyright holders and contributors "as is" and
29  * any express or implied warranties, including, but not limited to, the implied
30  * warranties of merchantability and fitness for a particular purpose are disclaimed.
31  * In no event shall copyright holders or contributors be liable for any direct,
32  * indirect, incidental, special, exemplary, or consequential damages
33  * (including, but not limited to, procurement of substitute goods or services;
34  * loss of use, data, or profits; or business interruption) however caused
35  * and on any theory of liability, whether in contract, strict liability,
36  * or tort (including negligence or otherwise) arising in any way out of
37  * the use of this software, even if advised of the possibility of such damage.
38  */
39 
40 #ifndef _tegra_hal_H_INCLUDED_
41 #define _tegra_hal_H_INCLUDED_
42 
43 #define CAROTENE_NS carotene_o4t
44 
45 #include "carotene/functions.hpp"
46 #include <cstddef>
47 #include <cstring>
48 #include <vector>
49 #include <opencv2/core/base.hpp>
50 
51 #define RANGE_DATA(type, base, step) reinterpret_cast<type*>(const_cast<char *>(reinterpret_cast<const char *>(base)) + static_cast<size_t>(range.start) * step)
52 
53 #define PARALLEL_CORE 0
54 #if PARALLEL_CORE
55 
56 #define SRC_ARG1 ST * src1_data_, size_t src1_step_,
57 #define SRC_STORE1 src1_data(src1_data_), src1_step(src1_step_),
58 #define SRC_VAR1 ST * src1_data; \
59                  size_t src1_step;
60 #define SRC_ARG2 ST * src1_data_, size_t src1_step_, \
61                  ST * src2_data_, size_t src2_step_,
62 #define SRC_STORE2 src1_data(src1_data_), src1_step(src1_step_), \
63                    src2_data(src2_data_), src2_step(src2_step_),
64 #define SRC_VAR2 ST * src1_data; \
65                  size_t src1_step; \
66                  ST * src2_data; \
67                  size_t src2_step;
68 
69 #define DST_ARG1 DT * dst1_data_, size_t dst1_step_,
70 #define DST_STORE1 dst1_data(dst1_data_), dst1_step(dst1_step_),
71 #define DST_VAR1 DT * dst1_data; \
72                  size_t dst1_step;
73 
74 #define SCALE_ARG0
75 #define SCALE_STORE0
76 #define SCALE_VAR0
77 #define SCALE_ARG1 , double scale_
78 #define SCALE_STORE1 , scale(scale_)
79 #define SCALE_VAR1 double scale;
80 #define SCALE_ARG3 , const double *scales_
81 #define SCALE_STORE3 , scales(scales_, scales_ + 3)
82 #define SCALE_VAR3 std::vector<double> scales;
83 
84 #define TegraGenOp_Invoker(name, func, src_cnt, dst_cnt, scale_cnt, ...) \
85 template <typename ST, typename DT> \
86 class TegraGenOp_##name##_Invoker : public cv::ParallelLoopBody \
87 { \
88 public: \
89     TegraGenOp_##name##_Invoker(SRC_ARG##src_cnt \
90                                 DST_ARG##dst_cnt \
91                                 int width_, int height_ \
92                                 SCALE_ARG##scale_cnt) : \
93         cv::ParallelLoopBody(), SRC_STORE##src_cnt \
94                                 DST_STORE##dst_cnt \
95                                 width(width_), height(height_) \
96                                 SCALE_STORE##scale_cnt {} \
97     virtual void operator()(const cv::Range& range) const \
98     { \
99         CAROTENE_NS::func(CAROTENE_NS::Size2D(width, range.end-range.start), __VA_ARGS__); \
100     } \
101 private: \
102     SRC_VAR##src_cnt \
103     DST_VAR##dst_cnt \
104     int width, height; \
105     SCALE_VAR##scale_cnt \
106     const TegraGenOp_##name##_Invoker& operator= (const TegraGenOp_##name##_Invoker&); \
107 };
108 
109 #define TegraBinaryOp_Invoker(name, func) TegraGenOp_Invoker(name, func, 2, 1, 0, \
110                                                              RANGE_DATA(ST, src1_data, src1_step), src1_step, \
111                                                              RANGE_DATA(ST, src2_data, src2_step), src2_step, \
112                                                              RANGE_DATA(DT, dst1_data, dst1_step), dst1_step )
113 
114 #define TegraBinaryOp_InvokerVAArg(name, func, ...) TegraGenOp_Invoker(name, func, 2, 1, 0, \
115                                                                        RANGE_DATA(ST, src1_data, src1_step), src1_step, \
116                                                                        RANGE_DATA(ST, src2_data, src2_step), src2_step, \
117                                                                        RANGE_DATA(DT, dst1_data, dst1_step), dst1_step, __VA_ARGS__)
118 
119 #define TEGRA_BINARYOP(type, op, src1, sz1, src2, sz2, dst, sz, w, h) \
120 ( \
121     CAROTENE_NS::isSupportedConfiguration() ? \
122     parallel_for_(Range(0, h), \
123     TegraGenOp_##op##_Invoker<const type, type>(src1, sz1, src2, sz2, dst, sz, w, h), \
124     (w * h) / static_cast<double>(1<<16)), \
125     CV_HAL_ERROR_OK \
126     : CV_HAL_ERROR_NOT_IMPLEMENTED \
127 )
128 
129 TegraBinaryOp_InvokerVAArg(add, add, CAROTENE_NS::CONVERT_POLICY_SATURATE) /*Original addition use saturated operator, so use the same from CAROTENE*/
130 
131 TegraBinaryOp_Invoker(addf, add)
132 
133 TegraBinaryOp_InvokerVAArg(sub, sub, CAROTENE_NS::CONVERT_POLICY_SATURATE) /*Original addition use saturated operator, so use the same from CAROTENE*/
134 
135 TegraBinaryOp_Invoker(subf, sub)
136 
137 TegraBinaryOp_Invoker(max, max)
138 
139 TegraBinaryOp_Invoker(min, min)
140 
141 TegraBinaryOp_Invoker(absDiff, absDiff)
142 
143 TegraBinaryOp_Invoker(bitwiseAnd, bitwiseAnd)
144 
145 TegraBinaryOp_Invoker(bitwiseOr, bitwiseOr)
146 
147 TegraBinaryOp_Invoker(bitwiseXor, bitwiseXor)
148 
149 #define TegraUnaryOp_Invoker(name, func) TegraGenOp_Invoker(name, func, 1, 1, 0, \
150                                                             RANGE_DATA(ST, src1_data, src1_step), src1_step, \
151                                                             RANGE_DATA(DT, dst1_data, dst1_step), dst1_step )
152 
153 TegraUnaryOp_Invoker(bitwiseNot, bitwiseNot)
154 #define TEGRA_UNARYOP(type, op, src1, sz1, dst, sz, w, h) \
155 ( \
156     CAROTENE_NS::isSupportedConfiguration() ? \
157     parallel_for_(Range(0, h), \
158     TegraGenOp_##op##_Invoker<const type, type>(src1, sz1, dst, sz, w, h), \
159     (w * h) / static_cast<double>(1<<16)), \
160     CV_HAL_ERROR_OK \
161     : CV_HAL_ERROR_NOT_IMPLEMENTED \
162 )
163 
164 #undef cv_hal_add8u
165 #define cv_hal_add8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, add, src1, sz1, src2, sz2, dst, sz, w, h)
166 #undef cv_hal_add8s
167 #define cv_hal_add8s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s8, add, src1, sz1, src2, sz2, dst, sz, w, h)
168 #undef cv_hal_add16u
169 #define cv_hal_add16u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u16, add, src1, sz1, src2, sz2, dst, sz, w, h)
170 #undef cv_hal_add16s
171 #define cv_hal_add16s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s16, add, src1, sz1, src2, sz2, dst, sz, w, h)
172 #undef cv_hal_add32s
173 #define cv_hal_add32s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s32, add, src1, sz1, src2, sz2, dst, sz, w, h)
174 #undef cv_hal_add32f
175 #define cv_hal_add32f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f32, addf, src1, sz1, src2, sz2, dst, sz, w, h)
176 //#undef cv_hal_add64f
177 //#define cv_hal_add64f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f64, addf, src1, sz1, src2, sz2, dst, sz, w, h)
178 #undef cv_hal_sub8u
179 #define cv_hal_sub8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, sub, src1, sz1, src2, sz2, dst, sz, w, h)
180 #undef cv_hal_sub8s
181 #define cv_hal_sub8s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s8, sub, src1, sz1, src2, sz2, dst, sz, w, h)
182 #undef cv_hal_sub16u
183 #define cv_hal_sub16u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u16, sub, src1, sz1, src2, sz2, dst, sz, w, h)
184 #undef cv_hal_sub16s
185 #define cv_hal_sub16s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s16, sub, src1, sz1, src2, sz2, dst, sz, w, h)
186 #undef cv_hal_sub32s
187 #define cv_hal_sub32s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s32, sub, src1, sz1, src2, sz2, dst, sz, w, h)
188 #undef cv_hal_sub32f
189 #define cv_hal_sub32f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f32, subf, src1, sz1, src2, sz2, dst, sz, w, h)
190 //#undef cv_hal_sub64f
191 //#define cv_hal_sub64f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f64, subf, src1, sz1, src2, sz2, dst, sz, w, h)
192 #undef cv_hal_max8u
193 #define cv_hal_max8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, max, src1, sz1, src2, sz2, dst, sz, w, h)
194 #undef cv_hal_max8s
195 #define cv_hal_max8s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s8, max, src1, sz1, src2, sz2, dst, sz, w, h)
196 #undef cv_hal_max16u
197 #define cv_hal_max16u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u16, max, src1, sz1, src2, sz2, dst, sz, w, h)
198 #undef cv_hal_max16s
199 #define cv_hal_max16s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s16, max, src1, sz1, src2, sz2, dst, sz, w, h)
200 #undef cv_hal_max32s
201 #define cv_hal_max32s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s32, max, src1, sz1, src2, sz2, dst, sz, w, h)
202 #undef cv_hal_max32f
203 #define cv_hal_max32f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f32, max, src1, sz1, src2, sz2, dst, sz, w, h)
204 //#undef cv_hal_max64f
205 //#define cv_hal_max64f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f64, max, src1, sz1, src2, sz2, dst, sz, w, h)
206 #undef cv_hal_min8u
207 #define cv_hal_min8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, min, src1, sz1, src2, sz2, dst, sz, w, h)
208 #undef cv_hal_min8s
209 #define cv_hal_min8s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s8, min, src1, sz1, src2, sz2, dst, sz, w, h)
210 #undef cv_hal_min16u
211 #define cv_hal_min16u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u16, min, src1, sz1, src2, sz2, dst, sz, w, h)
212 #undef cv_hal_min16s
213 #define cv_hal_min16s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s16, min, src1, sz1, src2, sz2, dst, sz, w, h)
214 #undef cv_hal_min32s
215 #define cv_hal_min32s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s32, min, src1, sz1, src2, sz2, dst, sz, w, h)
216 #undef cv_hal_min32f
217 #define cv_hal_min32f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f32, min, src1, sz1, src2, sz2, dst, sz, w, h)
218 //#undef cv_hal_min64f
219 //#define cv_hal_min64f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f64, min, src1, sz1, src2, sz2, dst, sz, w, h)
220 #undef cv_hal_absdiff8u
221 #define cv_hal_absdiff8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
222 #undef cv_hal_absdiff8s
223 #define cv_hal_absdiff8s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s8, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
224 #undef cv_hal_absdiff16u
225 #define cv_hal_absdiff16u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u16, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
226 #undef cv_hal_absdiff16s
227 #define cv_hal_absdiff16s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s16, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
228 #undef cv_hal_absdiff32s
229 #define cv_hal_absdiff32s(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::s32, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
230 #undef cv_hal_absdiff32f
231 #define cv_hal_absdiff32f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f32, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
232 //#undef cv_hal_absdiff64f
233 //#define cv_hal_absdiff64f(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::f64, absDiff, src1, sz1, src2, sz2, dst, sz, w, h)
234 #undef cv_hal_and8u
235 #define cv_hal_and8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, bitwiseAnd, src1, sz1, src2, sz2, dst, sz, w, h)
236 #undef cv_hal_or8u
237 #define cv_hal_or8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, bitwiseOr, src1, sz1, src2, sz2, dst, sz, w, h)
238 #undef cv_hal_xor8u
239 #define cv_hal_xor8u(src1, sz1, src2, sz2, dst, sz, w, h) TEGRA_BINARYOP(CAROTENE_NS::u8, bitwiseXor, src1, sz1, src2, sz2, dst, sz, w, h)
240 #undef cv_hal_not8u
241 #define cv_hal_not8u(src1, sz1, dst, sz, w, h) TEGRA_UNARYOP(CAROTENE_NS::u8, bitwiseNot, src1, sz1, dst, sz, w, h)
242 
243 TegraBinaryOp_Invoker(cmpEQ, cmpEQ)
244 TegraBinaryOp_Invoker(cmpNE, cmpNE)
245 TegraBinaryOp_Invoker(cmpGT, cmpGT)
246 TegraBinaryOp_Invoker(cmpGE, cmpGE)
247 TegraGenOp_Invoker(cmpLT, cmpGT, 2, 1, 0, RANGE_DATA(ST, src2_data, src2_step), src2_step, \
248                                           RANGE_DATA(ST, src1_data, src1_step), src1_step, \
249                                           RANGE_DATA(DT, dst1_data, dst1_step), dst1_step)
250 TegraGenOp_Invoker(cmpLE, cmpGE, 2, 1, 0, RANGE_DATA(ST, src2_data, src2_step), src2_step, \
251                                           RANGE_DATA(ST, src1_data, src1_step), src1_step, \
252                                           RANGE_DATA(DT, dst1_data, dst1_step), dst1_step)
253 #define TEGRA_CMP(type, src1, sz1, src2, sz2, dst, sz, w, h, op) \
254 ( \
255     CAROTENE_NS::isSupportedConfiguration() ? \
256         ((op) == cv::CMP_EQ) ? \
257         parallel_for_(Range(0, h), \
258         TegraGenOp_cmpEQ_Invoker<const type, CAROTENE_NS::u8>(src1, sz1, src2, sz2, dst, sz, w, h), \
259         (w * h) / static_cast<double>(1<<16)), \
260         CV_HAL_ERROR_OK : \
261         ((op) == cv::CMP_NE) ? \
262         parallel_for_(Range(0, h), \
263         TegraGenOp_cmpNE_Invoker<const type, CAROTENE_NS::u8>(src1, sz1, src2, sz2, dst, sz, w, h), \
264         (w * h) / static_cast<double>(1<<16)), \
265         CV_HAL_ERROR_OK : \
266         ((op) == cv::CMP_GT) ? \
267         parallel_for_(Range(0, h), \
268         TegraGenOp_cmpGT_Invoker<const type, CAROTENE_NS::u8>(src1, sz1, src2, sz2, dst, sz, w, h), \
269         (w * h) / static_cast<double>(1<<16)), \
270         CV_HAL_ERROR_OK : \
271         ((op) == cv::CMP_GE) ? \
272         parallel_for_(Range(0, h), \
273         TegraGenOp_cmpGE_Invoker<const type, CAROTENE_NS::u8>(src1, sz1, src2, sz2, dst, sz, w, h), \
274         (w * h) / static_cast<double>(1<<16)), \
275         CV_HAL_ERROR_OK : \
276         ((op) == cv::CMP_LT) ? \
277         parallel_for_(Range(0, h), \
278         TegraGenOp_cmpLT_Invoker<const type, CAROTENE_NS::u8>(src1, sz1, src2, sz2, dst, sz, w, h), \
279         (w * h) / static_cast<double>(1<<16)), \
280         CV_HAL_ERROR_OK : \
281         ((op) == cv::CMP_LE) ? \
282         parallel_for_(Range(0, h), \
283         TegraGenOp_cmpLE_Invoker<const type, CAROTENE_NS::u8>(src1, sz1, src2, sz2, dst, sz, w, h), \
284         (w * h) / static_cast<double>(1<<16)), \
285         CV_HAL_ERROR_OK : \
286         CV_HAL_ERROR_NOT_IMPLEMENTED \
287     : CV_HAL_ERROR_NOT_IMPLEMENTED \
288 )
289 
290 #undef cv_hal_cmp8u
291 #define cv_hal_cmp8u(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::u8, src1, sz1, src2, sz2, dst, sz, w, h, op)
292 #undef cv_hal_cmp8s
293 #define cv_hal_cmp8s(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::s8, src1, sz1, src2, sz2, dst, sz, w, h, op)
294 #undef cv_hal_cmp16u
295 #define cv_hal_cmp16u(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::u16, src1, sz1, src2, sz2, dst, sz, w, h, op)
296 #undef cv_hal_cmp16s
297 #define cv_hal_cmp16s(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::s16, src1, sz1, src2, sz2, dst, sz, w, h, op)
298 #undef cv_hal_cmp32s
299 #define cv_hal_cmp32s(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::s32, src1, sz1, src2, sz2, dst, sz, w, h, op)
300 #undef cv_hal_cmp32f
301 #define cv_hal_cmp32f(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::f32, src1, sz1, src2, sz2, dst, sz, w, h, op)
302 //#undef cv_hal_cmp64f
303 //#define cv_hal_cmp64f(src1, sz1, src2, sz2, dst, sz, w, h, op) TEGRA_CMP(CAROTENE_NS::f64, src1, sz1, src2, sz2, dst, sz, w, h, op)
304 
305 #define TegraBinaryOpScale_Invoker(name, func, scale_cnt, ...) TegraGenOp_Invoker(name, func, 2, 1, scale_cnt, \
306                                                                                   RANGE_DATA(ST, src1_data, src1_step), src1_step, \
307                                                                                   RANGE_DATA(ST, src2_data, src2_step), src2_step, \
308                                                                                   RANGE_DATA(DT, dst1_data, dst1_step), dst1_step, __VA_ARGS__)
309 
310 #define TEGRA_BINARYOPSCALE(type, op, src1, sz1, src2, sz2, dst, sz, w, h, scales) \
311 ( \
312     CAROTENE_NS::isSupportedConfiguration() ? \
313     parallel_for_(Range(0, h), \
314     TegraGenOp_##op##_Invoker<const type, type>(src1, sz1, src2, sz2, dst, sz, w, h, scales), \
315     (w * h) / static_cast<double>(1<<16)), \
316     CV_HAL_ERROR_OK \
317     : CV_HAL_ERROR_NOT_IMPLEMENTED \
318 )
319 
320 TegraBinaryOpScale_Invoker(mul, mul, 1, scale, CAROTENE_NS::CONVERT_POLICY_SATURATE)
321 
322 TegraBinaryOpScale_Invoker(mulf, mul, 1, scale)
323 
324 TegraBinaryOpScale_Invoker(div, div, 1, scale, CAROTENE_NS::CONVERT_POLICY_SATURATE)
325 
326 TegraBinaryOpScale_Invoker(divf, div, 1, scale)
327 
328 #define TegraUnaryOpScale_Invoker(name, func, scale_cnt, ...) TegraGenOp_Invoker(name, func, 1, 1, scale_cnt, \
329                                                                                  RANGE_DATA(ST, src1_data, src1_step), src1_step, \
330                                                                                  RANGE_DATA(DT, dst1_data, dst1_step), dst1_step, __VA_ARGS__)
331 
332 #define TEGRA_UNARYOPSCALE(type, op, src1, sz1, dst, sz, w, h, scales) \
333 ( \
334     CAROTENE_NS::isSupportedConfiguration() ? \
335     parallel_for_(Range(0, h), \
336     TegraGenOp_##op##_Invoker<const type, type>(src1, sz1, dst, sz, w, h, scales), \
337     (w * h) / static_cast<double>(1<<16)), \
338     CV_HAL_ERROR_OK \
339     : CV_HAL_ERROR_NOT_IMPLEMENTED \
340 )
341 
342 TegraUnaryOpScale_Invoker(recip, reciprocal, 1, scale, CAROTENE_NS::CONVERT_POLICY_SATURATE)
343 
344 TegraUnaryOpScale_Invoker(recipf, reciprocal, 1, scale)
345 
346 #undef cv_hal_mul8u
347 #define cv_hal_mul8u(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::u8, mul, src1, sz1, src2, sz2, dst, sz, w, h, scales)
348 #undef cv_hal_mul8s
349 #define cv_hal_mul8s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s8, mul, src1, sz1, src2, sz2, dst, sz, w, h, scales)
350 #undef cv_hal_mul16u
351 #define cv_hal_mul16u(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::u16, mul, src1, sz1, src2, sz2, dst, sz, w, h, scales)
352 #undef cv_hal_mul16s
353 #define cv_hal_mul16s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s16, mul, src1, sz1, src2, sz2, dst, sz, w, h, scales)
354 #undef cv_hal_mul32s
355 #define cv_hal_mul32s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s32, mul, src1, sz1, src2, sz2, dst, sz, w, h, scales)
356 #undef cv_hal_mul32f
357 #define cv_hal_mul32f(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::f32, mulf, src1, sz1, src2, sz2, dst, sz, w, h, scales)
358 //#undef cv_hal_mul64f
359 //#define cv_hal_mul64f(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::f64, mulf, src1, sz1, src2, sz2, dst, sz, w, h, scales)
360 #undef cv_hal_div8u
361 #define cv_hal_div8u(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::u8, div, src1, sz1, src2, sz2, dst, sz, w, h, scales)
362 #undef cv_hal_div8s
363 #define cv_hal_div8s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s8, div, src1, sz1, src2, sz2, dst, sz, w, h, scales)
364 #undef cv_hal_div16u
365 #define cv_hal_div16u(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::u16, div, src1, sz1, src2, sz2, dst, sz, w, h, scales)
366 #undef cv_hal_div16s
367 #define cv_hal_div16s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s16, div, src1, sz1, src2, sz2, dst, sz, w, h, scales)
368 #undef cv_hal_div32s
369 #define cv_hal_div32s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s32, div, src1, sz1, src2, sz2, dst, sz, w, h, scales)
370 #undef cv_hal_div32f
371 #define cv_hal_div32f(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::f32, divf, src1, sz1, src2, sz2, dst, sz, w, h, scales)
372 //#undef cv_hal_div64f
373 //#define cv_hal_div64f(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::f64, divf, src1, sz1, src2, sz2, dst, sz, w, h, scales)
374 #undef cv_hal_recip8u
375 #define cv_hal_recip8u(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::u8, recip, src1, sz1, dst, sz, w, h, scales)
376 #undef cv_hal_recip8s
377 #define cv_hal_recip8s(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::s8, recip, src1, sz1, dst, sz, w, h, scales)
378 #undef cv_hal_recip16u
379 #define cv_hal_recip16u(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::u16, recip, src1, sz1, dst, sz, w, h, scales)
380 #undef cv_hal_recip16s
381 #define cv_hal_recip16s(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::s16, recip, src1, sz1, dst, sz, w, h, scales)
382 #undef cv_hal_recip32s
383 #define cv_hal_recip32s(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::s32, recip, src1, sz1, dst, sz, w, h, scales)
384 #undef cv_hal_recip32f
385 #define cv_hal_recip32f(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::f32, recipf, src1, sz1, dst, sz, w, h, scales)
386 //#undef cv_hal_recip64f
387 //#define cv_hal_recip64f(src1, sz1, dst, sz, w, h, scales) TEGRA_UNARYOPSCALE(CAROTENE_NS::f64, recipf, src1, sz1, dst, sz, w, h, scales)
388 
389 TegraBinaryOpScale_Invoker(addWeighted, addWeighted, 3, scales[0], scales[1], scales[2])
390 
391 #undef cv_hal_addWeighted8u
392 #define cv_hal_addWeighted8u(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::u8, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
393 #undef cv_hal_addWeighted8s
394 #define cv_hal_addWeighted8s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s8, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
395 #undef cv_hal_addWeighted16u
396 #define cv_hal_addWeighted16u(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::u16, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
397 #undef cv_hal_addWeighted16s
398 #define cv_hal_addWeighted16s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s16, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
399 #undef cv_hal_addWeighted32s
400 #define cv_hal_addWeighted32s(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::s32, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
401 //#undef cv_hal_addWeighted32f
402 //#define cv_hal_addWeighted32f(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::f32, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
403 //#undef cv_hal_addWeighted64f
404 //#define cv_hal_addWeighted64f(src1, sz1, src2, sz2, dst, sz, w, h, scales) TEGRA_BINARYOPSCALE(CAROTENE_NS::f64, addWeighted, src1, sz1, src2, sz2, dst, sz, w, h, scales)
405 
406 #else
407 
408 #define TEGRA_ADD(src1, sz1, src2, sz2, dst, sz, w, h) \
409 ( \
410     CAROTENE_NS::isSupportedConfiguration() ? \
411     CAROTENE_NS::add(CAROTENE_NS::Size2D(w, h), \
412                      src1, sz1, \
413                      src2, sz2, \
414                      dst, sz, \
415                      CAROTENE_NS::CONVERT_POLICY_SATURATE), /*Original addition use saturated operator*/ \
416                                                             /*so use the same from CAROTENE*/ \
417     CV_HAL_ERROR_OK \
418     : CV_HAL_ERROR_NOT_IMPLEMENTED \
419 )
420 
421 #define TEGRA_ADDF(src1, sz1, src2, sz2, dst, sz, w, h) \
422 ( \
423     CAROTENE_NS::isSupportedConfiguration() ? \
424     CAROTENE_NS::add(CAROTENE_NS::Size2D(w, h), \
425                      src1, sz1, \
426                      src2, sz2, \
427                      dst, sz), \
428     CV_HAL_ERROR_OK \
429     : CV_HAL_ERROR_NOT_IMPLEMENTED \
430 )
431 
432 #define TEGRA_SUB(src1, sz1, src2, sz2, dst, sz, w, h) \
433 ( \
434     CAROTENE_NS::isSupportedConfiguration() ? \
435     CAROTENE_NS::sub(CAROTENE_NS::Size2D(w, h), \
436                      src1, sz1, \
437                      src2, sz2, \
438                      dst, sz, \
439                      CAROTENE_NS::CONVERT_POLICY_SATURATE), /*Original addition use saturated operator*/ \
440                                                             /*so use the same from CAROTENE*/ \
441     CV_HAL_ERROR_OK \
442     : CV_HAL_ERROR_NOT_IMPLEMENTED \
443 )
444 
445 #define TEGRA_SUBF(src1, sz1, src2, sz2, dst, sz, w, h) \
446 ( \
447     CAROTENE_NS::isSupportedConfiguration() ? \
448     CAROTENE_NS::sub(CAROTENE_NS::Size2D(w, h), \
449                      src1, sz1, \
450                      src2, sz2, \
451                      dst, sz), \
452     CV_HAL_ERROR_OK \
453     : CV_HAL_ERROR_NOT_IMPLEMENTED \
454 )
455 
456 #define TEGRA_MAX(src1, sz1, src2, sz2, dst, sz, w, h) \
457 ( \
458     CAROTENE_NS::isSupportedConfiguration() ? \
459     CAROTENE_NS::max(CAROTENE_NS::Size2D(w, h), \
460                      src1, sz1, \
461                      src2, sz2, \
462                      dst, sz), \
463     CV_HAL_ERROR_OK \
464     : CV_HAL_ERROR_NOT_IMPLEMENTED \
465 )
466 
467 #define TEGRA_MIN(src1, sz1, src2, sz2, dst, sz, w, h) \
468 ( \
469     CAROTENE_NS::isSupportedConfiguration() ? \
470     CAROTENE_NS::min(CAROTENE_NS::Size2D(w, h), \
471                      src1, sz1, \
472                      src2, sz2, \
473                      dst, sz), \
474     CV_HAL_ERROR_OK \
475     : CV_HAL_ERROR_NOT_IMPLEMENTED \
476 )
477 
478 #define TEGRA_ABSDIFF(src1, sz1, src2, sz2, dst, sz, w, h) \
479 ( \
480     CAROTENE_NS::isSupportedConfiguration() ? \
481     CAROTENE_NS::absDiff(CAROTENE_NS::Size2D(w, h), \
482                      src1, sz1, \
483                      src2, sz2, \
484                      dst, sz), \
485     CV_HAL_ERROR_OK \
486     : CV_HAL_ERROR_NOT_IMPLEMENTED \
487 )
488 
489 #define TEGRA_AND(src1, sz1, src2, sz2, dst, sz, w, h) \
490 ( \
491     CAROTENE_NS::isSupportedConfiguration() ? \
492     CAROTENE_NS::bitwiseAnd(CAROTENE_NS::Size2D(w, h), \
493                      src1, sz1, \
494                      src2, sz2, \
495                      dst, sz), \
496     CV_HAL_ERROR_OK \
497     : CV_HAL_ERROR_NOT_IMPLEMENTED \
498 )
499 #define TEGRA_OR(src1, sz1, src2, sz2, dst, sz, w, h) \
500 ( \
501     CAROTENE_NS::isSupportedConfiguration() ? \
502     CAROTENE_NS::bitwiseOr(CAROTENE_NS::Size2D(w, h), \
503                      src1, sz1, \
504                      src2, sz2, \
505                      dst, sz), \
506     CV_HAL_ERROR_OK \
507     : CV_HAL_ERROR_NOT_IMPLEMENTED \
508 )
509 
510 #define TEGRA_XOR(src1, sz1, src2, sz2, dst, sz, w, h) \
511 ( \
512     CAROTENE_NS::isSupportedConfiguration() ? \
513     CAROTENE_NS::bitwiseXor(CAROTENE_NS::Size2D(w, h), \
514                      src1, sz1, \
515                      src2, sz2, \
516                      dst, sz), \
517     CV_HAL_ERROR_OK \
518     : CV_HAL_ERROR_NOT_IMPLEMENTED \
519 )
520 
521 #define TEGRA_NOT(src1, sz1, dst, sz, w, h) \
522 ( \
523     CAROTENE_NS::isSupportedConfiguration() ? \
524     CAROTENE_NS::bitwiseNot(CAROTENE_NS::Size2D(w, h), \
525                      src1, sz1, \
526                      dst, sz), \
527     CV_HAL_ERROR_OK \
528     : CV_HAL_ERROR_NOT_IMPLEMENTED \
529 )
530 
531 #undef cv_hal_add8u
532 #define cv_hal_add8u TEGRA_ADD
533 #undef cv_hal_add8s
534 #define cv_hal_add8s TEGRA_ADD
535 #undef cv_hal_add16u
536 #define cv_hal_add16u TEGRA_ADD
537 #undef cv_hal_add16s
538 #define cv_hal_add16s TEGRA_ADD
539 #undef cv_hal_add32s
540 #define cv_hal_add32s TEGRA_ADD
541 #undef cv_hal_add32f
542 #define cv_hal_add32f TEGRA_ADDF
543 //#undef cv_hal_add64f
544 //#define cv_hal_add64f TEGRA_ADDF
545 #undef cv_hal_sub8u
546 #define cv_hal_sub8u TEGRA_SUB
547 #undef cv_hal_sub8s
548 #define cv_hal_sub8s TEGRA_SUB
549 #undef cv_hal_sub16u
550 #define cv_hal_sub16u TEGRA_SUB
551 #undef cv_hal_sub16s
552 #define cv_hal_sub16s TEGRA_SUB
553 #undef cv_hal_sub32s
554 #define cv_hal_sub32s TEGRA_SUB
555 #undef cv_hal_sub32f
556 #define cv_hal_sub32f TEGRA_SUBF
557 //#undef cv_hal_sub64f
558 //#define cv_hal_sub64f TEGRA_SUBF
559 #undef cv_hal_max8u
560 #define cv_hal_max8u TEGRA_MAX
561 #undef cv_hal_max8s
562 #define cv_hal_max8s TEGRA_MAX
563 #undef cv_hal_max16u
564 #define cv_hal_max16u TEGRA_MAX
565 #undef cv_hal_max16s
566 #define cv_hal_max16s TEGRA_MAX
567 #undef cv_hal_max32s
568 #define cv_hal_max32s TEGRA_MAX
569 #undef cv_hal_max32f
570 #define cv_hal_max32f TEGRA_MAX
571 //#undef cv_hal_max64f
572 //#define cv_hal_max64f TEGRA_MAX
573 #undef cv_hal_min8u
574 #define cv_hal_min8u TEGRA_MIN
575 #undef cv_hal_min8s
576 #define cv_hal_min8s TEGRA_MIN
577 #undef cv_hal_min16u
578 #define cv_hal_min16u TEGRA_MIN
579 #undef cv_hal_min16s
580 #define cv_hal_min16s TEGRA_MIN
581 #undef cv_hal_min32s
582 #define cv_hal_min32s TEGRA_MIN
583 #undef cv_hal_min32f
584 #define cv_hal_min32f TEGRA_MIN
585 //#undef cv_hal_min64f
586 //#define cv_hal_min64f TEGRA_MIN
587 #undef cv_hal_absdiff8u
588 #define cv_hal_absdiff8u TEGRA_ABSDIFF
589 #undef cv_hal_absdiff8s
590 #define cv_hal_absdiff8s TEGRA_ABSDIFF
591 #undef cv_hal_absdiff16u
592 #define cv_hal_absdiff16u TEGRA_ABSDIFF
593 #undef cv_hal_absdiff16s
594 #define cv_hal_absdiff16s TEGRA_ABSDIFF
595 #undef cv_hal_absdiff32s
596 #define cv_hal_absdiff32s TEGRA_ABSDIFF
597 #undef cv_hal_absdiff32f
598 #define cv_hal_absdiff32f TEGRA_ABSDIFF
599 //#undef cv_hal_absdiff64f
600 //#define cv_hal_absdiff64f TEGRA_ABSDIFF
601 #undef cv_hal_and8u
602 #define cv_hal_and8u TEGRA_AND
603 #undef cv_hal_or8u
604 #define cv_hal_or8u TEGRA_OR
605 #undef cv_hal_xor8u
606 #define cv_hal_xor8u TEGRA_XOR
607 #undef cv_hal_not8u
608 #define cv_hal_not8u TEGRA_NOT
609 
610 #define TEGRA_CMP(src1, sz1, src2, sz2, dst, sz, w, h, op) \
611 ( \
612     CAROTENE_NS::isSupportedConfiguration() ? \
613         ((op) == cv::CMP_EQ) ? \
614         CAROTENE_NS::cmpEQ(CAROTENE_NS::Size2D(w, h), \
615                            src1, sz1, \
616                            src2, sz2, \
617                            dst, sz), \
618         CV_HAL_ERROR_OK : \
619         ((op) == cv::CMP_NE) ? \
620         CAROTENE_NS::cmpNE(CAROTENE_NS::Size2D(w, h), \
621                            src1, sz1, \
622                            src2, sz2, \
623                            dst, sz), \
624         CV_HAL_ERROR_OK : \
625         ((op) == cv::CMP_GT) ? \
626         CAROTENE_NS::cmpGT(CAROTENE_NS::Size2D(w, h), \
627                            src1, sz1, \
628                            src2, sz2, \
629                            dst, sz), \
630         CV_HAL_ERROR_OK : \
631         ((op) == cv::CMP_GE) ? \
632         CAROTENE_NS::cmpGE(CAROTENE_NS::Size2D(w, h), \
633                            src1, sz1, \
634                            src2, sz2, \
635                            dst, sz), \
636         CV_HAL_ERROR_OK : \
637         ((op) == cv::CMP_LT) ? \
638         CAROTENE_NS::cmpGT(CAROTENE_NS::Size2D(w, h), \
639                            src2, sz2, \
640                            src1, sz1, \
641                            dst, sz), \
642         CV_HAL_ERROR_OK : \
643         ((op) == cv::CMP_LE) ? \
644         CAROTENE_NS::cmpGE(CAROTENE_NS::Size2D(w, h), \
645                            src2, sz2, \
646                            src1, sz1, \
647                            dst, sz), \
648         CV_HAL_ERROR_OK : \
649         CV_HAL_ERROR_NOT_IMPLEMENTED \
650     : CV_HAL_ERROR_NOT_IMPLEMENTED \
651 )
652 
653 #undef cv_hal_cmp8u
654 #define cv_hal_cmp8u TEGRA_CMP
655 #undef cv_hal_cmp8s
656 #define cv_hal_cmp8s TEGRA_CMP
657 #undef cv_hal_cmp16u
658 #define cv_hal_cmp16u TEGRA_CMP
659 #undef cv_hal_cmp16s
660 #define cv_hal_cmp16s TEGRA_CMP
661 #undef cv_hal_cmp32s
662 #define cv_hal_cmp32s TEGRA_CMP
663 #undef cv_hal_cmp32f
664 #define cv_hal_cmp32f TEGRA_CMP
665 //#undef cv_hal_cmp64f
666 //#define cv_hal_cmp64f TEGRA_CMP
667 
668 #define TEGRA_MUL(src1, sz1, src2, sz2, dst, sz, w, h, scale) \
669 ( \
670     CAROTENE_NS::isSupportedConfiguration() ? \
671     CAROTENE_NS::mul(CAROTENE_NS::Size2D(w, h), \
672                      src1, sz1, \
673                      src2, sz2, \
674                      dst, sz, \
675                      scale, \
676                      CAROTENE_NS::CONVERT_POLICY_SATURATE), \
677     CV_HAL_ERROR_OK \
678     : CV_HAL_ERROR_NOT_IMPLEMENTED \
679 )
680 
681 #define TEGRA_MULF(src1, sz1, src2, sz2, dst, sz, w, h, scale) \
682 ( \
683     CAROTENE_NS::isSupportedConfiguration() ? \
684     CAROTENE_NS::mul(CAROTENE_NS::Size2D(w, h), \
685                      src1, sz1, \
686                      src2, sz2, \
687                      dst, sz, \
688                      (float)scale), \
689     CV_HAL_ERROR_OK \
690     : CV_HAL_ERROR_NOT_IMPLEMENTED \
691 )
692 
693 #define TEGRA_DIV(src1, sz1, src2, sz2, dst, sz, w, h, scale) \
694 ( \
695     CAROTENE_NS::isSupportedConfiguration() ? \
696     CAROTENE_NS::div(CAROTENE_NS::Size2D(w, h), \
697                      src1, sz1, \
698                      src2, sz2, \
699                      dst, sz, \
700                      scale, \
701                      CAROTENE_NS::CONVERT_POLICY_SATURATE), \
702     CV_HAL_ERROR_OK \
703     : CV_HAL_ERROR_NOT_IMPLEMENTED \
704 )
705 
706 #define TEGRA_DIVF(src1, sz1, src2, sz2, dst, sz, w, h, scale) \
707 ( \
708     CAROTENE_NS::isSupportedConfiguration() ? \
709     CAROTENE_NS::div(CAROTENE_NS::Size2D(w, h), \
710                      src1, sz1, \
711                      src2, sz2, \
712                      dst, sz, \
713                      (float)scale), \
714     CV_HAL_ERROR_OK \
715     : CV_HAL_ERROR_NOT_IMPLEMENTED \
716 )
717 
718 #define TEGRA_RECIP(src2, sz2, dst, sz, w, h, scale) \
719 ( \
720     CAROTENE_NS::isSupportedConfiguration() ? \
721     CAROTENE_NS::reciprocal(CAROTENE_NS::Size2D(w, h), \
722                             src2, sz2, \
723                             dst, sz, \
724                             scale, \
725                             CAROTENE_NS::CONVERT_POLICY_SATURATE), \
726     CV_HAL_ERROR_OK \
727     : CV_HAL_ERROR_NOT_IMPLEMENTED \
728 )
729 
730 #define TEGRA_RECIPF(src2, sz2, dst, sz, w, h, scale) \
731 ( \
732     CAROTENE_NS::isSupportedConfiguration() ? \
733     CAROTENE_NS::reciprocal(CAROTENE_NS::Size2D(w, h), \
734                             src2, sz2, \
735                             dst, sz, \
736                             (float)scale), \
737     CV_HAL_ERROR_OK \
738     : CV_HAL_ERROR_NOT_IMPLEMENTED \
739 )
740 
741 #undef cv_hal_mul8u
742 #define cv_hal_mul8u TEGRA_MUL
743 #undef cv_hal_mul8s
744 #define cv_hal_mul8s TEGRA_MUL
745 #undef cv_hal_mul16u
746 #define cv_hal_mul16u TEGRA_MUL
747 #undef cv_hal_mul16s
748 #define cv_hal_mul16s TEGRA_MUL
749 #undef cv_hal_mul32s
750 #define cv_hal_mul32s TEGRA_MUL
751 #undef cv_hal_mul32f
752 #define cv_hal_mul32f TEGRA_MULF
753 //#undef cv_hal_mul64f
754 //#define cv_hal_mul64f TEGRA_MULF
755 #undef cv_hal_div8u
756 #define cv_hal_div8u TEGRA_DIV
757 #undef cv_hal_div8s
758 #define cv_hal_div8s TEGRA_DIV
759 #undef cv_hal_div16u
760 #define cv_hal_div16u TEGRA_DIV
761 #undef cv_hal_div16s
762 #define cv_hal_div16s TEGRA_DIV
763 #undef cv_hal_div32s
764 #define cv_hal_div32s TEGRA_DIV
765 #undef cv_hal_div32f
766 #define cv_hal_div32f TEGRA_DIVF
767 //#undef cv_hal_div64f
768 //#define cv_hal_div64f TEGRA_DIVF
769 #undef cv_hal_recip8u
770 #define cv_hal_recip8u TEGRA_RECIP
771 #undef cv_hal_recip8s
772 #define cv_hal_recip8s TEGRA_RECIP
773 #undef cv_hal_recip16u
774 #define cv_hal_recip16u TEGRA_RECIP
775 #undef cv_hal_recip16s
776 #define cv_hal_recip16s TEGRA_RECIP
777 #undef cv_hal_recip32s
778 #define cv_hal_recip32s TEGRA_RECIP
779 #undef cv_hal_recip32f
780 #define cv_hal_recip32f TEGRA_RECIPF
781 //#undef cv_hal_recip64f
782 //#define cv_hal_recip64f TEGRA_RECIPF
783 
784 #define TEGRA_ADDWEIGHTED(src1, sz1, src2, sz2, dst, sz, w, h, scales) \
785 ( \
786     CAROTENE_NS::isSupportedConfiguration() ? \
787     CAROTENE_NS::addWeighted(CAROTENE_NS::Size2D(w, h), \
788                              src1, sz1, \
789                              src2, sz2, \
790                              dst, sz, \
791                              ((double *)scales)[0], ((double *)scales)[1], ((double *)scales)[2]), \
792     CV_HAL_ERROR_OK \
793     : CV_HAL_ERROR_NOT_IMPLEMENTED \
794 )
795 
796 #undef cv_hal_addWeighted8u
797 #define cv_hal_addWeighted8u TEGRA_ADDWEIGHTED
798 #undef cv_hal_addWeighted8s
799 #define cv_hal_addWeighted8s TEGRA_ADDWEIGHTED
800 #undef cv_hal_addWeighted16u
801 #define cv_hal_addWeighted16u TEGRA_ADDWEIGHTED
802 #undef cv_hal_addWeighted16s
803 #define cv_hal_addWeighted16s TEGRA_ADDWEIGHTED
804 #undef cv_hal_addWeighted32s
805 #define cv_hal_addWeighted32s TEGRA_ADDWEIGHTED
806 //#undef cv_hal_addWeighted32f
807 //#define cv_hal_addWeighted32f TEGRA_ADDWEIGHTED
808 //#undef cv_hal_addWeighted64f
809 //#define cv_hal_addWeighted64f TEGRA_ADDWEIGHTED
810 
811 #endif //PARALLEL_CORE
812 
813 #define ROW_SRC_ARG1 const ST * src1_data_
814 #define ROW_SRC_STORE1 , src1_data(src1_data_)
815 #define ROW_SRC_VAR1 const ST * src1_data;
816 #define ROW_SRC_ARG2 ROW_SRC_ARG1 \
817                      , const ST * src2_data_
818 #define ROW_SRC_STORE2 ROW_SRC_STORE1 \
819                        , src2_data(src2_data_)
820 #define ROW_SRC_VAR2 ROW_SRC_VAR1 \
821                      const ST * src2_data;
822 #define ROW_SRC_ARG3 ROW_SRC_ARG2 \
823                      , const ST * src3_data_
824 #define ROW_SRC_STORE3 ROW_SRC_STORE2 \
825                        , src3_data(src3_data_)
826 #define ROW_SRC_VAR3 ROW_SRC_VAR2 \
827                      const ST * src3_data;
828 #define ROW_SRC_ARG4 ROW_SRC_ARG3 \
829                      , const ST * src4_data_
830 #define ROW_SRC_STORE4 ROW_SRC_STORE3 \
831                        , src4_data(src4_data_)
832 #define ROW_SRC_VAR4 ROW_SRC_VAR3 \
833                      const ST * src4_data;
834 
835 #define ROW_DST_ARG1 , DT * dst1_data_
836 #define ROW_DST_STORE1 , dst1_data(dst1_data_)
837 #define ROW_DST_VAR1 DT * dst1_data;
838 #define ROW_DST_ARG2 ROW_DST_ARG1 \
839                      , DT * dst2_data_
840 #define ROW_DST_STORE2 ROW_DST_STORE1 \
841                        , dst2_data(dst2_data_)
842 #define ROW_DST_VAR2 ROW_DST_VAR1 \
843                      DT * dst2_data;
844 #define ROW_DST_ARG3 ROW_DST_ARG2 \
845                      , DT * dst3_data_
846 #define ROW_DST_STORE3 ROW_DST_STORE2 \
847                        , dst3_data(dst3_data_)
848 #define ROW_DST_VAR3 ROW_DST_VAR2 \
849                      DT * dst3_data;
850 #define ROW_DST_ARG4 ROW_DST_ARG3 \
851                      , DT * dst4_data_
852 #define ROW_DST_STORE4 ROW_DST_STORE3 \
853                        , dst4_data(dst4_data_)
854 #define ROW_DST_VAR4 ROW_DST_VAR3 \
855                      DT * dst4_data;
856 
857 #define ROW_VAL_ARG0
858 #define ROW_VAL_STORE0
859 #define ROW_VAL_VAR0
860 #define ROW_VAL_ARG1 , double val_
861 #define ROW_VAL_STORE1 , val(val_)
862 #define ROW_VAL_VAR1 double val;
863 
864 #define TegraRowOp_Invoker(name, func, src_cnt, dst_cnt, val_cnt, ...) \
865 template <typename ST, typename DT> \
866 class TegraRowOp_##name##_Invoker : public cv::ParallelLoopBody \
867 { \
868 public: \
869     TegraRowOp_##name##_Invoker(ROW_SRC_ARG##src_cnt \
870                                 ROW_DST_ARG##dst_cnt \
871                                 ROW_VAL_ARG##val_cnt) : \
872          cv::ParallelLoopBody() ROW_SRC_STORE##src_cnt \
873                                 ROW_DST_STORE##dst_cnt \
874                                 ROW_VAL_STORE##val_cnt {} \
875     virtual void operator()(const cv::Range& range) const \
876     { \
877         CAROTENE_NS::func(CAROTENE_NS::Size2D(range.end-range.start, 1), __VA_ARGS__); \
878     } \
879 private: \
880     ROW_SRC_VAR##src_cnt \
881     ROW_DST_VAR##dst_cnt \
882     ROW_VAL_VAR##val_cnt \
883     const TegraRowOp_##name##_Invoker& operator= (const TegraRowOp_##name##_Invoker&); \
884 };
885 
886 
887 #define TEGRA_SPLIT(src, dst, len, cn) \
888 ( \
889     CAROTENE_NS::isSupportedConfiguration() ? \
890         cn == 2 ? \
891         CAROTENE_NS::split2(CAROTENE_NS::Size2D(len, 1), \
892                             src, len, \
893                             dst[0], len, \
894                             dst[1], len), \
895         CV_HAL_ERROR_OK : \
896         cn == 3 ? \
897         CAROTENE_NS::split3(CAROTENE_NS::Size2D(len, 1), \
898                             src, len, \
899                             dst[0], len, \
900                             dst[1], len, \
901                             dst[2], len), \
902         CV_HAL_ERROR_OK : \
903         cn == 4 ? \
904         CAROTENE_NS::split4(CAROTENE_NS::Size2D(len, 1), \
905                             src, len, \
906                             dst[0], len, \
907                             dst[1], len, \
908                             dst[2], len, \
909                             dst[3], len), \
910         CV_HAL_ERROR_OK : \
911         CV_HAL_ERROR_NOT_IMPLEMENTED \
912     : CV_HAL_ERROR_NOT_IMPLEMENTED \
913 )
914 
915 TegraRowOp_Invoker(split2, split2, 1, 2, 0, RANGE_DATA(ST, src1_data, 2*sizeof(ST)), range.end-range.start,
916                                             RANGE_DATA(DT, dst1_data, sizeof(DT)), range.end-range.start,
917                                             RANGE_DATA(DT, dst2_data, sizeof(DT)), range.end-range.start)
918 TegraRowOp_Invoker(split3, split3, 1, 3, 0, RANGE_DATA(ST, src1_data, 3*sizeof(ST)), range.end-range.start,
919                                             RANGE_DATA(DT, dst1_data, sizeof(DT)), range.end-range.start,
920                                             RANGE_DATA(DT, dst2_data, sizeof(DT)), range.end-range.start,
921                                             RANGE_DATA(DT, dst3_data, sizeof(DT)), range.end-range.start)
922 TegraRowOp_Invoker(split4, split4, 1, 4, 0, RANGE_DATA(ST, src1_data, 4*sizeof(ST)), range.end-range.start,
923                                             RANGE_DATA(DT, dst1_data, sizeof(DT)), range.end-range.start,
924                                             RANGE_DATA(DT, dst2_data, sizeof(DT)), range.end-range.start,
925                                             RANGE_DATA(DT, dst3_data, sizeof(DT)), range.end-range.start,
926                                             RANGE_DATA(DT, dst4_data, sizeof(DT)), range.end-range.start)
927 #define TEGRA_SPLIT64S(type, src, dst, len, cn) \
928 ( \
929     CAROTENE_NS::isSupportedConfiguration() ? \
930         cn == 2 ? \
931         parallel_for_(Range(0, len), \
932         TegraRowOp_split2_Invoker<const type, type>(src, dst[0], dst[1]), \
933         (len) / static_cast<double>(1<<16)), \
934         CV_HAL_ERROR_OK : \
935         cn == 3 ? \
936         parallel_for_(Range(0, len), \
937         TegraRowOp_split3_Invoker<const type, type>(src, dst[0], dst[1], dst[2]), \
938         (len) / static_cast<double>(1<<16)), \
939         CV_HAL_ERROR_OK : \
940         cn == 4 ? \
941         parallel_for_(Range(0, len), \
942         TegraRowOp_split4_Invoker<const type, type>(src, dst[0], dst[1], dst[2], dst[3]), \
943         (len) / static_cast<double>(1<<16)), \
944         CV_HAL_ERROR_OK : \
945         CV_HAL_ERROR_NOT_IMPLEMENTED \
946     : CV_HAL_ERROR_NOT_IMPLEMENTED \
947 )
948 
949 #define TEGRA_MERGE(src, dst, len, cn) \
950 ( \
951     CAROTENE_NS::isSupportedConfiguration() ? \
952         cn == 2 ? \
953         CAROTENE_NS::combine2(CAROTENE_NS::Size2D(len, 1), \
954                               src[0], len, \
955                               src[1], len, \
956                               dst, len), \
957         CV_HAL_ERROR_OK : \
958         cn == 3 ? \
959         CAROTENE_NS::combine3(CAROTENE_NS::Size2D(len, 1), \
960                               src[0], len, \
961                               src[1], len, \
962                               src[2], len, \
963                               dst, len), \
964         CV_HAL_ERROR_OK : \
965         cn == 4 ? \
966         CAROTENE_NS::combine4(CAROTENE_NS::Size2D(len, 1), \
967                               src[0], len, \
968                               src[1], len, \
969                               src[2], len, \
970                               src[3], len, \
971                               dst, len), \
972         CV_HAL_ERROR_OK : \
973         CV_HAL_ERROR_NOT_IMPLEMENTED \
974     : CV_HAL_ERROR_NOT_IMPLEMENTED \
975 )
976 
977 TegraRowOp_Invoker(combine2, combine2, 2, 1, 0, RANGE_DATA(ST, src1_data, sizeof(ST)), range.end-range.start,
978                                                 RANGE_DATA(ST, src2_data, sizeof(ST)), range.end-range.start,
979                                                 RANGE_DATA(DT, dst1_data, 2*sizeof(DT)), range.end-range.start)
980 TegraRowOp_Invoker(combine3, combine3, 3, 1, 0, RANGE_DATA(ST, src1_data, sizeof(ST)), range.end-range.start,
981                                                 RANGE_DATA(ST, src2_data, sizeof(ST)), range.end-range.start,
982                                                 RANGE_DATA(ST, src3_data, sizeof(ST)), range.end-range.start,
983                                                 RANGE_DATA(DT, dst1_data, 3*sizeof(DT)), range.end-range.start)
984 TegraRowOp_Invoker(combine4, combine4, 4, 1, 0, RANGE_DATA(ST, src1_data, sizeof(ST)), range.end-range.start,
985                                                 RANGE_DATA(ST, src2_data, sizeof(ST)), range.end-range.start,
986                                                 RANGE_DATA(ST, src3_data, sizeof(ST)), range.end-range.start,
987                                                 RANGE_DATA(ST, src4_data, sizeof(ST)), range.end-range.start,
988                                                 RANGE_DATA(DT, dst1_data, 4*sizeof(DT)), range.end-range.start)
989 #define TEGRA_MERGE64S(type, src, dst, len, cn) \
990 ( \
991     CAROTENE_NS::isSupportedConfiguration() ? \
992         cn == 2 ? \
993         parallel_for_(Range(0, len), \
994         TegraRowOp_combine2_Invoker<const type, type>(src[0], src[1], dst), \
995         (len) / static_cast<double>(1<<16)), \
996         CV_HAL_ERROR_OK : \
997         cn == 3 ? \
998         parallel_for_(Range(0, len), \
999         TegraRowOp_combine3_Invoker<const type, type>(src[0], src[1], src[2], dst), \
1000         (len) / static_cast<double>(1<<16)), \
1001         CV_HAL_ERROR_OK : \
1002         cn == 4 ? \
1003         parallel_for_(Range(0, len), \
1004         TegraRowOp_combine4_Invoker<const type, type>(src[0], src[1], src[2], src[3], dst), \
1005         (len) / static_cast<double>(1<<16)), \
1006         CV_HAL_ERROR_OK : \
1007         CV_HAL_ERROR_NOT_IMPLEMENTED \
1008     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1009 )
1010 
1011 #undef cv_hal_split8u
1012 #define cv_hal_split8u TEGRA_SPLIT
1013 #undef cv_hal_split16u
1014 #define cv_hal_split16u TEGRA_SPLIT
1015 #undef cv_hal_split32s
1016 #define cv_hal_split32s TEGRA_SPLIT
1017 #undef cv_hal_split64s
1018 #define cv_hal_split64s(src, dst, len, cn) TEGRA_SPLIT64S(CAROTENE_NS::s64, src, dst, len, cn)
1019 
1020 #undef cv_hal_merge8u
1021 #define cv_hal_merge8u TEGRA_MERGE
1022 #undef cv_hal_merge16u
1023 #define cv_hal_merge16u TEGRA_MERGE
1024 #undef cv_hal_merge32s
1025 #define cv_hal_merge32s TEGRA_MERGE
1026 #undef cv_hal_merge64s
1027 #define cv_hal_merge64s(src, dst, len, cn) TEGRA_MERGE64S(CAROTENE_NS::s64, src, dst, len, cn)
1028 
1029 
1030 TegraRowOp_Invoker(phase, phase, 2, 1, 1, RANGE_DATA(ST, src1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start,
1031                                           RANGE_DATA(ST, src2_data, sizeof(CAROTENE_NS::f32)), range.end-range.start,
1032                                           RANGE_DATA(DT, dst1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start, val)
1033 #define TEGRA_FASTATAN(y, x, dst, len, angleInDegrees) \
1034 ( \
1035     CAROTENE_NS::isSupportedConfiguration() ? \
1036     parallel_for_(Range(0, len), \
1037     TegraRowOp_phase_Invoker<const CAROTENE_NS::f32, CAROTENE_NS::f32>(x, y, dst, angleInDegrees ? 1.0f : M_PI/180), \
1038     (len) / static_cast<double>(1<<16)), \
1039     CV_HAL_ERROR_OK \
1040     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1041 )
1042 
1043 #undef cv_hal_fastAtan32f
1044 #define cv_hal_fastAtan32f TEGRA_FASTATAN
1045 
1046 TegraRowOp_Invoker(magnitude, magnitude, 2, 1, 0, RANGE_DATA(ST, src1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start,
1047                                                   RANGE_DATA(ST, src2_data, sizeof(CAROTENE_NS::f32)), range.end-range.start,
1048                                                   RANGE_DATA(DT, dst1_data, sizeof(CAROTENE_NS::f32)), range.end-range.start)
1049 #define TEGRA_MAGNITUDE(x, y, dst, len) \
1050 ( \
1051     CAROTENE_NS::isSupportedConfiguration() ? \
1052     parallel_for_(Range(0, len), \
1053     TegraRowOp_magnitude_Invoker<const CAROTENE_NS::f32, CAROTENE_NS::f32>(x, y, dst), \
1054     (len) / static_cast<double>(1<<16)), \
1055     CV_HAL_ERROR_OK \
1056     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1057 )
1058 
1059 #undef cv_hal_magnitude32f
1060 #define cv_hal_magnitude32f TEGRA_MAGNITUDE
1061 
1062 
1063 #if defined OPENCV_IMGPROC_HAL_INTERFACE_H
1064 
1065 struct cvhalFilter2D;
1066 
1067 struct FilterCtx
1068 {
1069     CAROTENE_NS::Size2D ksize;
1070     CAROTENE_NS::s16* kernel_data;
1071     CAROTENE_NS::BORDER_MODE border;
1072 };
TEGRA_FILTERINIT(cvhalFilter2D ** context,uchar * kernel_data,size_t kernel_step,int kernel_type,int kernel_width,int kernel_height,int max_width,int max_height,int src_type,int dst_type,int borderType,double delta,int anchor_x,int anchor_y,bool allowSubmatrix,bool allowInplace)1073 inline int TEGRA_FILTERINIT(cvhalFilter2D **context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
1074                             int max_width, int max_height, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace)
1075 {
1076     if(!context || !kernel_data || allowSubmatrix || allowInplace ||
1077        src_type != CV_8UC1 || dst_type != CV_8UC1 ||
1078        delta != 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2 )
1079         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1080 
1081     FilterCtx* ctx = new FilterCtx;
1082     if(!ctx)
1083         return CV_HAL_ERROR_UNKNOWN;
1084     ctx->ksize.width = kernel_width;
1085     ctx->ksize.height = kernel_height;
1086     switch(borderType)
1087     {
1088     case CV_HAL_BORDER_CONSTANT:
1089         ctx->border = CAROTENE_NS::BORDER_MODE_CONSTANT;
1090         break;
1091     case CV_HAL_BORDER_REPLICATE:
1092         ctx->border = CAROTENE_NS::BORDER_MODE_REPLICATE;
1093         break;
1094     case CV_HAL_BORDER_REFLECT:
1095         ctx->border = CAROTENE_NS::BORDER_MODE_REFLECT;
1096         break;
1097     case CV_HAL_BORDER_WRAP:
1098         ctx->border = CAROTENE_NS::BORDER_MODE_WRAP;
1099         break;
1100     case CV_HAL_BORDER_REFLECT_101:
1101         ctx->border = CAROTENE_NS::BORDER_MODE_REFLECT101;
1102         break;
1103     default:
1104         delete ctx;
1105         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1106     }
1107 
1108     if(!CAROTENE_NS::isConvolutionSupported(CAROTENE_NS::Size2D(max_width, max_height), ctx->ksize, ctx->border))
1109     {
1110         delete ctx;
1111         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1112     }
1113 
1114     ctx->kernel_data = new CAROTENE_NS::s16[kernel_width*kernel_height];
1115     if(!ctx->kernel_data)
1116         return CV_HAL_ERROR_UNKNOWN;
1117     switch(kernel_type)
1118     {
1119     case CV_8UC1:
1120         convert(ctx->ksize, (CAROTENE_NS::u8*)kernel_data, kernel_step, ctx->kernel_data, kernel_width);
1121         break;
1122     case CV_8SC1:
1123         convert(ctx->ksize, (CAROTENE_NS::s8*)kernel_data, kernel_step, ctx->kernel_data, kernel_width);
1124         break;
1125     case CV_16UC1:
1126         for(int j = 0; j < kernel_height; ++j)
1127         {
1128             std::memcpy(ctx->kernel_data + kernel_width * j, kernel_data + kernel_step * j, kernel_width * sizeof(int16_t));
1129         }
1130         break;
1131     default:
1132         delete[] ctx->kernel_data;
1133         delete ctx;
1134         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1135     }
1136 
1137     *context = (cvhalFilter2D*)(ctx);
1138     return CV_HAL_ERROR_OK;
1139 }
TEGRA_FILTERFREE(cvhalFilter2D * context)1140 inline int TEGRA_FILTERFREE(cvhalFilter2D *context)
1141 {
1142     if(context)
1143     {
1144         if(((FilterCtx*)context)->kernel_data)
1145             delete[] ((FilterCtx*)context)->kernel_data;
1146         delete (FilterCtx*)context;
1147         return CV_HAL_ERROR_OK;
1148     }
1149     else
1150     {
1151         return CV_HAL_ERROR_UNKNOWN;
1152     }
1153 }
1154 #define TEGRA_FILTERIMPL(context, src_data, src_step, dst_data, dst_step, width, height, full_width, full_height, offset_x, offset_y) \
1155 ( \
1156     (void)full_width, (void)full_height, (void)offset_x, (void)offset_y, \
1157     context && CAROTENE_NS::isConvolutionSupported(CAROTENE_NS::Size2D(width, height), ((FilterCtx*)context)->ksize, ((FilterCtx*)context)->border) ? \
1158     CAROTENE_NS::convolution(CAROTENE_NS::Size2D(width, height), \
1159                              src_data, src_step, \
1160                              dst_data, dst_step, \
1161                              ((FilterCtx*)context)->border, 0, \
1162                              ((FilterCtx*)context)->ksize, ((FilterCtx*)context)->kernel_data, 1), \
1163     CV_HAL_ERROR_OK \
1164     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1165 )
1166 
1167 #undef cv_hal_filterInit
1168 #define cv_hal_filterInit TEGRA_FILTERINIT
1169 #undef cv_hal_filter
1170 #define cv_hal_filter TEGRA_FILTERIMPL
1171 #undef cv_hal_filterFree
1172 #define cv_hal_filterFree TEGRA_FILTERFREE
1173 
1174 
1175 struct SepFilterCtx
1176 {
1177     int16_t kernelx_data[3];
1178     int16_t kernely_data[3];
1179     CAROTENE_NS::BORDER_MODE border;
1180 };
TEGRA_SEPFILTERINIT(cvhalFilter2D ** context,int src_type,int dst_type,int kernel_type,uchar * kernelx_data,int kernelx_length,uchar * kernely_data,int kernely_length,int anchor_x,int anchor_y,double delta,int borderType)1181 inline int TEGRA_SEPFILTERINIT(cvhalFilter2D **context, int src_type, int dst_type, int kernel_type,
1182                                uchar *kernelx_data, int kernelx_length,
1183                                uchar *kernely_data, int kernely_length,
1184                                int anchor_x, int anchor_y, double delta, int borderType)
1185 {
1186     if(!context || !kernelx_data || !kernely_data || src_type != CV_8UC1 || dst_type != CV_16SC1 ||
1187        kernelx_length != 3 || kernely_length != 3 ||
1188        delta != 0 || anchor_x != 1 || anchor_y != 1)
1189         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1190 
1191     SepFilterCtx* ctx = new SepFilterCtx;
1192     if(!ctx)
1193         return CV_HAL_ERROR_UNKNOWN;
1194     switch(borderType)
1195     {
1196     case CV_HAL_BORDER_CONSTANT:
1197         ctx->border = CAROTENE_NS::BORDER_MODE_CONSTANT;
1198         break;
1199     case CV_HAL_BORDER_REPLICATE:
1200         ctx->border = CAROTENE_NS::BORDER_MODE_REPLICATE;
1201         break;
1202     case CV_HAL_BORDER_REFLECT:
1203         ctx->border = CAROTENE_NS::BORDER_MODE_REFLECT;
1204         break;
1205     case CV_HAL_BORDER_WRAP:
1206         ctx->border = CAROTENE_NS::BORDER_MODE_WRAP;
1207         break;
1208     case CV_HAL_BORDER_REFLECT_101:
1209         ctx->border = CAROTENE_NS::BORDER_MODE_REFLECT101;
1210         break;
1211     default:
1212         delete ctx;
1213         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1214     }
1215 
1216     if(!CAROTENE_NS::isSeparableFilter3x3Supported(CAROTENE_NS::Size2D(16, 16), ctx->border, 3, 3))
1217     {
1218         delete ctx;
1219         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1220     }
1221 
1222     switch(kernel_type)
1223     {
1224     case CV_8UC1:
1225         ctx->kernelx_data[0]=kernelx_data[0];
1226         ctx->kernelx_data[1]=kernelx_data[1];
1227         ctx->kernelx_data[2]=kernelx_data[2];
1228         ctx->kernely_data[0]=kernely_data[0];
1229         ctx->kernely_data[1]=kernely_data[1];
1230         ctx->kernely_data[2]=kernely_data[2];
1231         break;
1232     case CV_8SC1:
1233         ctx->kernelx_data[0]=((char*)kernelx_data)[0];
1234         ctx->kernelx_data[1]=((char*)kernelx_data)[1];
1235         ctx->kernelx_data[2]=((char*)kernelx_data)[2];
1236         ctx->kernely_data[0]=((char*)kernely_data)[0];
1237         ctx->kernely_data[1]=((char*)kernely_data)[1];
1238         ctx->kernely_data[2]=((char*)kernely_data)[2];
1239         break;
1240     case CV_16UC1:
1241         ctx->kernelx_data[0]=((int16_t*)kernelx_data)[0];
1242         ctx->kernelx_data[1]=((int16_t*)kernelx_data)[1];
1243         ctx->kernelx_data[2]=((int16_t*)kernelx_data)[2];
1244         ctx->kernely_data[0]=((int16_t*)kernely_data)[0];
1245         ctx->kernely_data[1]=((int16_t*)kernely_data)[1];
1246         ctx->kernely_data[2]=((int16_t*)kernely_data)[2];
1247         break;
1248     default:
1249         delete ctx;
1250         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1251     }
1252 
1253     *context = (cvhalFilter2D*)(ctx);
1254     return CV_HAL_ERROR_OK;
1255 }
TEGRA_SEPFILTERFREE(cvhalFilter2D * context)1256 inline int TEGRA_SEPFILTERFREE(cvhalFilter2D *context)
1257 {
1258     if(context)
1259     {
1260         delete (SepFilterCtx*)context;
1261         return CV_HAL_ERROR_OK;
1262     }
1263     else
1264     {
1265         return CV_HAL_ERROR_UNKNOWN;
1266     }
1267 }
1268 #define TEGRA_SEPFILTERIMPL(context, src_data, src_step, dst_data, dst_step, width, height, full_width, full_height, offset_x, offset_y) \
1269 ( \
1270     context && CAROTENE_NS::isSeparableFilter3x3Supported(CAROTENE_NS::Size2D(width, height), ((SepFilterCtx*)context)->border, 3, 3, \
1271                                                CAROTENE_NS::Margin(offset_x, full_width - width - offset_x, offset_y, full_height - height - offset_y)) ? \
1272     CAROTENE_NS::SeparableFilter3x3(CAROTENE_NS::Size2D(width, height), \
1273                                     src_data, src_step, \
1274                                     (CAROTENE_NS::s16*)dst_data, dst_step, \
1275                                     3, 3, ((SepFilterCtx*)context)->kernelx_data, ((SepFilterCtx*)context)->kernely_data, \
1276                                     ((SepFilterCtx*)context)->border, 0, \
1277                                     CAROTENE_NS::Margin(offset_x, full_width - width - offset_x, offset_y, full_height - height - offset_y)), \
1278     CV_HAL_ERROR_OK \
1279     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1280 )
1281 
1282 #undef cv_hal_sepFilterInit
1283 #define cv_hal_sepFilterInit TEGRA_SEPFILTERINIT
1284 #undef cv_hal_sepFilter
1285 #define cv_hal_sepFilter TEGRA_SEPFILTERIMPL
1286 #undef cv_hal_sepFilterFree
1287 #define cv_hal_sepFilterFree TEGRA_SEPFILTERFREE
1288 
1289 
1290 struct MorphCtx
1291 {
1292     int operation;
1293     int channels;
1294     CAROTENE_NS::Size2D ksize;
1295     int anchor_x, anchor_y;
1296     CAROTENE_NS::BORDER_MODE border;
1297     uchar borderValues[4];
1298 };
TEGRA_MORPHINIT(cvhalFilter2D ** context,int operation,int src_type,int dst_type,int,int,int kernel_type,uchar * kernel_data,size_t kernel_step,int kernel_width,int kernel_height,int anchor_x,int anchor_y,int borderType,const double borderValue[4],int iterations,bool allowSubmatrix,bool allowInplace)1299 inline int TEGRA_MORPHINIT(cvhalFilter2D **context, int operation, int src_type, int dst_type, int, int,
1300                            int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y,
1301                            int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace)
1302 {
1303     if(!context || !kernel_data || src_type != dst_type ||
1304        CV_MAT_DEPTH(src_type) != CV_8U || src_type < 0 || (src_type >> CV_CN_SHIFT) > 3 ||
1305 
1306        allowSubmatrix || allowInplace || iterations != 1 ||
1307        !CAROTENE_NS::isSupportedConfiguration())
1308         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1309 
1310     switch(CV_MAT_DEPTH(kernel_type))
1311     {
1312     case CV_8U:
1313         if(CAROTENE_NS::countNonZero(CAROTENE_NS::Size2D(kernel_width, kernel_height), kernel_data, kernel_step) != kernel_width * kernel_height)
1314             return CV_HAL_ERROR_NOT_IMPLEMENTED;
1315         break;
1316     case CV_16U:
1317         if(CAROTENE_NS::countNonZero(CAROTENE_NS::Size2D(kernel_width, kernel_height), (uint16_t*)kernel_data, kernel_step) != kernel_width * kernel_height)
1318             return CV_HAL_ERROR_NOT_IMPLEMENTED;
1319         break;
1320     case CV_32S:
1321         if(CAROTENE_NS::countNonZero(CAROTENE_NS::Size2D(kernel_width, kernel_height), (int32_t*)kernel_data, kernel_step) != kernel_width * kernel_height)
1322             return CV_HAL_ERROR_NOT_IMPLEMENTED;
1323         break;
1324     case CV_32F:
1325         if(CAROTENE_NS::countNonZero(CAROTENE_NS::Size2D(kernel_width, kernel_height), (float*)kernel_data, kernel_step) != kernel_width * kernel_height)
1326             return CV_HAL_ERROR_NOT_IMPLEMENTED;
1327         break;
1328     case CV_64F:
1329         if(CAROTENE_NS::countNonZero(CAROTENE_NS::Size2D(kernel_width, kernel_height), (double*)kernel_data, kernel_step) != kernel_width * kernel_height)
1330             return CV_HAL_ERROR_NOT_IMPLEMENTED;
1331         break;
1332     default:
1333         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1334     }
1335 
1336     MorphCtx* ctx = new MorphCtx;
1337     if(!ctx)
1338         return CV_HAL_ERROR_UNKNOWN;
1339     ctx->channels = (src_type >> CV_CN_SHIFT) + 1;
1340     ctx->ksize.width = kernel_width;
1341     ctx->ksize.height = kernel_height;
1342     ctx->anchor_x = anchor_x;
1343     ctx->anchor_y = anchor_y;
1344     switch(operation)
1345     {
1346     case CV_HAL_MORPH_ERODE:
1347     case CV_HAL_MORPH_DILATE:
1348         ctx->operation = operation;
1349         break;
1350     default:
1351         delete ctx;
1352         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1353     }
1354     switch(borderType)
1355     {
1356     case CV_HAL_BORDER_CONSTANT:
1357         ctx->border = CAROTENE_NS::BORDER_MODE_CONSTANT;
1358         if( borderValue[0] == DBL_MAX && borderValue[1] == DBL_MAX && borderValue[2] == DBL_MAX && borderValue[3] == DBL_MAX )
1359         {
1360             if( operation == CV_HAL_MORPH_ERODE )
1361                 for(int i = 0; i < ctx->channels; ++i)
1362                     ctx->borderValues[i] = (CAROTENE_NS::u8)UCHAR_MAX;
1363             else
1364                 for(int i = 0; i < ctx->channels; ++i)
1365                     ctx->borderValues[i] = 0;
1366         }
1367         else
1368         {
1369             for(int i = 0; i < ctx->channels; ++i)
1370                 ctx->borderValues[i] = (CAROTENE_NS::u8)cv::saturate_cast<uchar>(borderValue[i]);
1371         }
1372         break;
1373     case CV_HAL_BORDER_REPLICATE:
1374         ctx->border = CAROTENE_NS::BORDER_MODE_REPLICATE;
1375         break;
1376     case CV_HAL_BORDER_REFLECT:
1377         ctx->border = CAROTENE_NS::BORDER_MODE_REFLECT;
1378         break;
1379     case CV_HAL_BORDER_WRAP:
1380         ctx->border = CAROTENE_NS::BORDER_MODE_WRAP;
1381         break;
1382     case CV_HAL_BORDER_REFLECT_101:
1383         ctx->border = CAROTENE_NS::BORDER_MODE_REFLECT101;
1384         break;
1385     default:
1386         delete ctx;
1387         return CV_HAL_ERROR_NOT_IMPLEMENTED;
1388     }
1389 
1390     *context = (cvhalFilter2D*)(ctx);
1391     return CV_HAL_ERROR_OK;
1392 }
TEGRA_MORPHFREE(cvhalFilter2D * context)1393 inline int TEGRA_MORPHFREE(cvhalFilter2D *context)
1394 {
1395     if(context)
1396     {
1397         delete (MorphCtx*)context;
1398         return CV_HAL_ERROR_OK;
1399     }
1400     else
1401     {
1402         return CV_HAL_ERROR_UNKNOWN;
1403     }
1404 }
1405 #define TEGRA_MORPHIMPL(context, src_data, src_step, dst_data, dst_step, width, height, src_full_width, src_full_height, src_roi_x, src_roi_y, dst_full_width, dst_full_height, dst_roi_x, dst_roi_y) \
1406 ( \
1407     (void)dst_full_width, (void)dst_full_height, (void)dst_roi_x, (void)dst_roi_y, \
1408     context && CAROTENE_NS::isSupportedConfiguration() ? \
1409         ((MorphCtx*)context)->operation == CV_HAL_MORPH_ERODE ? \
1410         CAROTENE_NS::erode(CAROTENE_NS::Size2D(width, height), ((MorphCtx*)context)->channels, \
1411                            src_data, src_step, dst_data, dst_step, \
1412                            ((MorphCtx*)context)->ksize, ((MorphCtx*)context)->anchor_x, ((MorphCtx*)context)->anchor_y, \
1413                            ((MorphCtx*)context)->border, ((MorphCtx*)context)->border, ((MorphCtx*)context)->borderValues, \
1414                            CAROTENE_NS::Margin(src_roi_x, src_full_width - width - src_roi_x, src_roi_y, src_full_height - height - src_roi_y)), \
1415         CV_HAL_ERROR_OK : \
1416         ((MorphCtx*)context)->operation == CV_HAL_MORPH_DILATE ? \
1417         CAROTENE_NS::dilate(CAROTENE_NS::Size2D(width, height), ((MorphCtx*)context)->channels, \
1418                             src_data, src_step, dst_data, dst_step, \
1419                             ((MorphCtx*)context)->ksize, ((MorphCtx*)context)->anchor_x, ((MorphCtx*)context)->anchor_y, \
1420                             ((MorphCtx*)context)->border, ((MorphCtx*)context)->border, ((MorphCtx*)context)->borderValues, \
1421                             CAROTENE_NS::Margin(src_roi_x, src_full_width - width - src_roi_x, src_roi_y, src_full_height - height - src_roi_y)), \
1422         CV_HAL_ERROR_OK : \
1423         CV_HAL_ERROR_NOT_IMPLEMENTED \
1424     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1425 )
1426 
1427 #undef cv_hal_morphInit
1428 #define cv_hal_morphInit TEGRA_MORPHINIT
1429 #undef cv_hal_morph
1430 #define cv_hal_morph TEGRA_MORPHIMPL
1431 #undef cv_hal_morphFree
1432 #define cv_hal_morphFree TEGRA_MORPHFREE
1433 
1434 
1435 
1436 #define TEGRA_RESIZE(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, inv_scale_x, inv_scale_y, interpolation) \
1437 ( \
1438     interpolation == CV_HAL_INTER_LINEAR ? \
1439         CV_MAT_DEPTH(src_type) == CV_8U && CAROTENE_NS::isResizeLinearOpenCVSupported(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), ((src_type >> CV_CN_SHIFT) + 1)) && \
1440         inv_scale_x > 0 && inv_scale_y > 0 && \
1441         (dst_width - 0.5)/inv_scale_x - 0.5 < src_width && (dst_height - 0.5)/inv_scale_y - 0.5 < src_height && \
1442         (dst_width + 0.5)/inv_scale_x + 0.5 >= src_width && (dst_height + 0.5)/inv_scale_y + 0.5 >= src_height && \
1443         std::abs(dst_width / inv_scale_x - src_width) < 0.1 && std::abs(dst_height / inv_scale_y - src_height) < 0.1 ? \
1444             CAROTENE_NS::resizeLinearOpenCV(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1445                                             src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)), \
1446             CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
1447     interpolation == CV_HAL_INTER_AREA ? \
1448         CV_MAT_DEPTH(src_type) == CV_8U && CAROTENE_NS::isResizeAreaSupported(1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)) && \
1449         std::abs(dst_width / inv_scale_x - src_width) < 0.1 && std::abs(dst_height / inv_scale_y - src_height) < 0.1 ? \
1450             CAROTENE_NS::resizeAreaOpenCV(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1451                                           src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)), \
1452             CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
1453     /*nearest neighbour interpolation disabled due to rounding accuracy issues*/ \
1454     /*interpolation == CV_HAL_INTER_NEAREST ? \
1455         (src_type == CV_8UC1 || src_type == CV_8SC1) && CAROTENE_NS::isResizeNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height), 1) ? \
1456             CAROTENE_NS::resizeNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1457                                                src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, 1), \
1458             CV_HAL_ERROR_OK : \
1459         (src_type == CV_8UC3 || src_type == CV_8SC3) && CAROTENE_NS::isResizeNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height), 3) ? \
1460             CAROTENE_NS::resizeNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1461                                                src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, 3), \
1462             CV_HAL_ERROR_OK : \
1463         (src_type == CV_8UC4 || src_type == CV_8SC4 || src_type == CV_16UC2 || src_type == CV_16SC2 || src_type == CV_32SC1) && \
1464         CAROTENE_NS::isResizeNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height), 4) ? \
1465             CAROTENE_NS::resizeNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1466                                                src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, 4), \
1467             CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED :*/ \
1468     CV_HAL_ERROR_NOT_IMPLEMENTED \
1469 )
1470 
1471 #define TEGRA_WARPAFFINE(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, M, interpolation, borderType, borderValue) \
1472 ( \
1473     interpolation == CV_HAL_INTER_NEAREST ? \
1474         (src_type == CV_8UC1 || src_type == CV_8SC1) && (borderType == CV_HAL_BORDER_REPLICATE || borderType == CV_HAL_BORDER_CONSTANT) && \
1475         CAROTENE_NS::isWarpAffineNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height)) ? \
1476             CAROTENE_NS::warpAffineNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1477                                                    src_data, src_step, \
1478                                                    std::vector<float>(M+0,M+6).data(), \
1479                                                    dst_data, dst_step, \
1480                                                    borderType == CV_HAL_BORDER_REPLICATE ? CAROTENE_NS::BORDER_MODE_REPLICATE : CAROTENE_NS::BORDER_MODE_CONSTANT, \
1481                                                    (CAROTENE_NS::u8)borderValue[0]), \
1482         CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
1483     interpolation == CV_HAL_INTER_LINEAR ? \
1484         (src_type == CV_8UC1 || src_type == CV_8SC1) && (borderType == CV_HAL_BORDER_REPLICATE || borderType == CV_HAL_BORDER_CONSTANT) && \
1485         CAROTENE_NS::isWarpAffineLinearSupported(CAROTENE_NS::Size2D(src_width, src_height)) ? \
1486             CAROTENE_NS::warpAffineLinear(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1487                                           src_data, src_step, \
1488                                           std::vector<float>(M+0,M+6).data(), \
1489                                           dst_data, dst_step, \
1490                                           borderType == CV_HAL_BORDER_REPLICATE ? CAROTENE_NS::BORDER_MODE_REPLICATE : CAROTENE_NS::BORDER_MODE_CONSTANT, \
1491                                           (CAROTENE_NS::u8)borderValue[0]), \
1492         CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
1493     CV_HAL_ERROR_NOT_IMPLEMENTED \
1494 )
1495 
1496 #define TEGRA_WARPPERSPECTIVE(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, M, interpolation, borderType, borderValue) \
1497 ( \
1498     interpolation == CV_HAL_INTER_NEAREST ? \
1499         (src_type == CV_8UC1 || src_type == CV_8SC1) && (borderType == CV_HAL_BORDER_REPLICATE || borderType == CV_HAL_BORDER_CONSTANT) && \
1500         CAROTENE_NS::isWarpPerspectiveNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height)) ? \
1501             CAROTENE_NS::warpPerspectiveNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1502                                                         src_data, src_step, \
1503                                                         std::vector<float>(M+0,M+9).data(), \
1504                                                         dst_data, dst_step, \
1505                                                         borderType == CV_HAL_BORDER_REPLICATE ? CAROTENE_NS::BORDER_MODE_REPLICATE : CAROTENE_NS::BORDER_MODE_CONSTANT, \
1506                                                         (CAROTENE_NS::u8)borderValue[0]), \
1507         CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
1508     interpolation == CV_HAL_INTER_LINEAR ? \
1509         (src_type == CV_8UC1 || src_type == CV_8SC1) && (borderType == CV_HAL_BORDER_REPLICATE || borderType == CV_HAL_BORDER_CONSTANT) && \
1510         CAROTENE_NS::isWarpPerspectiveLinearSupported(CAROTENE_NS::Size2D(src_width, src_height)) ? \
1511             CAROTENE_NS::warpPerspectiveLinear(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
1512                                                src_data, src_step, \
1513                                                std::vector<float>(M+0,M+9).data(), \
1514                                                dst_data, dst_step, \
1515                                                borderType == CV_HAL_BORDER_REPLICATE ? CAROTENE_NS::BORDER_MODE_REPLICATE : CAROTENE_NS::BORDER_MODE_CONSTANT, \
1516                                                (CAROTENE_NS::u8)borderValue[0]), \
1517         CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
1518     CV_HAL_ERROR_NOT_IMPLEMENTED \
1519 )
1520 
1521 #undef cv_hal_resize
1522 #define cv_hal_resize TEGRA_RESIZE
1523 //warpAffine/warpPerspective disabled due to rounding accuracy issue
1524 //#undef cv_hal_warpAffine
1525 //#define cv_hal_warpAffine TEGRA_WARPAFFINE
1526 //#undef cv_hal_warpPerspective
1527 //#define cv_hal_warpPerspective TEGRA_WARPPERSPECTIVE
1528 
1529 
1530 #define TegraCvtColor_Invoker(name, func, ...) \
1531 class TegraCvtColor_##name##_Invoker : public cv::ParallelLoopBody \
1532 { \
1533 public: \
1534     TegraCvtColor_##name##_Invoker(const uchar * src_data_, size_t src_step_, uchar * dst_data_, size_t dst_step_, int width_, int height_) : \
1535         cv::ParallelLoopBody(), src_data(src_data_), src_step(src_step_), dst_data(dst_data_), dst_step(dst_step_), width(width_), height(height_) {} \
1536     virtual void operator()(const cv::Range& range) const CV_OVERRIDE \
1537     { \
1538         CAROTENE_NS::func(CAROTENE_NS::Size2D(width, range.end-range.start), __VA_ARGS__); \
1539     } \
1540 private: \
1541     const uchar * src_data; \
1542     size_t src_step; \
1543     uchar * dst_data; \
1544     size_t dst_step; \
1545     int width, height; \
1546     const TegraCvtColor_##name##_Invoker& operator= (const TegraCvtColor_##name##_Invoker&); \
1547 };
1548 
1549 TegraCvtColor_Invoker(rgb2bgr, rgb2bgr, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1550                                         dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1551 TegraCvtColor_Invoker(rgb2bgrx, rgb2bgrx, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1552                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1553 TegraCvtColor_Invoker(rgb2rgbx, rgb2rgbx, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1554                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1555 TegraCvtColor_Invoker(rgbx2bgr, rgbx2bgr, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1556                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1557 TegraCvtColor_Invoker(rgbx2rgb, rgbx2rgb, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1558                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1559 TegraCvtColor_Invoker(rgbx2bgrx, rgbx2bgrx, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1560                                             dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1561 #define TEGRA_CVTBGRTOBGR(src_data, src_step, dst_data, dst_step, width, height, depth, scn, dcn, swapBlue) \
1562 ( \
1563     depth == CV_8U && CAROTENE_NS::isSupportedConfiguration() ? \
1564         scn == 3 ? \
1565             dcn == 3 ? \
1566                 swapBlue ? \
1567                     parallel_for_(Range(0, height), \
1568                     TegraCvtColor_rgb2bgr_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1569                     (width * height) / static_cast<double>(1<<16)), \
1570                     CV_HAL_ERROR_OK : \
1571                     CV_HAL_ERROR_NOT_IMPLEMENTED : \
1572             dcn == 4 ? \
1573                 (swapBlue ? \
1574                     parallel_for_(Range(0, height), \
1575                     TegraCvtColor_rgb2bgrx_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1576                     (width * height) / static_cast<double>(1<<16)) : \
1577                     parallel_for_(Range(0, height), \
1578                     TegraCvtColor_rgb2rgbx_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1579                     (width * height) / static_cast<double>(1<<16)) ), \
1580                 CV_HAL_ERROR_OK : \
1581             CV_HAL_ERROR_NOT_IMPLEMENTED : \
1582         scn == 4 ? \
1583             dcn == 3 ? \
1584                 (swapBlue ? \
1585                     parallel_for_(Range(0, height), \
1586                     TegraCvtColor_rgbx2bgr_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1587                     (width * height) / static_cast<double>(1<<16)) : \
1588                     parallel_for_(Range(0, height), \
1589                     TegraCvtColor_rgbx2rgb_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1590                     (width * height) / static_cast<double>(1<<16)) ), \
1591                 CV_HAL_ERROR_OK : \
1592             dcn == 4 ? \
1593                 swapBlue ? \
1594                     parallel_for_(Range(0, height), \
1595                     TegraCvtColor_rgbx2bgrx_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1596                     (width * height) / static_cast<double>(1<<16)), \
1597                     CV_HAL_ERROR_OK : \
1598                     CV_HAL_ERROR_NOT_IMPLEMENTED : \
1599             CV_HAL_ERROR_NOT_IMPLEMENTED : \
1600         CV_HAL_ERROR_NOT_IMPLEMENTED \
1601     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1602 )
1603 
1604 TegraCvtColor_Invoker(rgb2bgr565, rgb2bgr565, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1605                                               dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1606 TegraCvtColor_Invoker(rgb2rgb565, rgb2rgb565, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1607                                               dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1608 TegraCvtColor_Invoker(rgbx2bgr565, rgbx2bgr565, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1609                                                 dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1610 TegraCvtColor_Invoker(rgbx2rgb565, rgbx2rgb565, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1611                                                 dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1612 #define TEGRA_CVTBGRTOBGR565(src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, greenBits) \
1613 ( \
1614     greenBits == 6 && CAROTENE_NS::isSupportedConfiguration() ? \
1615         scn == 3 ? \
1616             (swapBlue ? \
1617                 parallel_for_(Range(0, height), \
1618                 TegraCvtColor_rgb2bgr565_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1619                 (width * height) / static_cast<double>(1<<16)) : \
1620                 parallel_for_(Range(0, height), \
1621                 TegraCvtColor_rgb2rgb565_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1622                 (width * height) / static_cast<double>(1<<16)) ), \
1623             CV_HAL_ERROR_OK : \
1624         scn == 4 ? \
1625             (swapBlue ? \
1626                 parallel_for_(Range(0, height), \
1627                 TegraCvtColor_rgbx2bgr565_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1628                 (width * height) / static_cast<double>(1<<16)) : \
1629                 parallel_for_(Range(0, height), \
1630                 TegraCvtColor_rgbx2rgb565_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1631                 (width * height) / static_cast<double>(1<<16)) ), \
1632             CV_HAL_ERROR_OK : \
1633         CV_HAL_ERROR_NOT_IMPLEMENTED \
1634     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1635 )
1636 
1637 TegraCvtColor_Invoker(rgb2gray, rgb2gray, CAROTENE_NS::COLOR_SPACE_BT601, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1638                                                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1639 TegraCvtColor_Invoker(bgr2gray, bgr2gray, CAROTENE_NS::COLOR_SPACE_BT601, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1640                                                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1641 TegraCvtColor_Invoker(rgbx2gray, rgbx2gray, CAROTENE_NS::COLOR_SPACE_BT601, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1642                                                                             dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1643 TegraCvtColor_Invoker(bgrx2gray, bgrx2gray, CAROTENE_NS::COLOR_SPACE_BT601, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1644                                                                             dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1645 #define TEGRA_CVTBGRTOGRAY(src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue) \
1646 ( \
1647     depth == CV_8U && CAROTENE_NS::isSupportedConfiguration() ? \
1648         scn == 3 ? \
1649             (swapBlue ? \
1650                 parallel_for_(Range(0, height), \
1651                 TegraCvtColor_rgb2gray_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1652                 (width * height) / static_cast<double>(1<<16)) : \
1653                 parallel_for_(Range(0, height), \
1654                 TegraCvtColor_bgr2gray_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1655                 (width * height) / static_cast<double>(1<<16)) ), \
1656             CV_HAL_ERROR_OK : \
1657         scn == 4 ? \
1658             (swapBlue ? \
1659                 parallel_for_(Range(0, height), \
1660                 TegraCvtColor_rgbx2gray_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1661                 (width * height) / static_cast<double>(1<<16)) : \
1662                 parallel_for_(Range(0, height), \
1663                 TegraCvtColor_bgrx2gray_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1664                 (width * height) / static_cast<double>(1<<16)) ), \
1665             CV_HAL_ERROR_OK : \
1666         CV_HAL_ERROR_NOT_IMPLEMENTED \
1667     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1668 )
1669 
1670 TegraCvtColor_Invoker(gray2rgb, gray2rgb, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1671                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1672 TegraCvtColor_Invoker(gray2rgbx, gray2rgbx, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1673                                             dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1674 #define TEGRA_CVTGRAYTOBGR(src_data, src_step, dst_data, dst_step, width, height, depth, dcn) \
1675 ( \
1676     depth == CV_8U && CAROTENE_NS::isSupportedConfiguration() ? \
1677         dcn == 3 ? \
1678             parallel_for_(Range(0, height), \
1679             TegraCvtColor_gray2rgb_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1680             (width * height) / static_cast<double>(1<<16)), \
1681             CV_HAL_ERROR_OK : \
1682         dcn == 4 ? \
1683             parallel_for_(Range(0, height), \
1684             TegraCvtColor_gray2rgbx_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1685             (width * height) / static_cast<double>(1<<16)), \
1686             CV_HAL_ERROR_OK : \
1687         CV_HAL_ERROR_NOT_IMPLEMENTED \
1688     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1689 )
1690 
1691 TegraCvtColor_Invoker(rgb2ycrcb, rgb2ycrcb, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1692                                             dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1693 TegraCvtColor_Invoker(bgr2ycrcb, bgr2ycrcb, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1694                                             dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1695 TegraCvtColor_Invoker(rgbx2ycrcb, rgbx2ycrcb, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1696                                               dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1697 TegraCvtColor_Invoker(bgrx2ycrcb, bgrx2ycrcb, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1698                                               dst_data + static_cast<size_t>(range.start) * dst_step, dst_step)
1699 #define TEGRA_CVTBGRTOYUV(src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr) \
1700 ( \
1701     isCbCr && depth == CV_8U && CAROTENE_NS::isSupportedConfiguration() ? \
1702         scn == 3 ? \
1703             (swapBlue ? \
1704                 parallel_for_(Range(0, height), \
1705                 TegraCvtColor_rgb2ycrcb_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1706                 (width * height) / static_cast<double>(1<<16)) : \
1707                 parallel_for_(Range(0, height), \
1708                 TegraCvtColor_bgr2ycrcb_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1709                 (width * height) / static_cast<double>(1<<16)) ), \
1710             CV_HAL_ERROR_OK : \
1711         scn == 4 ? \
1712             (swapBlue ? \
1713                 parallel_for_(Range(0, height), \
1714                 TegraCvtColor_rgbx2ycrcb_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1715                 (width * height) / static_cast<double>(1<<16)) : \
1716                 parallel_for_(Range(0, height), \
1717                 TegraCvtColor_bgrx2ycrcb_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1718                 (width * height) / static_cast<double>(1<<16)) ), \
1719             CV_HAL_ERROR_OK : \
1720         CV_HAL_ERROR_NOT_IMPLEMENTED \
1721     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1722 )
1723 
1724 TegraCvtColor_Invoker(rgb2hsv, rgb2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1725                                         dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 180)
1726 TegraCvtColor_Invoker(bgr2hsv, bgr2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1727                                         dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 180)
1728 TegraCvtColor_Invoker(rgbx2hsv, rgbx2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1729                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 180)
1730 TegraCvtColor_Invoker(bgrx2hsv, bgrx2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1731                                           dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 180)
1732 TegraCvtColor_Invoker(rgb2hsvf, rgb2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1733                                          dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 256)
1734 TegraCvtColor_Invoker(bgr2hsvf, bgr2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1735                                          dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 256)
1736 TegraCvtColor_Invoker(rgbx2hsvf, rgbx2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1737                                            dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 256)
1738 TegraCvtColor_Invoker(bgrx2hsvf, bgrx2hsv, src_data + static_cast<size_t>(range.start) * src_step, src_step, \
1739                                            dst_data + static_cast<size_t>(range.start) * dst_step, dst_step, 256)
1740 #define TEGRA_CVTBGRTOHSV(src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isFullRange, isHSV) \
1741 ( \
1742     isHSV && depth == CV_8U && CAROTENE_NS::isSupportedConfiguration() ? \
1743         scn == 3 ? \
1744             (swapBlue ? \
1745                 isFullRange ? \
1746                     parallel_for_(Range(0, height), \
1747                     TegraCvtColor_rgb2hsvf_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1748                     (width * height) / static_cast<double>(1<<16)) : \
1749                     parallel_for_(Range(0, height), \
1750                     TegraCvtColor_rgb2hsv_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1751                     (width * height) / static_cast<double>(1<<16)) : \
1752                 isFullRange ? \
1753                     parallel_for_(Range(0, height), \
1754                     TegraCvtColor_bgr2hsvf_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1755                     (width * height) / static_cast<double>(1<<16)) : \
1756                     parallel_for_(Range(0, height), \
1757                     TegraCvtColor_bgr2hsv_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1758                     (width * height) / static_cast<double>(1<<16)) ), \
1759             CV_HAL_ERROR_OK : \
1760         scn == 4 ? \
1761             (swapBlue ? \
1762                 isFullRange ? \
1763                     parallel_for_(Range(0, height), \
1764                     TegraCvtColor_rgbx2hsvf_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1765                     (width * height) / static_cast<double>(1<<16)) : \
1766                     parallel_for_(Range(0, height), \
1767                     TegraCvtColor_rgbx2hsv_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1768                     (width * height) / static_cast<double>(1<<16)) : \
1769                 isFullRange ? \
1770                     parallel_for_(Range(0, height), \
1771                     TegraCvtColor_bgrx2hsvf_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1772                     (width * height) / static_cast<double>(1<<16)) : \
1773                     parallel_for_(Range(0, height), \
1774                     TegraCvtColor_bgrx2hsv_Invoker(src_data, src_step, dst_data, dst_step, width, height), \
1775                     (width * height) / static_cast<double>(1<<16)) ), \
1776             CV_HAL_ERROR_OK : \
1777         CV_HAL_ERROR_NOT_IMPLEMENTED \
1778     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1779 )
1780 
1781 #define TEGRA_CVT2PYUVTOBGR(src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx) \
1782 ( \
1783     CAROTENE_NS::isSupportedConfiguration() ? \
1784         dcn == 3 ? \
1785             uIdx == 0 ? \
1786                 (swapBlue ? \
1787                     CAROTENE_NS::yuv420i2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
1788                                              src_data, src_step, \
1789                                              src_data + src_step * dst_height, src_step, \
1790                                              dst_data, dst_step) : \
1791                     CAROTENE_NS::yuv420i2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
1792                                              src_data, src_step, \
1793                                              src_data + src_step * dst_height, src_step, \
1794                                              dst_data, dst_step)), \
1795                 CV_HAL_ERROR_OK : \
1796             uIdx == 1 ? \
1797                 (swapBlue ? \
1798                     CAROTENE_NS::yuv420sp2rgb(CAROTENE_NS::Size2D(dst_width, dst_height), \
1799                                               src_data, src_step, \
1800                                               src_data + src_step * dst_height, src_step, \
1801                                               dst_data, dst_step) : \
1802                     CAROTENE_NS::yuv420sp2bgr(CAROTENE_NS::Size2D(dst_width, dst_height), \
1803                                               src_data, src_step, \
1804                                               src_data + src_step * dst_height, src_step, \
1805                                               dst_data, dst_step)), \
1806                 CV_HAL_ERROR_OK : \
1807             CV_HAL_ERROR_NOT_IMPLEMENTED : \
1808         dcn == 4 ? \
1809             uIdx == 0 ? \
1810                 (swapBlue ? \
1811                     CAROTENE_NS::yuv420i2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
1812                                               src_data, src_step, \
1813                                               src_data + src_step * dst_height, src_step, \
1814                                               dst_data, dst_step) : \
1815                     CAROTENE_NS::yuv420i2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
1816                                               src_data, src_step, \
1817                                               src_data + src_step * dst_height, src_step, \
1818                                               dst_data, dst_step)), \
1819                 CV_HAL_ERROR_OK : \
1820             uIdx == 1 ? \
1821                 (swapBlue ? \
1822                     CAROTENE_NS::yuv420sp2rgbx(CAROTENE_NS::Size2D(dst_width, dst_height), \
1823                                                src_data, src_step, \
1824                                                src_data + src_step * dst_height, src_step, \
1825                                                dst_data, dst_step) : \
1826                     CAROTENE_NS::yuv420sp2bgrx(CAROTENE_NS::Size2D(dst_width, dst_height), \
1827                                                src_data, src_step, \
1828                                                src_data + src_step * dst_height, src_step, \
1829                                                dst_data, dst_step)), \
1830                 CV_HAL_ERROR_OK : \
1831             CV_HAL_ERROR_NOT_IMPLEMENTED : \
1832         CV_HAL_ERROR_NOT_IMPLEMENTED \
1833     : CV_HAL_ERROR_NOT_IMPLEMENTED \
1834 )
1835 
1836 #undef cv_hal_cvtBGRtoBGR
1837 #define cv_hal_cvtBGRtoBGR TEGRA_CVTBGRTOBGR
1838 #undef cv_hal_cvtBGRtoBGR5x5
1839 #define cv_hal_cvtBGRtoBGR5x5 TEGRA_CVTBGRTOBGR565
1840 #undef cv_hal_cvtBGRtoGray
1841 #define cv_hal_cvtBGRtoGray TEGRA_CVTBGRTOGRAY
1842 #undef cv_hal_cvtGraytoBGR
1843 #define cv_hal_cvtGraytoBGR TEGRA_CVTGRAYTOBGR
1844 #undef cv_hal_cvtBGRtoYUV
1845 #define cv_hal_cvtBGRtoYUV TEGRA_CVTBGRTOYUV
1846 #undef cv_hal_cvtBGRtoHSV
1847 #define cv_hal_cvtBGRtoHSV TEGRA_CVTBGRTOHSV
1848 #undef cv_hal_cvtTwoPlaneYUVtoBGR
1849 #define cv_hal_cvtTwoPlaneYUVtoBGR TEGRA_CVT2PYUVTOBGR
1850 
1851 #endif // OPENCV_IMGPROC_HAL_INTERFACE_H
1852 
1853 #endif
1854