Home | History | Annotate | Download | only in cuda
      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 #include "opencv2/opencv_modules.hpp"
     44 
     45 #ifndef HAVE_OPENCV_CUDEV
     46 
     47 #error "opencv_cudev is required"
     48 
     49 #else
     50 
     51 #include "opencv2/cudaarithm.hpp"
     52 #include "opencv2/cudev.hpp"
     53 #include "opencv2/core/private.cuda.hpp"
     54 
     55 using namespace cv;
     56 using namespace cv::cuda;
     57 using namespace cv::cudev;
     58 
     59 namespace
     60 {
     61     texture<uchar, cudaTextureType1D, cudaReadModeElementType> texLutTable;
     62 
     63     class LookUpTableImpl : public LookUpTable
     64     {
     65     public:
     66         LookUpTableImpl(InputArray lut);
     67         ~LookUpTableImpl();
     68 
     69         void transform(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
     70 
     71     private:
     72         GpuMat d_lut;
     73         cudaTextureObject_t texLutTableObj;
     74         bool cc30;
     75     };
     76 
     77     LookUpTableImpl::LookUpTableImpl(InputArray _lut)
     78     {
     79         if (_lut.kind() == _InputArray::CUDA_GPU_MAT)
     80         {
     81             d_lut = _lut.getGpuMat();
     82         }
     83         else
     84         {
     85             Mat h_lut = _lut.getMat();
     86             d_lut.upload(Mat(1, 256, h_lut.type(), h_lut.data));
     87         }
     88 
     89         CV_Assert( d_lut.depth() == CV_8U );
     90         CV_Assert( d_lut.rows == 1 && d_lut.cols == 256 );
     91 
     92         cc30 = deviceSupports(FEATURE_SET_COMPUTE_30);
     93 
     94         if (cc30)
     95         {
     96             // Use the texture object
     97             cudaResourceDesc texRes;
     98             std::memset(&texRes, 0, sizeof(texRes));
     99             texRes.resType = cudaResourceTypeLinear;
    100             texRes.res.linear.devPtr = d_lut.data;
    101             texRes.res.linear.desc = cudaCreateChannelDesc<uchar>();
    102             texRes.res.linear.sizeInBytes = 256 * d_lut.channels() * sizeof(uchar);
    103 
    104             cudaTextureDesc texDescr;
    105             std::memset(&texDescr, 0, sizeof(texDescr));
    106 
    107             CV_CUDEV_SAFE_CALL( cudaCreateTextureObject(&texLutTableObj, &texRes, &texDescr, 0) );
    108         }
    109         else
    110         {
    111             // Use the texture reference
    112             cudaChannelFormatDesc desc = cudaCreateChannelDesc<uchar>();
    113             CV_CUDEV_SAFE_CALL( cudaBindTexture(0, &texLutTable, d_lut.data, &desc) );
    114         }
    115     }
    116 
    117     LookUpTableImpl::~LookUpTableImpl()
    118     {
    119         if (cc30)
    120         {
    121             // Use the texture object
    122             cudaDestroyTextureObject(texLutTableObj);
    123         }
    124         else
    125         {
    126             // Use the texture reference
    127             cudaUnbindTexture(texLutTable);
    128         }
    129     }
    130 
    131     struct LutTablePtrC1
    132     {
    133         typedef uchar value_type;
    134         typedef uchar index_type;
    135 
    136         cudaTextureObject_t texLutTableObj;
    137 
    138         __device__ __forceinline__ uchar operator ()(uchar, uchar x) const
    139         {
    140         #if CV_CUDEV_ARCH < 300
    141             // Use the texture reference
    142             return tex1Dfetch(texLutTable, x);
    143         #else
    144             // Use the texture object
    145             return tex1Dfetch<uchar>(texLutTableObj, x);
    146         #endif
    147         }
    148     };
    149     struct LutTablePtrC3
    150     {
    151         typedef uchar3 value_type;
    152         typedef uchar3 index_type;
    153 
    154         cudaTextureObject_t texLutTableObj;
    155 
    156         __device__ __forceinline__ uchar3 operator ()(const uchar3&, const uchar3& x) const
    157         {
    158         #if CV_CUDEV_ARCH < 300
    159             // Use the texture reference
    160             return make_uchar3(tex1Dfetch(texLutTable, x.x * 3), tex1Dfetch(texLutTable, x.y * 3 + 1), tex1Dfetch(texLutTable, x.z * 3 + 2));
    161         #else
    162             // Use the texture object
    163             return make_uchar3(tex1Dfetch<uchar>(texLutTableObj, x.x * 3), tex1Dfetch<uchar>(texLutTableObj, x.y * 3 + 1), tex1Dfetch<uchar>(texLutTableObj, x.z * 3 + 2));
    164         #endif
    165         }
    166     };
    167 
    168     void LookUpTableImpl::transform(InputArray _src, OutputArray _dst, Stream& stream)
    169     {
    170         GpuMat src = getInputMat(_src, stream);
    171 
    172         const int cn = src.channels();
    173         const int lut_cn = d_lut.channels();
    174 
    175         CV_Assert( src.type() == CV_8UC1 || src.type() == CV_8UC3 );
    176         CV_Assert( lut_cn == 1 || lut_cn == cn );
    177 
    178         GpuMat dst = getOutputMat(_dst, src.size(), src.type(), stream);
    179 
    180         if (lut_cn == 1)
    181         {
    182             GpuMat_<uchar> src1(src.reshape(1));
    183             GpuMat_<uchar> dst1(dst.reshape(1));
    184 
    185             LutTablePtrC1 tbl;
    186             tbl.texLutTableObj = texLutTableObj;
    187 
    188             dst1.assign(lut_(src1, tbl), stream);
    189         }
    190         else if (lut_cn == 3)
    191         {
    192             GpuMat_<uchar3>& src3 = (GpuMat_<uchar3>&) src;
    193             GpuMat_<uchar3>& dst3 = (GpuMat_<uchar3>&) dst;
    194 
    195             LutTablePtrC3 tbl;
    196             tbl.texLutTableObj = texLutTableObj;
    197 
    198             dst3.assign(lut_(src3, tbl), stream);
    199         }
    200 
    201         syncOutput(dst, _dst, stream);
    202     }
    203 }
    204 
    205 Ptr<LookUpTable> cv::cuda::createLookUpTable(InputArray lut)
    206 {
    207     return makePtr<LookUpTableImpl>(lut);
    208 }
    209 
    210 #endif
    211