OpenCV 2.4.8 components for OpenCVgrabber.
[mmanager-3rdparty.git] / OpenCV2.4.8 / build / include / opencv2 / gpu / device / functional.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #ifndef __OPENCV_GPU_FUNCTIONAL_HPP__
44 #define __OPENCV_GPU_FUNCTIONAL_HPP__
45
46 #include <functional>
47 #include "saturate_cast.hpp"
48 #include "vec_traits.hpp"
49 #include "type_traits.hpp"
50 #include "device_functions.h"
51
52 namespace cv { namespace gpu { namespace device
53 {
54     // Function Objects
55     template<typename Argument, typename Result> struct unary_function : public std::unary_function<Argument, Result> {};
56     template<typename Argument1, typename Argument2, typename Result> struct binary_function : public std::binary_function<Argument1, Argument2, Result> {};
57
58     // Arithmetic Operations
59     template <typename T> struct plus : binary_function<T, T, T>
60     {
61         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
62                                                  typename TypeTraits<T>::ParameterType b) const
63         {
64             return a + b;
65         }
66         __host__ __device__ __forceinline__ plus() {}
67         __host__ __device__ __forceinline__ plus(const plus&) {}
68     };
69
70     template <typename T> struct minus : binary_function<T, T, T>
71     {
72         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
73                                                  typename TypeTraits<T>::ParameterType b) const
74         {
75             return a - b;
76         }
77         __host__ __device__ __forceinline__ minus() {}
78         __host__ __device__ __forceinline__ minus(const minus&) {}
79     };
80
81     template <typename T> struct multiplies : binary_function<T, T, T>
82     {
83         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
84                                                  typename TypeTraits<T>::ParameterType b) const
85         {
86             return a * b;
87         }
88         __host__ __device__ __forceinline__ multiplies() {}
89         __host__ __device__ __forceinline__ multiplies(const multiplies&) {}
90     };
91
92     template <typename T> struct divides : binary_function<T, T, T>
93     {
94         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
95                                                  typename TypeTraits<T>::ParameterType b) const
96         {
97             return a / b;
98         }
99         __host__ __device__ __forceinline__ divides() {}
100         __host__ __device__ __forceinline__ divides(const divides&) {}
101     };
102
103     template <typename T> struct modulus : binary_function<T, T, T>
104     {
105         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
106                                                  typename TypeTraits<T>::ParameterType b) const
107         {
108             return a % b;
109         }
110         __host__ __device__ __forceinline__ modulus() {}
111         __host__ __device__ __forceinline__ modulus(const modulus&) {}
112     };
113
114     template <typename T> struct negate : unary_function<T, T>
115     {
116         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a) const
117         {
118             return -a;
119         }
120         __host__ __device__ __forceinline__ negate() {}
121         __host__ __device__ __forceinline__ negate(const negate&) {}
122     };
123
124     // Comparison Operations
125     template <typename T> struct equal_to : binary_function<T, T, bool>
126     {
127         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
128                                                     typename TypeTraits<T>::ParameterType b) const
129         {
130             return a == b;
131         }
132         __host__ __device__ __forceinline__ equal_to() {}
133         __host__ __device__ __forceinline__ equal_to(const equal_to&) {}
134     };
135
136     template <typename T> struct not_equal_to : binary_function<T, T, bool>
137     {
138         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
139                                                     typename TypeTraits<T>::ParameterType b) const
140         {
141             return a != b;
142         }
143         __host__ __device__ __forceinline__ not_equal_to() {}
144         __host__ __device__ __forceinline__ not_equal_to(const not_equal_to&) {}
145     };
146
147     template <typename T> struct greater : binary_function<T, T, bool>
148     {
149         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
150                                                     typename TypeTraits<T>::ParameterType b) const
151         {
152             return a > b;
153         }
154         __host__ __device__ __forceinline__ greater() {}
155         __host__ __device__ __forceinline__ greater(const greater&) {}
156     };
157
158     template <typename T> struct less : binary_function<T, T, bool>
159     {
160         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
161                                                     typename TypeTraits<T>::ParameterType b) const
162         {
163             return a < b;
164         }
165         __host__ __device__ __forceinline__ less() {}
166         __host__ __device__ __forceinline__ less(const less&) {}
167     };
168
169     template <typename T> struct greater_equal : binary_function<T, T, bool>
170     {
171         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
172                                                     typename TypeTraits<T>::ParameterType b) const
173         {
174             return a >= b;
175         }
176         __host__ __device__ __forceinline__ greater_equal() {}
177         __host__ __device__ __forceinline__ greater_equal(const greater_equal&) {}
178     };
179
180     template <typename T> struct less_equal : binary_function<T, T, bool>
181     {
182         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
183                                                     typename TypeTraits<T>::ParameterType b) const
184         {
185             return a <= b;
186         }
187         __host__ __device__ __forceinline__ less_equal() {}
188         __host__ __device__ __forceinline__ less_equal(const less_equal&) {}
189     };
190
191     // Logical Operations
192     template <typename T> struct logical_and : binary_function<T, T, bool>
193     {
194         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
195                                                     typename TypeTraits<T>::ParameterType b) const
196         {
197             return a && b;
198         }
199         __host__ __device__ __forceinline__ logical_and() {}
200         __host__ __device__ __forceinline__ logical_and(const logical_and&) {}
201     };
202
203     template <typename T> struct logical_or : binary_function<T, T, bool>
204     {
205         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
206                                                     typename TypeTraits<T>::ParameterType b) const
207         {
208             return a || b;
209         }
210         __host__ __device__ __forceinline__ logical_or() {}
211         __host__ __device__ __forceinline__ logical_or(const logical_or&) {}
212     };
213
214     template <typename T> struct logical_not : unary_function<T, bool>
215     {
216         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a) const
217         {
218             return !a;
219         }
220         __host__ __device__ __forceinline__ logical_not() {}
221         __host__ __device__ __forceinline__ logical_not(const logical_not&) {}
222     };
223
224     // Bitwise Operations
225     template <typename T> struct bit_and : binary_function<T, T, T>
226     {
227         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
228                                                  typename TypeTraits<T>::ParameterType b) const
229         {
230             return a & b;
231         }
232         __host__ __device__ __forceinline__ bit_and() {}
233         __host__ __device__ __forceinline__ bit_and(const bit_and&) {}
234     };
235
236     template <typename T> struct bit_or : binary_function<T, T, T>
237     {
238         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
239                                                  typename TypeTraits<T>::ParameterType b) const
240         {
241             return a | b;
242         }
243         __host__ __device__ __forceinline__ bit_or() {}
244         __host__ __device__ __forceinline__ bit_or(const bit_or&) {}
245     };
246
247     template <typename T> struct bit_xor : binary_function<T, T, T>
248     {
249         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
250                                                  typename TypeTraits<T>::ParameterType b) const
251         {
252             return a ^ b;
253         }
254         __host__ __device__ __forceinline__ bit_xor() {}
255         __host__ __device__ __forceinline__ bit_xor(const bit_xor&) {}
256     };
257
258     template <typename T> struct bit_not : unary_function<T, T>
259     {
260         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType v) const
261         {
262             return ~v;
263         }
264         __host__ __device__ __forceinline__ bit_not() {}
265         __host__ __device__ __forceinline__ bit_not(const bit_not&) {}
266     };
267
268     // Generalized Identity Operations
269     template <typename T> struct identity : unary_function<T, T>
270     {
271         __device__ __forceinline__ typename TypeTraits<T>::ParameterType operator()(typename TypeTraits<T>::ParameterType x) const
272         {
273             return x;
274         }
275         __host__ __device__ __forceinline__ identity() {}
276         __host__ __device__ __forceinline__ identity(const identity&) {}
277     };
278
279     template <typename T1, typename T2> struct project1st : binary_function<T1, T2, T1>
280     {
281         __device__ __forceinline__ typename TypeTraits<T1>::ParameterType operator()(typename TypeTraits<T1>::ParameterType lhs, typename TypeTraits<T2>::ParameterType rhs) const
282         {
283             return lhs;
284         }
285         __host__ __device__ __forceinline__ project1st() {}
286         __host__ __device__ __forceinline__ project1st(const project1st&) {}
287     };
288
289     template <typename T1, typename T2> struct project2nd : binary_function<T1, T2, T2>
290     {
291         __device__ __forceinline__ typename TypeTraits<T2>::ParameterType operator()(typename TypeTraits<T1>::ParameterType lhs, typename TypeTraits<T2>::ParameterType rhs) const
292         {
293             return rhs;
294         }
295         __host__ __device__ __forceinline__ project2nd() {}
296         __host__ __device__ __forceinline__ project2nd(const project2nd&) {}
297     };
298
299     // Min/Max Operations
300
301 #define OPENCV_GPU_IMPLEMENT_MINMAX(name, type, op) \
302     template <> struct name<type> : binary_function<type, type, type> \
303     { \
304         __device__ __forceinline__ type operator()(type lhs, type rhs) const {return op(lhs, rhs);} \
305         __host__ __device__ __forceinline__ name() {}\
306         __host__ __device__ __forceinline__ name(const name&) {}\
307     };
308
309     template <typename T> struct maximum : binary_function<T, T, T>
310     {
311         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType lhs, typename TypeTraits<T>::ParameterType rhs) const
312         {
313             return max(lhs, rhs);
314         }
315         __host__ __device__ __forceinline__ maximum() {}
316         __host__ __device__ __forceinline__ maximum(const maximum&) {}
317     };
318
319     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, uchar, ::max)
320     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, schar, ::max)
321     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, char, ::max)
322     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, ushort, ::max)
323     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, short, ::max)
324     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, int, ::max)
325     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, uint, ::max)
326     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, float, ::fmax)
327     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, double, ::fmax)
328
329     template <typename T> struct minimum : binary_function<T, T, T>
330     {
331         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType lhs, typename TypeTraits<T>::ParameterType rhs) const
332         {
333             return min(lhs, rhs);
334         }
335         __host__ __device__ __forceinline__ minimum() {}
336         __host__ __device__ __forceinline__ minimum(const minimum&) {}
337     };
338
339     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, uchar, ::min)
340     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, schar, ::min)
341     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, char, ::min)
342     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, ushort, ::min)
343     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, short, ::min)
344     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, int, ::min)
345     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, uint, ::min)
346     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, float, ::fmin)
347     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, double, ::fmin)
348
349 #undef OPENCV_GPU_IMPLEMENT_MINMAX
350
351     // Math functions
352
353     template <typename T> struct abs_func : unary_function<T, T>
354     {
355         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType x) const
356         {
357             return abs(x);
358         }
359
360         __host__ __device__ __forceinline__ abs_func() {}
361         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
362     };
363     template <> struct abs_func<unsigned char> : unary_function<unsigned char, unsigned char>
364     {
365         __device__ __forceinline__ unsigned char operator ()(unsigned char x) const
366         {
367             return x;
368         }
369
370         __host__ __device__ __forceinline__ abs_func() {}
371         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
372     };
373     template <> struct abs_func<signed char> : unary_function<signed char, signed char>
374     {
375         __device__ __forceinline__ signed char operator ()(signed char x) const
376         {
377             return ::abs((int)x);
378         }
379
380         __host__ __device__ __forceinline__ abs_func() {}
381         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
382     };
383     template <> struct abs_func<char> : unary_function<char, char>
384     {
385         __device__ __forceinline__ char operator ()(char x) const
386         {
387             return ::abs((int)x);
388         }
389
390         __host__ __device__ __forceinline__ abs_func() {}
391         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
392     };
393     template <> struct abs_func<unsigned short> : unary_function<unsigned short, unsigned short>
394     {
395         __device__ __forceinline__ unsigned short operator ()(unsigned short x) const
396         {
397             return x;
398         }
399
400         __host__ __device__ __forceinline__ abs_func() {}
401         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
402     };
403     template <> struct abs_func<short> : unary_function<short, short>
404     {
405         __device__ __forceinline__ short operator ()(short x) const
406         {
407             return ::abs((int)x);
408         }
409
410         __host__ __device__ __forceinline__ abs_func() {}
411         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
412     };
413     template <> struct abs_func<unsigned int> : unary_function<unsigned int, unsigned int>
414     {
415         __device__ __forceinline__ unsigned int operator ()(unsigned int x) const
416         {
417             return x;
418         }
419
420         __host__ __device__ __forceinline__ abs_func() {}
421         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
422     };
423     template <> struct abs_func<int> : unary_function<int, int>
424     {
425         __device__ __forceinline__ int operator ()(int x) const
426         {
427             return ::abs(x);
428         }
429
430         __host__ __device__ __forceinline__ abs_func() {}
431         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
432     };
433     template <> struct abs_func<float> : unary_function<float, float>
434     {
435         __device__ __forceinline__ float operator ()(float x) const
436         {
437             return ::fabsf(x);
438         }
439
440         __host__ __device__ __forceinline__ abs_func() {}
441         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
442     };
443     template <> struct abs_func<double> : unary_function<double, double>
444     {
445         __device__ __forceinline__ double operator ()(double x) const
446         {
447             return ::fabs(x);
448         }
449
450         __host__ __device__ __forceinline__ abs_func() {}
451         __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
452     };
453
454 #define OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(name, func) \
455     template <typename T> struct name ## _func : unary_function<T, float> \
456     { \
457         __device__ __forceinline__ float operator ()(typename TypeTraits<T>::ParameterType v) const \
458         { \
459             return func ## f(v); \
460         } \
461         __host__ __device__ __forceinline__ name ## _func() {} \
462         __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
463     }; \
464     template <> struct name ## _func<double> : unary_function<double, double> \
465     { \
466         __device__ __forceinline__ double operator ()(double v) const \
467         { \
468             return func(v); \
469         } \
470         __host__ __device__ __forceinline__ name ## _func() {} \
471         __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
472     };
473
474 #define OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(name, func) \
475     template <typename T> struct name ## _func : binary_function<T, T, float> \
476     { \
477         __device__ __forceinline__ float operator ()(typename TypeTraits<T>::ParameterType v1, typename TypeTraits<T>::ParameterType v2) const \
478         { \
479             return func ## f(v1, v2); \
480         } \
481         __host__ __device__ __forceinline__ name ## _func() {} \
482         __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
483     }; \
484     template <> struct name ## _func<double> : binary_function<double, double, double> \
485     { \
486         __device__ __forceinline__ double operator ()(double v1, double v2) const \
487         { \
488             return func(v1, v2); \
489         } \
490         __host__ __device__ __forceinline__ name ## _func() {} \
491         __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
492     };
493
494     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(sqrt, ::sqrt)
495     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(exp, ::exp)
496     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(exp2, ::exp2)
497     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(exp10, ::exp10)
498     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(log, ::log)
499     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(log2, ::log2)
500     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(log10, ::log10)
501     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(sin, ::sin)
502     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(cos, ::cos)
503     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(tan, ::tan)
504     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(asin, ::asin)
505     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(acos, ::acos)
506     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(atan, ::atan)
507     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(sinh, ::sinh)
508     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(cosh, ::cosh)
509     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(tanh, ::tanh)
510     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(asinh, ::asinh)
511     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(acosh, ::acosh)
512     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(atanh, ::atanh)
513
514     OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(hypot, ::hypot)
515     OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(atan2, ::atan2)
516     OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(pow, ::pow)
517
518     #undef OPENCV_GPU_IMPLEMENT_UN_FUNCTOR
519     #undef OPENCV_GPU_IMPLEMENT_UN_FUNCTOR_NO_DOUBLE
520     #undef OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR
521
522     template<typename T> struct hypot_sqr_func : binary_function<T, T, float>
523     {
524         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType src1, typename TypeTraits<T>::ParameterType src2) const
525         {
526             return src1 * src1 + src2 * src2;
527         }
528         __host__ __device__ __forceinline__ hypot_sqr_func() {}
529         __host__ __device__ __forceinline__ hypot_sqr_func(const hypot_sqr_func&) {}
530     };
531
532     // Saturate Cast Functor
533     template <typename T, typename D> struct saturate_cast_func : unary_function<T, D>
534     {
535         __device__ __forceinline__ D operator ()(typename TypeTraits<T>::ParameterType v) const
536         {
537             return saturate_cast<D>(v);
538         }
539         __host__ __device__ __forceinline__ saturate_cast_func() {}
540         __host__ __device__ __forceinline__ saturate_cast_func(const saturate_cast_func&) {}
541     };
542
543     // Threshold Functors
544     template <typename T> struct thresh_binary_func : unary_function<T, T>
545     {
546         __host__ __device__ __forceinline__ thresh_binary_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {}
547
548         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
549         {
550             return (src > thresh) * maxVal;
551         }
552
553         __host__ __device__ __forceinline__ thresh_binary_func() {}
554         __host__ __device__ __forceinline__ thresh_binary_func(const thresh_binary_func& other)
555             : thresh(other.thresh), maxVal(other.maxVal) {}
556
557         const T thresh;
558         const T maxVal;
559     };
560
561     template <typename T> struct thresh_binary_inv_func : unary_function<T, T>
562     {
563         __host__ __device__ __forceinline__ thresh_binary_inv_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {}
564
565         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
566         {
567             return (src <= thresh) * maxVal;
568         }
569
570         __host__ __device__ __forceinline__ thresh_binary_inv_func() {}
571         __host__ __device__ __forceinline__ thresh_binary_inv_func(const thresh_binary_inv_func& other)
572             : thresh(other.thresh), maxVal(other.maxVal) {}
573
574         const T thresh;
575         const T maxVal;
576     };
577
578     template <typename T> struct thresh_trunc_func : unary_function<T, T>
579     {
580         explicit __host__ __device__ __forceinline__ thresh_trunc_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {(void)maxVal_;}
581
582         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
583         {
584             return minimum<T>()(src, thresh);
585         }
586
587         __host__ __device__ __forceinline__ thresh_trunc_func() {}
588         __host__ __device__ __forceinline__ thresh_trunc_func(const thresh_trunc_func& other)
589             : thresh(other.thresh) {}
590
591         const T thresh;
592     };
593
594     template <typename T> struct thresh_to_zero_func : unary_function<T, T>
595     {
596         explicit __host__ __device__ __forceinline__ thresh_to_zero_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {(void)maxVal_;}
597
598         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
599         {
600             return (src > thresh) * src;
601         }
602
603         __host__ __device__ __forceinline__ thresh_to_zero_func() {}
604        __host__  __device__ __forceinline__ thresh_to_zero_func(const thresh_to_zero_func& other)
605             : thresh(other.thresh) {}
606
607         const T thresh;
608     };
609
610     template <typename T> struct thresh_to_zero_inv_func : unary_function<T, T>
611     {
612         explicit __host__ __device__ __forceinline__ thresh_to_zero_inv_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {(void)maxVal_;}
613
614         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
615         {
616             return (src <= thresh) * src;
617         }
618
619         __host__ __device__ __forceinline__ thresh_to_zero_inv_func() {}
620         __host__ __device__ __forceinline__ thresh_to_zero_inv_func(const thresh_to_zero_inv_func& other)
621             : thresh(other.thresh) {}
622
623         const T thresh;
624     };
625
626     // Function Object Adaptors
627     template <typename Predicate> struct unary_negate : unary_function<typename Predicate::argument_type, bool>
628     {
629       explicit __host__ __device__ __forceinline__ unary_negate(const Predicate& p) : pred(p) {}
630
631       __device__ __forceinline__ bool operator()(typename TypeTraits<typename Predicate::argument_type>::ParameterType x) const
632       {
633           return !pred(x);
634       }
635
636       __host__ __device__ __forceinline__ unary_negate() {}
637       __host__ __device__ __forceinline__ unary_negate(const unary_negate& other) : pred(other.pred) {}
638
639       const Predicate pred;
640     };
641
642     template <typename Predicate> __host__ __device__ __forceinline__ unary_negate<Predicate> not1(const Predicate& pred)
643     {
644         return unary_negate<Predicate>(pred);
645     }
646
647     template <typename Predicate> struct binary_negate : binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
648     {
649         explicit __host__ __device__ __forceinline__ binary_negate(const Predicate& p) : pred(p) {}
650
651         __device__ __forceinline__ bool operator()(typename TypeTraits<typename Predicate::first_argument_type>::ParameterType x,
652                                                    typename TypeTraits<typename Predicate::second_argument_type>::ParameterType y) const
653         {
654             return !pred(x,y);
655         }
656
657         __host__ __device__ __forceinline__ binary_negate() {}
658         __host__ __device__ __forceinline__ binary_negate(const binary_negate& other) : pred(other.pred) {}
659
660         const Predicate pred;
661     };
662
663     template <typename BinaryPredicate> __host__ __device__ __forceinline__ binary_negate<BinaryPredicate> not2(const BinaryPredicate& pred)
664     {
665         return binary_negate<BinaryPredicate>(pred);
666     }
667
668     template <typename Op> struct binder1st : unary_function<typename Op::second_argument_type, typename Op::result_type>
669     {
670         __host__ __device__ __forceinline__ binder1st(const Op& op_, const typename Op::first_argument_type& arg1_) : op(op_), arg1(arg1_) {}
671
672         __device__ __forceinline__ typename Op::result_type operator ()(typename TypeTraits<typename Op::second_argument_type>::ParameterType a) const
673         {
674             return op(arg1, a);
675         }
676
677         __host__ __device__ __forceinline__ binder1st() {}
678         __host__ __device__ __forceinline__ binder1st(const binder1st& other) : op(other.op), arg1(other.arg1) {}
679
680         const Op op;
681         const typename Op::first_argument_type arg1;
682     };
683
684     template <typename Op, typename T> __host__ __device__ __forceinline__ binder1st<Op> bind1st(const Op& op, const T& x)
685     {
686         return binder1st<Op>(op, typename Op::first_argument_type(x));
687     }
688
689     template <typename Op> struct binder2nd : unary_function<typename Op::first_argument_type, typename Op::result_type>
690     {
691         __host__ __device__ __forceinline__ binder2nd(const Op& op_, const typename Op::second_argument_type& arg2_) : op(op_), arg2(arg2_) {}
692
693         __forceinline__ __device__ typename Op::result_type operator ()(typename TypeTraits<typename Op::first_argument_type>::ParameterType a) const
694         {
695             return op(a, arg2);
696         }
697
698         __host__ __device__ __forceinline__ binder2nd() {}
699         __host__ __device__ __forceinline__ binder2nd(const binder2nd& other) : op(other.op), arg2(other.arg2) {}
700
701         const Op op;
702         const typename Op::second_argument_type arg2;
703     };
704
705     template <typename Op, typename T> __host__ __device__ __forceinline__ binder2nd<Op> bind2nd(const Op& op, const T& x)
706     {
707         return binder2nd<Op>(op, typename Op::second_argument_type(x));
708     }
709
710     // Functor Traits
711     template <typename F> struct IsUnaryFunction
712     {
713         typedef char Yes;
714         struct No {Yes a[2];};
715
716         template <typename T, typename D> static Yes check(unary_function<T, D>);
717         static No check(...);
718
719         static F makeF();
720
721         enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
722     };
723
724     template <typename F> struct IsBinaryFunction
725     {
726         typedef char Yes;
727         struct No {Yes a[2];};
728
729         template <typename T1, typename T2, typename D> static Yes check(binary_function<T1, T2, D>);
730         static No check(...);
731
732         static F makeF();
733
734         enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
735     };
736
737     namespace functional_detail
738     {
739         template <size_t src_elem_size, size_t dst_elem_size> struct UnOpShift { enum { shift = 1 }; };
740         template <size_t src_elem_size> struct UnOpShift<src_elem_size, 1> { enum { shift = 4 }; };
741         template <size_t src_elem_size> struct UnOpShift<src_elem_size, 2> { enum { shift = 2 }; };
742
743         template <typename T, typename D> struct DefaultUnaryShift
744         {
745             enum { shift = UnOpShift<sizeof(T), sizeof(D)>::shift };
746         };
747
748         template <size_t src_elem_size1, size_t src_elem_size2, size_t dst_elem_size> struct BinOpShift { enum { shift = 1 }; };
749         template <size_t src_elem_size1, size_t src_elem_size2> struct BinOpShift<src_elem_size1, src_elem_size2, 1> { enum { shift = 4 }; };
750         template <size_t src_elem_size1, size_t src_elem_size2> struct BinOpShift<src_elem_size1, src_elem_size2, 2> { enum { shift = 2 }; };
751
752         template <typename T1, typename T2, typename D> struct DefaultBinaryShift
753         {
754             enum { shift = BinOpShift<sizeof(T1), sizeof(T2), sizeof(D)>::shift };
755         };
756
757         template <typename Func, bool unary = IsUnaryFunction<Func>::value> struct ShiftDispatcher;
758         template <typename Func> struct ShiftDispatcher<Func, true>
759         {
760             enum { shift = DefaultUnaryShift<typename Func::argument_type, typename Func::result_type>::shift };
761         };
762         template <typename Func> struct ShiftDispatcher<Func, false>
763         {
764             enum { shift = DefaultBinaryShift<typename Func::first_argument_type, typename Func::second_argument_type, typename Func::result_type>::shift };
765         };
766     }
767
768     template <typename Func> struct DefaultTransformShift
769     {
770         enum { shift = functional_detail::ShiftDispatcher<Func>::shift };
771     };
772
773     template <typename Func> struct DefaultTransformFunctorTraits
774     {
775         enum { simple_block_dim_x = 16 };
776         enum { simple_block_dim_y = 16 };
777
778         enum { smart_block_dim_x = 16 };
779         enum { smart_block_dim_y = 16 };
780         enum { smart_shift = DefaultTransformShift<Func>::shift };
781     };
782
783     template <typename Func> struct TransformFunctorTraits : DefaultTransformFunctorTraits<Func> {};
784
785 #define OPENCV_GPU_TRANSFORM_FUNCTOR_TRAITS(type) \
786     template <> struct TransformFunctorTraits< type > : DefaultTransformFunctorTraits< type >
787 }}} // namespace cv { namespace gpu { namespace device
788
789 #endif // __OPENCV_GPU_FUNCTIONAL_HPP__