include/opencv2/gpu/device/functional.hpp
Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_GPU_FUNCTIONAL_HPP__
00044 #define __OPENCV_GPU_FUNCTIONAL_HPP__
00045 
00046 #include <functional>
00047 #include "saturate_cast.hpp"
00048 #include "vec_traits.hpp"
00049 #include "type_traits.hpp"
00050 #include "device_functions.h"
00051 
00052 namespace cv { namespace gpu { namespace device
00053 {
00054     // Function Objects
00055     template<typename Argument, typename Result> struct unary_function : public std::unary_function<Argument, Result> {};
00056     template<typename Argument1, typename Argument2, typename Result> struct binary_function : public std::binary_function<Argument1, Argument2, Result> {};
00057 
00058     // Arithmetic Operations
00059     template <typename T> struct plus : binary_function<T, T, T>
00060     {
00061         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00062                                                  typename TypeTraits<T>::ParameterType b) const
00063         {
00064             return a + b;
00065         }
00066         __device__ __forceinline__ plus(const plus& other):binary_function<T,T,T>(){}
00067         __device__ __forceinline__ plus():binary_function<T,T,T>(){}
00068     };
00069 
00070     template <typename T> struct minus : binary_function<T, T, T>
00071     {
00072         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00073                                                  typename TypeTraits<T>::ParameterType b) const
00074         {
00075             return a - b;
00076         }
00077         __device__ __forceinline__ minus(const minus& other):binary_function<T,T,T>(){}
00078         __device__ __forceinline__ minus():binary_function<T,T,T>(){}
00079     };
00080 
00081     template <typename T> struct multiplies : binary_function<T, T, T>
00082     {
00083         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00084                                                  typename TypeTraits<T>::ParameterType b) const
00085         {
00086             return a * b;
00087         }
00088         __device__ __forceinline__ multiplies(const multiplies& other):binary_function<T,T,T>(){}
00089         __device__ __forceinline__ multiplies():binary_function<T,T,T>(){}
00090     };
00091 
00092     template <typename T> struct divides : binary_function<T, T, T>
00093     {
00094         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00095                                                  typename TypeTraits<T>::ParameterType b) const
00096         {
00097             return a / b;
00098         }
00099         __device__ __forceinline__ divides(const divides& other):binary_function<T,T,T>(){}
00100         __device__ __forceinline__ divides():binary_function<T,T,T>(){}
00101     };
00102 
00103     template <typename T> struct modulus : binary_function<T, T, T>
00104     {
00105         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00106                                                  typename TypeTraits<T>::ParameterType b) const
00107         {
00108             return a % b;
00109         }
00110         __device__ __forceinline__ modulus(const modulus& other):binary_function<T,T,T>(){}
00111         __device__ __forceinline__ modulus():binary_function<T,T,T>(){}
00112     };
00113 
00114     template <typename T> struct negate : unary_function<T, T>
00115     {
00116         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a) const
00117         {
00118             return -a;
00119         }
00120         __device__ __forceinline__ negate(const negate& other):unary_function<T,T>(){}
00121         __device__ __forceinline__ negate():unary_function<T,T>(){}
00122     };
00123 
00124     // Comparison Operations
00125     template <typename T> struct equal_to : binary_function<T, T, bool>
00126     {
00127         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00128                                                     typename TypeTraits<T>::ParameterType b) const
00129         {
00130             return a == b;
00131         }
00132         __device__ __forceinline__ equal_to(const equal_to& other):binary_function<T,T,bool>(){}
00133         __device__ __forceinline__ equal_to():binary_function<T,T,bool>(){}
00134     };
00135 
00136     template <typename T> struct not_equal_to : binary_function<T, T, bool>
00137     {
00138         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00139                                                     typename TypeTraits<T>::ParameterType b) const
00140         {
00141             return a != b;
00142         }
00143         __device__ __forceinline__ not_equal_to(const not_equal_to& other):binary_function<T,T,bool>(){}
00144         __device__ __forceinline__ not_equal_to():binary_function<T,T,bool>(){}
00145     };
00146 
00147     template <typename T> struct greater : binary_function<T, T, bool>
00148     {
00149         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00150                                                     typename TypeTraits<T>::ParameterType b) const
00151         {
00152             return a > b;
00153         }
00154         __device__ __forceinline__ greater(const greater& other):binary_function<T,T,bool>(){}
00155         __device__ __forceinline__ greater():binary_function<T,T,bool>(){}
00156     };
00157 
00158     template <typename T> struct less : binary_function<T, T, bool>
00159     {
00160         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00161                                                     typename TypeTraits<T>::ParameterType b) const
00162         {
00163             return a < b;
00164         }
00165         __device__ __forceinline__ less(const less& other):binary_function<T,T,bool>(){}
00166         __device__ __forceinline__ less():binary_function<T,T,bool>(){}
00167     };
00168 
00169     template <typename T> struct greater_equal : binary_function<T, T, bool>
00170     {
00171         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00172                                                     typename TypeTraits<T>::ParameterType b) const
00173         {
00174             return a >= b;
00175         }
00176         __device__ __forceinline__ greater_equal(const greater_equal& other):binary_function<T,T,bool>(){}
00177         __device__ __forceinline__ greater_equal():binary_function<T,T,bool>(){}
00178     };
00179 
00180     template <typename T> struct less_equal : binary_function<T, T, bool>
00181     {
00182         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00183                                                     typename TypeTraits<T>::ParameterType b) const
00184         {
00185             return a <= b;
00186         }
00187         __device__ __forceinline__ less_equal(const less_equal& other):binary_function<T,T,bool>(){}
00188         __device__ __forceinline__ less_equal():binary_function<T,T,bool>(){}
00189     };
00190 
00191     // Logical Operations
00192     template <typename T> struct logical_and : binary_function<T, T, bool>
00193     {
00194         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00195                                                     typename TypeTraits<T>::ParameterType b) const
00196         {
00197             return a && b;
00198         }
00199         __device__ __forceinline__ logical_and(const logical_and& other):binary_function<T,T,bool>(){}
00200         __device__ __forceinline__ logical_and():binary_function<T,T,bool>(){}
00201     };
00202 
00203     template <typename T> struct logical_or : binary_function<T, T, bool>
00204     {
00205         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
00206                                                     typename TypeTraits<T>::ParameterType b) const
00207         {
00208             return a || b;
00209         }
00210         __device__ __forceinline__ logical_or(const logical_or& other):binary_function<T,T,bool>(){}
00211         __device__ __forceinline__ logical_or():binary_function<T,T,bool>(){}
00212     };
00213 
00214     template <typename T> struct logical_not : unary_function<T, bool>
00215     {
00216         __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a) const
00217         {
00218             return !a;
00219         }
00220         __device__ __forceinline__ logical_not(const logical_not& other):unary_function<T,bool>(){}
00221         __device__ __forceinline__ logical_not():unary_function<T,bool>(){}
00222     };
00223 
00224     // Bitwise Operations
00225     template <typename T> struct bit_and : binary_function<T, T, T>
00226     {
00227         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00228                                                  typename TypeTraits<T>::ParameterType b) const
00229         {
00230             return a & b;
00231         }
00232         __device__ __forceinline__ bit_and(const bit_and& other):binary_function<T,T,T>(){}
00233         __device__ __forceinline__ bit_and():binary_function<T,T,T>(){}
00234     };
00235 
00236     template <typename T> struct bit_or : binary_function<T, T, T>
00237     {
00238         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00239                                                  typename TypeTraits<T>::ParameterType b) const
00240         {
00241             return a | b;
00242         }
00243         __device__ __forceinline__ bit_or(const bit_or& other):binary_function<T,T,T>(){}
00244         __device__ __forceinline__ bit_or():binary_function<T,T,T>(){}
00245     };
00246 
00247     template <typename T> struct bit_xor : binary_function<T, T, T>
00248     {
00249         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
00250                                                  typename TypeTraits<T>::ParameterType b) const
00251         {
00252             return a ^ b;
00253         }
00254         __device__ __forceinline__ bit_xor(const bit_xor& other):binary_function<T,T,T>(){}
00255         __device__ __forceinline__ bit_xor():binary_function<T,T,T>(){}
00256     };
00257 
00258     template <typename T> struct bit_not : unary_function<T, T>
00259     {
00260         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType v) const
00261         {
00262             return ~v;
00263         }
00264         __device__ __forceinline__ bit_not(const bit_not& other):unary_function<T,T>(){}
00265         __device__ __forceinline__ bit_not():unary_function<T,T>(){}
00266     };
00267 
00268     // Generalized Identity Operations
00269     template <typename T> struct identity : unary_function<T, T>
00270     {
00271         __device__ __forceinline__ typename TypeTraits<T>::ParameterType operator()(typename TypeTraits<T>::ParameterType x) const
00272         {
00273             return x;
00274         }
00275         __device__ __forceinline__ identity(const identity& other):unary_function<T,T>(){}
00276         __device__ __forceinline__ identity():unary_function<T,T>(){}
00277     };
00278 
00279     template <typename T1, typename T2> struct project1st : binary_function<T1, T2, T1>
00280     {
00281         __device__ __forceinline__ typename TypeTraits<T1>::ParameterType operator()(typename TypeTraits<T1>::ParameterType lhs, typename TypeTraits<T2>::ParameterType rhs) const
00282         {
00283             return lhs;
00284         }
00285         __device__ __forceinline__ project1st(const project1st& other):binary_function<T1,T2,T1>(){}
00286         __device__ __forceinline__ project1st():binary_function<T1,T2,T1>(){}
00287     };
00288 
00289     template <typename T1, typename T2> struct project2nd : binary_function<T1, T2, T2>
00290     {
00291         __device__ __forceinline__ typename TypeTraits<T2>::ParameterType operator()(typename TypeTraits<T1>::ParameterType lhs, typename TypeTraits<T2>::ParameterType rhs) const
00292         {
00293             return rhs;
00294         }
00295         __device__ __forceinline__ project2nd(const project2nd& other):binary_function<T1,T2,T2>(){}
00296         __device__ __forceinline__ project2nd():binary_function<T1,T2,T2>(){}
00297     };
00298 
00299     // Min/Max Operations
00300 
00301 #define OPENCV_GPU_IMPLEMENT_MINMAX(name, type, op) \
00302     template <> struct name<type> : binary_function<type, type, type> \
00303     { \
00304         __device__ __forceinline__ type operator()(type lhs, type rhs) const {return op(lhs, rhs);} \
00305         __device__ __forceinline__ name(const name& other):binary_function<type, type, type>(){}\
00306         __device__ __forceinline__ name():binary_function<type, type, type>(){}\
00307     };
00308 
00309     template <typename T> struct maximum : binary_function<T, T, T>
00310     {
00311         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType lhs, typename TypeTraits<T>::ParameterType rhs) const
00312         {
00313             return lhs < rhs ? rhs : lhs;
00314         }
00315         __device__ __forceinline__ maximum(const maximum& other):binary_function<T, T, T>(){}
00316         __device__ __forceinline__ maximum():binary_function<T, T, T>(){}
00317     };
00318 
00319     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, uchar, ::max)
00320     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, schar, ::max)
00321     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, char, ::max)
00322     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, ushort, ::max)
00323     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, short, ::max)
00324     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, int, ::max)
00325     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, uint, ::max)
00326     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, float, ::fmax)
00327     OPENCV_GPU_IMPLEMENT_MINMAX(maximum, double, ::fmax)
00328 
00329     template <typename T> struct minimum : binary_function<T, T, T>
00330     {
00331         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType lhs, typename TypeTraits<T>::ParameterType rhs) const
00332         {
00333             return lhs < rhs ? lhs : rhs;
00334         }
00335         __device__ __forceinline__ minimum(const minimum& other):binary_function<T, T, T>(){}
00336         __device__ __forceinline__ minimum():binary_function<T, T, T>(){}
00337     };
00338 
00339     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, uchar, ::min)
00340     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, schar, ::min)
00341     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, char, ::min)
00342     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, ushort, ::min)
00343     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, short, ::min)
00344     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, int, ::min)
00345     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, uint, ::min)
00346     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, float, ::fmin)
00347     OPENCV_GPU_IMPLEMENT_MINMAX(minimum, double, ::fmin)
00348 
00349 #undef OPENCV_GPU_IMPLEMENT_MINMAX
00350 
00351     // Math functions
00353 #define OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(name, func) \
00354     template <typename T> struct name ## _func : unary_function<T, float> \
00355     { \
00356         __device__ __forceinline__ float operator ()(typename TypeTraits<T>::ParameterType v) const \
00357         { \
00358             return func ## f(v); \
00359         } \
00360     }; \
00361     template <> struct name ## _func<double> : unary_function<double, double> \
00362     { \
00363         __device__ __forceinline__ double operator ()(double v) const \
00364         { \
00365             return func(v); \
00366         } \
00367     };
00368 
00369 #define OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(name, func) \
00370     template <typename T> struct name ## _func : binary_function<T, T, float> \
00371     { \
00372         __device__ __forceinline__ float operator ()(typename TypeTraits<T>::ParameterType v1, typename TypeTraits<T>::ParameterType v2) const \
00373         { \
00374             return func ## f(v1, v2); \
00375         } \
00376     }; \
00377     template <> struct name ## _func<double> : binary_function<double, double, double> \
00378     { \
00379         __device__ __forceinline__ double operator ()(double v1, double v2) const \
00380         { \
00381             return func(v1, v2); \
00382         } \
00383     };
00384 
00385     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(fabs, ::fabs)
00386     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(sqrt, ::sqrt)
00387     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(exp, ::exp)
00388     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(exp2, ::exp2)
00389     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(exp10, ::exp10)
00390     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(log, ::log)
00391     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(log2, ::log2)
00392     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(log10, ::log10)
00393     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(sin, ::sin)
00394     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(cos, ::cos)
00395     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(tan, ::tan)
00396     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(asin, ::asin)
00397     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(acos, ::acos)
00398     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(atan, ::atan)
00399     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(sinh, ::sinh)
00400     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(cosh, ::cosh)
00401     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(tanh, ::tanh)
00402     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(asinh, ::asinh)
00403     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(acosh, ::acosh)
00404     OPENCV_GPU_IMPLEMENT_UN_FUNCTOR(atanh, ::atanh)
00405 
00406     OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(hypot, ::hypot)
00407     OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(atan2, ::atan2)
00408     OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR(pow, ::pow)
00409 
00410     #undef OPENCV_GPU_IMPLEMENT_UN_FUNCTOR
00411     #undef OPENCV_GPU_IMPLEMENT_UN_FUNCTOR_NO_DOUBLE
00412     #undef OPENCV_GPU_IMPLEMENT_BIN_FUNCTOR
00413 
00414     template<typename T> struct hypot_sqr_func : binary_function<T, T, float>
00415     {
00416         __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType src1, typename TypeTraits<T>::ParameterType src2) const
00417         {
00418             return src1 * src1 + src2 * src2;
00419         }
00420         __device__ __forceinline__ hypot_sqr_func(const hypot_sqr_func& other) : binary_function<T, T, float>(){}
00421         __device__ __forceinline__ hypot_sqr_func() : binary_function<T, T, float>(){}
00422     };
00423 
00424     // Saturate Cast Functor
00425     template <typename T, typename D> struct saturate_cast_func : unary_function<T, D>
00426     {
00427         __device__ __forceinline__ D operator ()(typename TypeTraits<T>::ParameterType v) const
00428         {
00429             return saturate_cast<D>(v);
00430         }
00431         __device__ __forceinline__ saturate_cast_func(const saturate_cast_func& other):unary_function<T, D>(){}
00432         __device__ __forceinline__ saturate_cast_func():unary_function<T, D>(){}
00433     };
00434 
00435     // Threshold Functors
00436     template <typename T> struct thresh_binary_func : unary_function<T, T>
00437     {
00438         __host__ __device__ __forceinline__ thresh_binary_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {}
00439 
00440         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
00441         {
00442             return (src > thresh) * maxVal;
00443         }
00444 
00445         __device__ __forceinline__ thresh_binary_func(const thresh_binary_func& other)
00446             : unary_function<T, T>(), thresh(other.thresh), maxVal(other.maxVal){}
00447 
00448         __device__ __forceinline__ thresh_binary_func():unary_function<T, T>(){}
00449 
00450         const T thresh;
00451         const T maxVal;
00452     };
00453 
00454     template <typename T> struct thresh_binary_inv_func : unary_function<T, T>
00455     {
00456         __host__ __device__ __forceinline__ thresh_binary_inv_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {}
00457 
00458         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
00459         {
00460             return (src <= thresh) * maxVal;
00461         }
00462 
00463         __device__ __forceinline__ thresh_binary_inv_func(const thresh_binary_inv_func& other)
00464             : unary_function<T, T>(), thresh(other.thresh), maxVal(other.maxVal){}
00465 
00466         __device__ __forceinline__ thresh_binary_inv_func():unary_function<T, T>(){}
00467 
00468         const T thresh;
00469         const T maxVal;
00470     };
00471 
00472     template <typename T> struct thresh_trunc_func : unary_function<T, T>
00473     {
00474         explicit __host__ __device__ __forceinline__ thresh_trunc_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {(void)maxVal_;}
00475 
00476         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
00477         {
00478             return minimum<T>()(src, thresh);
00479         }
00480 
00481         __device__ __forceinline__ thresh_trunc_func(const thresh_trunc_func& other)
00482             : unary_function<T, T>(), thresh(other.thresh){}
00483 
00484         __device__ __forceinline__ thresh_trunc_func():unary_function<T, T>(){}
00485 
00486         const T thresh;
00487     };
00488 
00489     template <typename T> struct thresh_to_zero_func : unary_function<T, T>
00490     {
00491         explicit __host__ __device__ __forceinline__ thresh_to_zero_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {(void)maxVal_;}
00492 
00493         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
00494         {
00495             return (src > thresh) * src;
00496         }
00497         __device__ __forceinline__ thresh_to_zero_func(const thresh_to_zero_func& other)
00498             : unary_function<T, T>(), thresh(other.thresh){}
00499 
00500         __device__ __forceinline__ thresh_to_zero_func():unary_function<T, T>(){}
00501 
00502         const T thresh;
00503     };
00504 
00505     template <typename T> struct thresh_to_zero_inv_func : unary_function<T, T>
00506     {
00507         explicit __host__ __device__ __forceinline__ thresh_to_zero_inv_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {(void)maxVal_;}
00508 
00509         __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
00510         {
00511             return (src <= thresh) * src;
00512         }
00513         __device__ __forceinline__ thresh_to_zero_inv_func(const thresh_to_zero_inv_func& other)
00514             : unary_function<T, T>(), thresh(other.thresh){}
00515 
00516         __device__ __forceinline__ thresh_to_zero_inv_func():unary_function<T, T>(){}
00517 
00518         const T thresh;
00519     };
00520 //bound!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ============>
00521     // Function Object Adaptors
00522     template <typename Predicate> struct unary_negate : unary_function<typename Predicate::argument_type, bool>
00523     {
00524       explicit __host__ __device__ __forceinline__ unary_negate(const Predicate& p) : pred(p) {}
00525 
00526       __device__ __forceinline__ bool operator()(typename TypeTraits<typename Predicate::argument_type>::ParameterType x) const
00527       {
00528           return !pred(x);
00529       }
00530 
00531         __device__ __forceinline__ unary_negate(const unary_negate& other) : unary_function<typename Predicate::argument_type, bool>(){}
00532         __device__ __forceinline__ unary_negate() : unary_function<typename Predicate::argument_type, bool>(){}
00533 
00534       const Predicate pred;
00535     };
00536 
00537     template <typename Predicate> __host__ __device__ __forceinline__ unary_negate<Predicate> not1(const Predicate& pred)
00538     {
00539         return unary_negate<Predicate>(pred);
00540     }
00541 
00542     template <typename Predicate> struct binary_negate : binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
00543     {
00544         explicit __host__ __device__ __forceinline__ binary_negate(const Predicate& p) : pred(p) {}
00545 
00546         __device__ __forceinline__ bool operator()(typename TypeTraits<typename Predicate::first_argument_type>::ParameterType x,
00547                                                    typename TypeTraits<typename Predicate::second_argument_type>::ParameterType y) const
00548         {
00549             return !pred(x,y);
00550         }
00551         __device__ __forceinline__ binary_negate(const binary_negate& other)
00552         : binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>(){}
00553 
00554         __device__ __forceinline__ binary_negate() :
00555         binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>(){}
00556 
00557         const Predicate pred;
00558     };
00559 
00560     template <typename BinaryPredicate> __host__ __device__ __forceinline__ binary_negate<BinaryPredicate> not2(const BinaryPredicate& pred)
00561     {
00562         return binary_negate<BinaryPredicate>(pred);
00563     }
00564 
00565     template <typename Op> struct binder1st : unary_function<typename Op::second_argument_type, typename Op::result_type>
00566     {
00567         __host__ __device__ __forceinline__ binder1st(const Op& op_, const typename Op::first_argument_type& arg1_) : op(op_), arg1(arg1_) {}
00568 
00569         __device__ __forceinline__ typename Op::result_type operator ()(typename TypeTraits<typename Op::second_argument_type>::ParameterType a) const
00570         {
00571             return op(arg1, a);
00572         }
00573 
00574         __device__ __forceinline__ binder1st(const binder1st& other) :
00575         unary_function<typename Op::second_argument_type, typename Op::result_type>(){}
00576 
00577         const Op op;
00578         const typename Op::first_argument_type arg1;
00579     };
00580 
00581     template <typename Op, typename T> __host__ __device__ __forceinline__ binder1st<Op> bind1st(const Op& op, const T& x)
00582     {
00583         return binder1st<Op>(op, typename Op::first_argument_type(x));
00584     }
00585 
00586     template <typename Op> struct binder2nd : unary_function<typename Op::first_argument_type, typename Op::result_type>
00587     {
00588         __host__ __device__ __forceinline__ binder2nd(const Op& op_, const typename Op::second_argument_type& arg2_) : op(op_), arg2(arg2_) {}
00589 
00590         __forceinline__ __device__ typename Op::result_type operator ()(typename TypeTraits<typename Op::first_argument_type>::ParameterType a) const
00591         {
00592             return op(a, arg2);
00593         }
00594 
00595          __device__ __forceinline__ binder2nd(const binder2nd& other) :
00596         unary_function<typename Op::first_argument_type, typename Op::result_type>(), op(other.op), arg2(other.arg2){}
00597 
00598         const Op op;
00599         const typename Op::second_argument_type arg2;
00600     };
00601 
00602     template <typename Op, typename T> __host__ __device__ __forceinline__ binder2nd<Op> bind2nd(const Op& op, const T& x)
00603     {
00604         return binder2nd<Op>(op, typename Op::second_argument_type(x));
00605     }
00606 
00607     // Functor Traits
00608     template <typename F> struct IsUnaryFunction
00609     {
00610         typedef char Yes;
00611         struct No {Yes a[2];};
00612 
00613         template <typename T, typename D> static Yes check(unary_function<T, D>);
00614         static No check(...);
00615 
00616         static F makeF();
00617 
00618         enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
00619     };
00620 
00621     template <typename F> struct IsBinaryFunction
00622     {
00623         typedef char Yes;
00624         struct No {Yes a[2];};
00625 
00626         template <typename T1, typename T2, typename D> static Yes check(binary_function<T1, T2, D>);
00627         static No check(...);
00628 
00629         static F makeF();
00630 
00631         enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
00632     };
00633 
00634     namespace functional_detail
00635     {
00636         template <size_t src_elem_size, size_t dst_elem_size> struct UnOpShift { enum { shift = 1 }; };
00637         template <size_t src_elem_size> struct UnOpShift<src_elem_size, 1> { enum { shift = 4 }; };
00638         template <size_t src_elem_size> struct UnOpShift<src_elem_size, 2> { enum { shift = 2 }; };
00639 
00640         template <typename T, typename D> struct DefaultUnaryShift
00641         {
00642             enum { shift = UnOpShift<sizeof(T), sizeof(D)>::shift };
00643         };
00644 
00645         template <size_t src_elem_size1, size_t src_elem_size2, size_t dst_elem_size> struct BinOpShift { enum { shift = 1 }; };
00646         template <size_t src_elem_size1, size_t src_elem_size2> struct BinOpShift<src_elem_size1, src_elem_size2, 1> { enum { shift = 4 }; };
00647         template <size_t src_elem_size1, size_t src_elem_size2> struct BinOpShift<src_elem_size1, src_elem_size2, 2> { enum { shift = 2 }; };
00648 
00649         template <typename T1, typename T2, typename D> struct DefaultBinaryShift
00650         {
00651             enum { shift = BinOpShift<sizeof(T1), sizeof(T2), sizeof(D)>::shift };
00652         };
00653 
00654         template <typename Func, bool unary = IsUnaryFunction<Func>::value> struct ShiftDispatcher;
00655         template <typename Func> struct ShiftDispatcher<Func, true>
00656         {
00657             enum { shift = DefaultUnaryShift<typename Func::argument_type, typename Func::result_type>::shift };
00658         };
00659         template <typename Func> struct ShiftDispatcher<Func, false>
00660         {
00661             enum { shift = DefaultBinaryShift<typename Func::first_argument_type, typename Func::second_argument_type, typename Func::result_type>::shift };
00662         };
00663     }
00664 
00665     template <typename Func> struct DefaultTransformShift
00666     {
00667         enum { shift = functional_detail::ShiftDispatcher<Func>::shift };
00668     };
00669 
00670     template <typename Func> struct DefaultTransformFunctorTraits
00671     {
00672         enum { simple_block_dim_x = 16 };
00673         enum { simple_block_dim_y = 16 };
00674 
00675         enum { smart_block_dim_x = 16 };
00676         enum { smart_block_dim_y = 16 };
00677         enum { smart_shift = DefaultTransformShift<Func>::shift };
00678     };
00679 
00680     template <typename Func> struct TransformFunctorTraits : DefaultTransformFunctorTraits<Func> {};
00681 
00682 #define OPENCV_GPU_TRANSFORM_FUNCTOR_TRAITS(type) \
00683     template <> struct TransformFunctorTraits< type > : DefaultTransformFunctorTraits< type >
00684 }}} // namespace cv { namespace gpu { namespace device
00685 
00686 #endif // __OPENCV_GPU_FUNCTIONAL_HPP__