Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cuda_gpu_mat.cpp Source File

cuda_gpu_mat.cpp

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 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
00016 // Third party copyrights are property of their respective owners.
00017 //
00018 // Redistribution and use in source and binary forms, with or without modification,
00019 // are permitted provided that the following conditions are met:
00020 //
00021 //   * Redistribution's of source code must retain the above copyright notice,
00022 //     this list of conditions and the following disclaimer.
00023 //
00024 //   * Redistribution's in binary form must reproduce the above copyright notice,
00025 //     this list of conditions and the following disclaimer in the documentation
00026 //     and/or other materials provided with the distribution.
00027 //
00028 //   * The name of the copyright holders may not be used to endorse or promote products
00029 //     derived from this software without specific prior written permission.
00030 //
00031 // This software is provided by the copyright holders and contributors "as is" and
00032 // any express or implied warranties, including, but not limited to, the implied
00033 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00034 // In no event shall the Intel Corporation or contributors be liable for any direct,
00035 // indirect, incidental, special, exemplary, or consequential damages
00036 // (including, but not limited to, procurement of substitute goods or services;
00037 // loss of use, data, or profits; or business interruption) however caused
00038 // and on any theory of liability, whether in contract, strict liability,
00039 // or tort (including negligence or otherwise) arising in any way out of
00040 // the use of this software, even if advised of the possibility of such damage.
00041 //
00042 //M*/
00043 
00044 #include "precomp.hpp"
00045 
00046 using namespace cv;
00047 using namespace cv::cuda;
00048 
00049 cv::cuda::GpuMat::GpuMat(int rows_, int cols_, int type_, void* data_, size_t step_) :
00050     flags(Mat::MAGIC_VAL + (type_ & Mat::TYPE_MASK)), rows(rows_), cols(cols_),
00051     step(step_), data((uchar*)data_), refcount(0),
00052     datastart((uchar*)data_), dataend((const uchar*)data_),
00053     allocator(defaultAllocator())
00054 {
00055     size_t minstep = cols * elemSize();
00056 
00057     if (step == Mat::AUTO_STEP)
00058     {
00059         step = minstep;
00060         flags  |= Mat::CONTINUOUS_FLAG;
00061     }
00062     else
00063     {
00064         if (rows == 1)
00065             step = minstep;
00066 
00067         CV_DbgAssert( step >= minstep );
00068 
00069         flags  |= step == minstep ? Mat::CONTINUOUS_FLAG : 0;
00070     }
00071 
00072     dataend += step * (rows - 1) + minstep;
00073 }
00074 
00075 cv::cuda::GpuMat::GpuMat(Size size_, int type_, void* data_, size_t step_) :
00076     flags(Mat::MAGIC_VAL + (type_ & Mat::TYPE_MASK)), rows(size_.height), cols(size_.width),
00077     step(step_), data((uchar*)data_), refcount(0),
00078     datastart((uchar*)data_), dataend((const uchar*)data_),
00079     allocator(defaultAllocator())
00080 {
00081     size_t minstep = cols * elemSize();
00082 
00083     if (step == Mat::AUTO_STEP)
00084     {
00085         step = minstep;
00086         flags  |= Mat::CONTINUOUS_FLAG;
00087     }
00088     else
00089     {
00090         if (rows == 1)
00091             step = minstep;
00092 
00093         CV_DbgAssert( step >= minstep );
00094 
00095         flags  |= step == minstep ? Mat::CONTINUOUS_FLAG : 0;
00096     }
00097 
00098     dataend += step * (rows - 1) + minstep;
00099 }
00100 
00101 cv::cuda::GpuMat::GpuMat(const GpuMat& m, Range rowRange_, Range colRange_)
00102 {
00103     flags = m.flags ;
00104     step = m.step; refcount = m.refcount;
00105     data = m.data; datastart = m.datastart; dataend = m.dataend;
00106     allocator = m.allocator;
00107 
00108     if (rowRange_ == Range::all())
00109     {
00110         rows = m.rows;
00111     }
00112     else
00113     {
00114         CV_Assert( 0 <= rowRange_.start && rowRange_.start <= rowRange_.end && rowRange_.end <= m.rows );
00115 
00116         rows = rowRange_.size();
00117         data += step*rowRange_.start;
00118     }
00119 
00120     if (colRange_ == Range::all())
00121     {
00122         cols = m.cols;
00123     }
00124     else
00125     {
00126         CV_Assert( 0 <= colRange_.start && colRange_.start <= colRange_.end && colRange_.end <= m.cols );
00127 
00128         cols = colRange_.size();
00129         data += colRange_.start*elemSize();
00130         flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
00131     }
00132 
00133     if (rows == 1)
00134         flags |= Mat::CONTINUOUS_FLAG;
00135 
00136     if (refcount)
00137         CV_XADD(refcount, 1);
00138 
00139     if (rows <= 0 || cols <= 0)
00140         rows = cols = 0;
00141 }
00142 
00143 cv::cuda::GpuMat::GpuMat(const GpuMat& m, Rect roi) :
00144     flags(m.flags), rows(roi.height), cols(roi.width),
00145     step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
00146     datastart(m.datastart), dataend(m.dataend),
00147     allocator(m.allocator)
00148 {
00149     flags  &= roi.width < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
00150     data += roi.x * elemSize();
00151 
00152     CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
00153 
00154     if (refcount)
00155         CV_XADD(refcount, 1);
00156 
00157     if (rows <= 0 || cols <= 0)
00158         rows = cols = 0;
00159 }
00160 
00161 GpuMat cv::cuda::GpuMat::reshape(int new_cn, int new_rows) const
00162 {
00163     GpuMat hdr = *this;
00164 
00165     int cn = channels();
00166     if (new_cn == 0)
00167         new_cn = cn;
00168 
00169     int total_width = cols * cn;
00170 
00171     if ((new_cn > total_width || total_width % new_cn != 0) && new_rows == 0)
00172         new_rows = rows * total_width / new_cn;
00173 
00174     if (new_rows != 0 && new_rows != rows)
00175     {
00176         int total_size = total_width * rows;
00177 
00178         if (!isContinuous())
00179             CV_Error(cv::Error::BadStep, "The matrix is not continuous, thus its number of rows can not be changed");
00180 
00181         if ((unsigned)new_rows > (unsigned)total_size)
00182             CV_Error(cv::Error::StsOutOfRange, "Bad new number of rows");
00183 
00184         total_width = total_size / new_rows;
00185 
00186         if (total_width * new_rows != total_size)
00187             CV_Error(cv::Error::StsBadArg, "The total number of matrix elements is not divisible by the new number of rows");
00188 
00189         hdr.rows = new_rows;
00190         hdr.step = total_width * elemSize1();
00191     }
00192 
00193     int new_width = total_width / new_cn;
00194 
00195     if (new_width * new_cn != total_width)
00196         CV_Error(cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels");
00197 
00198     hdr.cols = new_width;
00199     hdr.flags  = (hdr.flags  & ~CV_MAT_CN_MASK) | ((new_cn - 1) << CV_CN_SHIFT);
00200 
00201     return hdr;
00202 }
00203 
00204 void cv::cuda::GpuMat::locateROI(Size& wholeSize, Point & ofs) const
00205 {
00206     CV_DbgAssert( step > 0 );
00207 
00208     size_t esz = elemSize();
00209     ptrdiff_t delta1 = data - datastart;
00210     ptrdiff_t delta2 = dataend - datastart;
00211 
00212     if (delta1 == 0)
00213     {
00214         ofs.x = ofs.y = 0;
00215     }
00216     else
00217     {
00218         ofs.y = static_cast<int>(delta1 / step);
00219         ofs.x = static_cast<int>((delta1 - step * ofs.y) / esz);
00220 
00221         CV_DbgAssert( data == datastart + ofs.y * step + ofs.x * esz );
00222     }
00223 
00224     size_t minstep = (ofs.x + cols) * esz;
00225 
00226     wholeSize.height = std::max(static_cast<int>((delta2 - minstep) / step + 1), ofs.y + rows);
00227     wholeSize.width = std::max(static_cast<int>((delta2 - step * (wholeSize.height - 1)) / esz), ofs.x + cols);
00228 }
00229 
00230 GpuMat& cv::cuda::GpuMat::adjustROI(int dtop, int dbottom, int dleft, int dright)
00231 {
00232     Size wholeSize;
00233     Point  ofs;
00234     locateROI(wholeSize, ofs);
00235 
00236     size_t esz = elemSize();
00237 
00238     int row1 = std::max(ofs.y - dtop, 0);
00239     int row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
00240 
00241     int col1 = std::max(ofs.x - dleft, 0);
00242     int col2 = std::min(ofs.x + cols + dright, wholeSize.width);
00243 
00244     data += (row1 - ofs.y) * step + (col1 - ofs.x) * esz;
00245     rows = row2 - row1;
00246     cols = col2 - col1;
00247 
00248     if (esz * cols == step || rows == 1)
00249         flags |= Mat::CONTINUOUS_FLAG;
00250     else
00251         flags &= ~Mat::CONTINUOUS_FLAG;
00252 
00253     return *this;
00254 }
00255 
00256 namespace
00257 {
00258     template <class ObjType>
00259     void createContinuousImpl(int rows, int cols, int type, ObjType& obj)
00260     {
00261         const int area = rows * cols;
00262 
00263         if (obj.empty() || obj.type() != type || !obj.isContinuous() || obj.size().area() != area)
00264             obj.create(1, area, type);
00265 
00266         obj = obj.reshape(obj.channels(), rows);
00267     }
00268 }
00269 
00270 void cv::cuda::createContinuous(int rows, int cols, int type, OutputArray arr)
00271 {
00272     switch (arr.kind())
00273     {
00274     case _InputArray::MAT:
00275         ::createContinuousImpl(rows, cols, type, arr.getMatRef());
00276         break;
00277 
00278     case _InputArray::CUDA_GPU_MAT:
00279         ::createContinuousImpl(rows, cols, type, arr.getGpuMatRef());
00280         break;
00281 
00282     case _InputArray::CUDA_HOST_MEM:
00283         ::createContinuousImpl(rows, cols, type, arr.getHostMemRef());
00284         break;
00285 
00286     default:
00287         arr.create(rows, cols, type);
00288     }
00289 }
00290 
00291 namespace
00292 {
00293     template <class ObjType>
00294     void ensureSizeIsEnoughImpl(int rows, int cols, int type, ObjType& obj)
00295     {
00296         if (obj.empty() || obj.type() != type || obj.data != obj.datastart)
00297         {
00298             obj.create(rows, cols, type);
00299         }
00300         else
00301         {
00302             const size_t esz = obj.elemSize();
00303             const ptrdiff_t delta2 = obj.dataend - obj.datastart;
00304 
00305             const size_t minstep = obj.cols * esz;
00306 
00307             Size wholeSize;
00308             wholeSize.height = std::max(static_cast<int>((delta2 - minstep) / static_cast<size_t>(obj.step) + 1), obj.rows);
00309             wholeSize.width = std::max(static_cast<int>((delta2 - static_cast<size_t>(obj.step) * (wholeSize.height - 1)) / esz), obj.cols);
00310 
00311             if (wholeSize.height < rows || wholeSize.width < cols)
00312             {
00313                 obj.create(rows, cols, type);
00314             }
00315             else
00316             {
00317                 obj.cols = cols;
00318                 obj.rows = rows;
00319             }
00320         }
00321     }
00322 }
00323 
00324 void cv::cuda::ensureSizeIsEnough(int rows, int cols, int type, OutputArray arr)
00325 {
00326     switch (arr.kind())
00327     {
00328     case _InputArray::MAT:
00329         ::ensureSizeIsEnoughImpl(rows, cols, type, arr.getMatRef());
00330         break;
00331 
00332     case _InputArray::CUDA_GPU_MAT:
00333         ::ensureSizeIsEnoughImpl(rows, cols, type, arr.getGpuMatRef());
00334         break;
00335 
00336     case _InputArray::CUDA_HOST_MEM:
00337         ::ensureSizeIsEnoughImpl(rows, cols, type, arr.getHostMemRef());
00338         break;
00339 
00340     default:
00341         arr.create(rows, cols, type);
00342     }
00343 }
00344 
00345 GpuMat cv::cuda::getInputMat(InputArray _src, Stream& stream)
00346 {
00347     GpuMat src;
00348 
00349 #ifndef HAVE_CUDA
00350     (void) _src;
00351     (void) stream;
00352     throw_no_cuda();
00353 #else
00354     if (_src.kind() == _InputArray::CUDA_GPU_MAT)
00355     {
00356         src = _src.getGpuMat();
00357     }
00358     else if (!_src.empty())
00359     {
00360         BufferPool pool(stream);
00361         src = pool.getBuffer(_src.size(), _src.type());
00362         src.upload(_src, stream);
00363     }
00364 #endif
00365 
00366     return src;
00367 }
00368 
00369 GpuMat cv::cuda::getOutputMat(OutputArray _dst, int rows, int cols, int type, Stream& stream)
00370 {
00371     GpuMat dst;
00372 
00373 #ifndef HAVE_CUDA
00374     (void) _dst;
00375     (void) rows;
00376     (void) cols;
00377     (void) type;
00378     (void) stream;
00379     throw_no_cuda();
00380 #else
00381     if (_dst.kind() == _InputArray::CUDA_GPU_MAT)
00382     {
00383         _dst.create(rows, cols, type);
00384         dst = _dst.getGpuMat();
00385     }
00386     else
00387     {
00388         BufferPool pool(stream);
00389         dst = pool.getBuffer(rows, cols, type);
00390     }
00391 #endif
00392 
00393     return dst;
00394 }
00395 
00396 void cv::cuda::syncOutput(const GpuMat& dst, OutputArray _dst, Stream& stream)
00397 {
00398 #ifndef HAVE_CUDA
00399     (void) dst;
00400     (void) _dst;
00401     (void) stream;
00402     throw_no_cuda();
00403 #else
00404     if (_dst.kind() != _InputArray::CUDA_GPU_MAT)
00405     {
00406         if (stream)
00407             dst.download(_dst, stream);
00408         else
00409             dst.download(_dst);
00410     }
00411 #endif
00412 }
00413 
00414 #ifndef HAVE_CUDA
00415 
00416 GpuMat::Allocator* cv::cuda::GpuMat::defaultAllocator()
00417 {
00418     return 0;
00419 }
00420 
00421 void cv::cuda::GpuMat::setDefaultAllocator(Allocator * allocator)
00422 {
00423     (void) allocator;
00424     throw_no_cuda();
00425 }
00426 
00427 void cv::cuda::GpuMat::create(int _rows, int _cols, int _type)
00428 {
00429     (void) _rows;
00430     (void) _cols;
00431     (void) _type;
00432     throw_no_cuda();
00433 }
00434 
00435 void cv::cuda::GpuMat::release()
00436 {
00437 }
00438 
00439 void cv::cuda::GpuMat::upload(InputArray arr)
00440 {
00441     (void) arr;
00442     throw_no_cuda();
00443 }
00444 
00445 void cv::cuda::GpuMat::upload(InputArray arr, Stream& _stream)
00446 {
00447     (void) arr;
00448     (void) _stream;
00449     throw_no_cuda();
00450 }
00451 
00452 void cv::cuda::GpuMat::download(OutputArray _dst) const
00453 {
00454     (void) _dst;
00455     throw_no_cuda();
00456 }
00457 
00458 void cv::cuda::GpuMat::download(OutputArray _dst, Stream& _stream) const
00459 {
00460     (void) _dst;
00461     (void) _stream;
00462     throw_no_cuda();
00463 }
00464 
00465 void cv::cuda::GpuMat::copyTo(OutputArray _dst) const
00466 {
00467     (void) _dst;
00468     throw_no_cuda();
00469 }
00470 
00471 void cv::cuda::GpuMat::copyTo(OutputArray _dst, Stream& _stream) const
00472 {
00473     (void) _dst;
00474     (void) _stream;
00475     throw_no_cuda();
00476 }
00477 
00478 void cv::cuda::GpuMat::copyTo(OutputArray _dst, InputArray _mask, Stream& _stream) const
00479 {
00480     (void) _dst;
00481     (void) _mask;
00482     (void) _stream;
00483     throw_no_cuda();
00484 }
00485 
00486 GpuMat& cv::cuda::GpuMat::setTo(Scalar  s, Stream& _stream)
00487 {
00488     (void) s;
00489     (void) _stream;
00490     throw_no_cuda();
00491     return *this;
00492 }
00493 
00494 GpuMat& cv::cuda::GpuMat::setTo(Scalar  s, InputArray _mask, Stream& _stream)
00495 {
00496     (void) s;
00497     (void) _mask;
00498     (void) _stream;
00499     throw_no_cuda();
00500     return *this;
00501 }
00502 
00503 void cv::cuda::GpuMat::convertTo(OutputArray _dst, int rtype, Stream& _stream) const
00504 {
00505     (void) _dst;
00506     (void) rtype;
00507     (void) _stream;
00508     throw_no_cuda();
00509 }
00510 
00511 void cv::cuda::GpuMat::convertTo(OutputArray _dst, int rtype, double alpha, double beta, Stream& _stream) const
00512 {
00513     (void) _dst;
00514     (void) rtype;
00515     (void) alpha;
00516     (void) beta;
00517     (void) _stream;
00518     throw_no_cuda();
00519 }
00520 
00521 #endif
00522