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 mat.inl.hpp Source File

mat.inl.hpp

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 // Copyright (C) 2015, Itseez Inc., all rights reserved.
00017 // Third party copyrights are property of their respective owners.
00018 //
00019 // Redistribution and use in source and binary forms, with or without modification,
00020 // are permitted provided that the following conditions are met:
00021 //
00022 //   * Redistribution's of source code must retain the above copyright notice,
00023 //     this list of conditions and the following disclaimer.
00024 //
00025 //   * Redistribution's in binary form must reproduce the above copyright notice,
00026 //     this list of conditions and the following disclaimer in the documentation
00027 //     and/or other materials provided with the distribution.
00028 //
00029 //   * The name of the copyright holders may not be used to endorse or promote products
00030 //     derived from this software without specific prior written permission.
00031 //
00032 // This software is provided by the copyright holders and contributors "as is" and
00033 // any express or implied warranties, including, but not limited to, the implied
00034 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00035 // In no event shall the Intel Corporation or contributors be liable for any direct,
00036 // indirect, incidental, special, exemplary, or consequential damages
00037 // (including, but not limited to, procurement of substitute goods or services;
00038 // loss of use, data, or profits; or business interruption) however caused
00039 // and on any theory of liability, whether in contract, strict liability,
00040 // or tort (including negligence or otherwise) arising in any way out of
00041 // the use of this software, even if advised of the possibility of such damage.
00042 //
00043 //M*/
00044 
00045 #ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
00046 #define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
00047 
00048 #ifndef __cplusplus
00049 #  error mat.inl.hpp header must be compiled as C++
00050 #endif
00051 
00052 namespace cv
00053 {
00054 
00055 //! @cond IGNORED
00056 
00057 //////////////////////// Input/Output Arrays ////////////////////////
00058 
00059 inline void _InputArray::init(int _flags, const void* _obj)
00060 { flags = _flags; obj = (void*)_obj; }
00061 
00062 inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
00063 { flags = _flags; obj = (void*)_obj; sz = _sz; }
00064 
00065 inline void* _InputArray::getObj() const { return obj; }
00066 inline int _InputArray::getFlags() const { return flags; }
00067 inline Size _InputArray::getSz() const { return sz; }
00068 
00069 inline _InputArray::_InputArray() { init(NONE, 0); }
00070 inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
00071 inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
00072 inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
00073 inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
00074 inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }
00075 
00076 template<typename _Tp> inline
00077 _InputArray::_InputArray(const std::vector<_Tp>& vec)
00078 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
00079 
00080 inline
00081 _InputArray::_InputArray(const std::vector<bool>& vec)
00082 { init(FIXED_TYPE + STD_BOOL_VECTOR + DataType<bool>::type + ACCESS_READ, &vec); }
00083 
00084 template<typename _Tp> inline
00085 _InputArray::_InputArray(const std::vector<std::vector<_Tp> >& vec)
00086 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
00087 
00088 template<typename _Tp> inline
00089 _InputArray::_InputArray(const std::vector<Mat_<_Tp> >& vec)
00090 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_READ, &vec); }
00091 
00092 template<typename _Tp, int m, int n> inline
00093 _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
00094 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, &mtx, Size(n, m)); }
00095 
00096 template<typename _Tp> inline
00097 _InputArray::_InputArray(const _Tp* vec, int n)
00098 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, vec, Size(n, 1)); }
00099 
00100 template<typename _Tp> inline
00101 _InputArray::_InputArray(const Mat_<_Tp>& m)
00102 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_READ, &m); }
00103 
00104 inline _InputArray::_InputArray(const double& val)
00105 { init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); }
00106 
00107 inline _InputArray::_InputArray(const MatExpr& expr)
00108 { init(FIXED_TYPE + FIXED_SIZE + EXPR + ACCESS_READ, &expr); }
00109 
00110 inline _InputArray::_InputArray(const cuda::GpuMat& d_mat)
00111 { init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
00112 
00113 inline _InputArray::_InputArray(const std::vector<cuda::GpuMat>& d_mat)
00114 {   init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);}
00115 
00116 inline _InputArray::_InputArray(const ogl::Buffer& buf)
00117 { init(OPENGL_BUFFER + ACCESS_READ, &buf); }
00118 
00119 inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
00120 { init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
00121 
00122 inline _InputArray::~_InputArray() {}
00123 
00124 inline Mat _InputArray::getMat(int i) const
00125 {
00126     if( kind() == MAT && i < 0 )
00127         return *(const Mat*)obj;
00128     return getMat_(i);
00129 }
00130 
00131 inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }
00132 inline bool _InputArray::isUMat() const  { return kind() == _InputArray::UMAT; }
00133 inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
00134 inline bool _InputArray::isUMatVector() const  { return kind() == _InputArray::STD_VECTOR_UMAT; }
00135 inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; }
00136 inline bool _InputArray::isVector() const { return kind() == _InputArray::STD_VECTOR || kind() == _InputArray::STD_BOOL_VECTOR; }
00137 inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::STD_VECTOR_CUDA_GPU_MAT; }
00138 
00139 ////////////////////////////////////////////////////////////////////////////////////////
00140 
00141 inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
00142 inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
00143 inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
00144 inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
00145 inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
00146 inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
00147 
00148 template<typename _Tp> inline
00149 _OutputArray::_OutputArray(std::vector<_Tp>& vec)
00150 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00151 
00152 inline
00153 _OutputArray::_OutputArray(std::vector<bool>&)
00154 { CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an output array\n"); }
00155 
00156 template<typename _Tp> inline
00157 _OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
00158 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00159 
00160 template<typename _Tp> inline
00161 _OutputArray::_OutputArray(std::vector<Mat_<_Tp> >& vec)
00162 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00163 
00164 template<typename _Tp> inline
00165 _OutputArray::_OutputArray(Mat_<_Tp>& m)
00166 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
00167 
00168 template<typename _Tp, int m, int n> inline
00169 _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
00170 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
00171 
00172 template<typename _Tp> inline
00173 _OutputArray::_OutputArray(_Tp* vec, int n)
00174 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
00175 
00176 template<typename _Tp> inline
00177 _OutputArray::_OutputArray(const std::vector<_Tp>& vec)
00178 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00179 
00180 template<typename _Tp> inline
00181 _OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
00182 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00183 
00184 template<typename _Tp> inline
00185 _OutputArray::_OutputArray(const std::vector<Mat_<_Tp> >& vec)
00186 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00187 
00188 template<typename _Tp> inline
00189 _OutputArray::_OutputArray(const Mat_<_Tp>& m)
00190 { init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
00191 
00192 template<typename _Tp, int m, int n> inline
00193 _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
00194 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
00195 
00196 template<typename _Tp> inline
00197 _OutputArray::_OutputArray(const _Tp* vec, int n)
00198 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
00199 
00200 inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat)
00201 { init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
00202 
00203 inline _OutputArray::_OutputArray(std::vector<cuda::GpuMat>& d_mat)
00204 {   init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);}
00205 
00206 inline _OutputArray::_OutputArray(ogl::Buffer& buf)
00207 { init(OPENGL_BUFFER + ACCESS_WRITE, &buf); }
00208 
00209 inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem)
00210 { init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
00211 
00212 inline _OutputArray::_OutputArray(const Mat& m)
00213 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); }
00214 
00215 inline _OutputArray::_OutputArray(const std::vector<Mat>& vec)
00216 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
00217 
00218 inline _OutputArray::_OutputArray(const UMat& m)
00219 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); }
00220 
00221 inline _OutputArray::_OutputArray(const std::vector<UMat>& vec)
00222 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
00223 
00224 inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat)
00225 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
00226 
00227 
00228 inline _OutputArray::_OutputArray(const ogl::Buffer& buf)
00229 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); }
00230 
00231 inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
00232 { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
00233 
00234 ///////////////////////////////////////////////////////////////////////////////////////////
00235 
00236 inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
00237 inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
00238 inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
00239 inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
00240 inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
00241 inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); }
00242 
00243 template<typename _Tp> inline
00244 _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
00245 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00246 
00247 inline _InputOutputArray::_InputOutputArray(std::vector<bool>&)
00248 { CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an input/output array\n"); }
00249 
00250 template<typename _Tp> inline
00251 _InputOutputArray::_InputOutputArray(std::vector<std::vector<_Tp> >& vec)
00252 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00253 
00254 template<typename _Tp> inline
00255 _InputOutputArray::_InputOutputArray(std::vector<Mat_<_Tp> >& vec)
00256 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
00257 
00258 template<typename _Tp> inline
00259 _InputOutputArray::_InputOutputArray(Mat_<_Tp>& m)
00260 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
00261 
00262 template<typename _Tp, int m, int n> inline
00263 _InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx)
00264 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
00265 
00266 template<typename _Tp> inline
00267 _InputOutputArray::_InputOutputArray(_Tp* vec, int n)
00268 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
00269 
00270 template<typename _Tp> inline
00271 _InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec)
00272 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00273 
00274 template<typename _Tp> inline
00275 _InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec)
00276 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00277 
00278 template<typename _Tp> inline
00279 _InputOutputArray::_InputOutputArray(const std::vector<Mat_<_Tp> >& vec)
00280 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
00281 
00282 template<typename _Tp> inline
00283 _InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m)
00284 { init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
00285 
00286 template<typename _Tp, int m, int n> inline
00287 _InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx)
00288 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
00289 
00290 template<typename _Tp> inline
00291 _InputOutputArray::_InputOutputArray(const _Tp* vec, int n)
00292 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
00293 
00294 inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat)
00295 { init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
00296 
00297 inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf)
00298 { init(OPENGL_BUFFER + ACCESS_RW, &buf); }
00299 
00300 inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem)
00301 { init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
00302 
00303 inline _InputOutputArray::_InputOutputArray(const Mat& m)
00304 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); }
00305 
00306 inline _InputOutputArray::_InputOutputArray(const std::vector<Mat>& vec)
00307 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); }
00308 
00309 inline _InputOutputArray::_InputOutputArray(const UMat& m)
00310 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); }
00311 
00312 inline _InputOutputArray::_InputOutputArray(const std::vector<UMat>& vec)
00313 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); }
00314 
00315 inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat)
00316 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
00317 inline _InputOutputArray::_InputOutputArray(const std::vector<cuda::GpuMat>& d_mat)
00318 {   init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);}
00319 
00320 inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf)
00321 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); }
00322 
00323 inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
00324 { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
00325 
00326 //////////////////////////////////////////// Mat //////////////////////////////////////////
00327 
00328 inline
00329 Mat::Mat()
00330     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00331       datalimit(0), allocator(0), u(0), size(&rows)
00332 {}
00333 
00334 inline
00335 Mat::Mat(int _rows, int _cols, int _type)
00336     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00337       datalimit(0), allocator(0), u(0), size(&rows)
00338 {
00339     create(_rows, _cols, _type);
00340 }
00341 
00342 inline
00343 Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
00344     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00345       datalimit(0), allocator(0), u(0), size(&rows)
00346 {
00347     create(_rows, _cols, _type);
00348     *this = _s;
00349 }
00350 
00351 inline
00352 Mat::Mat(Size _sz, int _type)
00353     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00354       datalimit(0), allocator(0), u(0), size(&rows)
00355 {
00356     create( _sz.height, _sz.width, _type );
00357 }
00358 
00359 inline
00360 Mat::Mat(Size _sz, int _type, const Scalar& _s)
00361     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00362       datalimit(0), allocator(0), u(0), size(&rows)
00363 {
00364     create(_sz.height, _sz.width, _type);
00365     *this = _s;
00366 }
00367 
00368 inline
00369 Mat::Mat(int _dims, const int* _sz, int _type)
00370     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00371       datalimit(0), allocator(0), u(0), size(&rows)
00372 {
00373     create(_dims, _sz, _type);
00374 }
00375 
00376 inline
00377 Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
00378     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00379       datalimit(0), allocator(0), u(0), size(&rows)
00380 {
00381     create(_dims, _sz, _type);
00382     *this = _s;
00383 }
00384 
00385 inline
00386 Mat::Mat(const Mat& m)
00387     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
00388       datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
00389       u(m.u), size(&rows)
00390 {
00391     if( u )
00392         CV_XADD(&u->refcount, 1);
00393     if( m.dims <= 2 )
00394     {
00395         step[0] = m.step[0]; step[1] = m.step[1];
00396     }
00397     else
00398     {
00399         dims = 0;
00400         copySize(m);
00401     }
00402 }
00403 
00404 inline
00405 Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
00406     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
00407       data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
00408       allocator(0), u(0), size(&rows)
00409 {
00410     CV_Assert(total() == 0 || data != NULL);
00411 
00412     size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
00413     size_t minstep = cols * esz;
00414     if( _step == AUTO_STEP )
00415     {
00416         _step = minstep;
00417         flags |= CONTINUOUS_FLAG;
00418     }
00419     else
00420     {
00421         if( rows == 1 ) _step = minstep;
00422         CV_DbgAssert( _step >= minstep );
00423 
00424         if (_step % esz1 != 0)
00425         {
00426             CV_Error(Error::BadStep, "Step must be a multiple of esz1");
00427         }
00428 
00429         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
00430     }
00431     step[0] = _step;
00432     step[1] = esz;
00433     datalimit = datastart + _step * rows;
00434     dataend = datalimit - _step + minstep;
00435 }
00436 
00437 inline
00438 Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
00439     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
00440       data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
00441       allocator(0), u(0), size(&rows)
00442 {
00443     CV_Assert(total() == 0 || data != NULL);
00444 
00445     size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
00446     size_t minstep = cols*esz;
00447     if( _step == AUTO_STEP )
00448     {
00449         _step = minstep;
00450         flags |= CONTINUOUS_FLAG;
00451     }
00452     else
00453     {
00454         if( rows == 1 ) _step = minstep;
00455         CV_DbgAssert( _step >= minstep );
00456 
00457         if (_step % esz1 != 0)
00458         {
00459             CV_Error(Error::BadStep, "Step must be a multiple of esz1");
00460         }
00461 
00462         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
00463     }
00464     step[0] = _step;
00465     step[1] = esz;
00466     datalimit = datastart + _step*rows;
00467     dataend = datalimit - _step + minstep;
00468 }
00469 
00470 template<typename _Tp> inline
00471 Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
00472     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
00473       cols(1), data(0), datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00474 {
00475     if(vec.empty())
00476         return;
00477     if( !copyData )
00478     {
00479         step[0] = step[1] = sizeof(_Tp);
00480         datastart = data = (uchar*)&vec[0];
00481         datalimit = dataend = datastart + rows * step[0];
00482     }
00483     else
00484         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
00485 }
00486 
00487 template<typename _Tp, int n> inline
00488 Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
00489     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
00490       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00491 {
00492     if( !copyData )
00493     {
00494         step[0] = step[1] = sizeof(_Tp);
00495         datastart = data = (uchar*)vec.val;
00496         datalimit = dataend = datastart + rows * step[0];
00497     }
00498     else
00499         Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
00500 }
00501 
00502 
00503 template<typename _Tp, int m, int n> inline
00504 Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
00505     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
00506       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00507 {
00508     if( !copyData )
00509     {
00510         step[0] = cols * sizeof(_Tp);
00511         step[1] = sizeof(_Tp);
00512         datastart = data = (uchar*)M.val;
00513         datalimit = dataend = datastart + rows * step[0];
00514     }
00515     else
00516         Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
00517 }
00518 
00519 template<typename _Tp> inline
00520 Mat::Mat(const Point_<_Tp>& pt, bool copyData)
00521     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
00522       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00523 {
00524     if( !copyData )
00525     {
00526         step[0] = step[1] = sizeof(_Tp);
00527         datastart = data = (uchar*)&pt.x;
00528         datalimit = dataend = datastart + rows * step[0];
00529     }
00530     else
00531     {
00532         create(2, 1, DataType<_Tp>::type);
00533         ((_Tp*)data)[0] = pt.x;
00534         ((_Tp*)data)[1] = pt.y;
00535     }
00536 }
00537 
00538 template<typename _Tp> inline
00539 Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
00540     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
00541       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00542 {
00543     if( !copyData )
00544     {
00545         step[0] = step[1] = sizeof(_Tp);
00546         datastart = data = (uchar*)&pt.x;
00547         datalimit = dataend = datastart + rows * step[0];
00548     }
00549     else
00550     {
00551         create(3, 1, DataType<_Tp>::type);
00552         ((_Tp*)data)[0] = pt.x;
00553         ((_Tp*)data)[1] = pt.y;
00554         ((_Tp*)data)[2] = pt.z;
00555     }
00556 }
00557 
00558 template<typename _Tp> inline
00559 Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
00560     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
00561       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00562 {
00563     *this = commaInitializer.operator Mat_<_Tp>();
00564 }
00565 
00566 inline
00567 Mat::~Mat()
00568 {
00569     release();
00570     if( step.p != step.buf )
00571         fastFree(step.p);
00572 }
00573 
00574 inline
00575 Mat& Mat::operator = (const Mat& m)
00576 {
00577     if( this != &m )
00578     {
00579         if( m.u )
00580             CV_XADD(&m.u->refcount, 1);
00581         release();
00582         flags  = m.flags;
00583         if( dims <= 2 && m.dims <= 2 )
00584         {
00585             dims = m.dims;
00586             rows = m.rows;
00587             cols = m.cols;
00588             step[0] = m.step[0];
00589             step[1] = m.step[1];
00590         }
00591         else
00592             copySize(m);
00593         data = m.data;
00594         datastart = m.datastart;
00595         dataend = m.dataend;
00596         datalimit = m.datalimit;
00597         allocator = m.allocator;
00598         u = m.u;
00599     }
00600     return *this;
00601 }
00602 
00603 inline
00604 Mat Mat::row(int y) const
00605 {
00606     return Mat(*this, Range(y, y + 1), Range::all());
00607 }
00608 
00609 inline
00610 Mat Mat::col(int x) const
00611 {
00612     return Mat(*this, Range::all(), Range(x, x + 1));
00613 }
00614 
00615 inline
00616 Mat Mat::rowRange(int startrow, int endrow) const
00617 {
00618     return Mat(*this, Range(startrow, endrow), Range::all());
00619 }
00620 
00621 inline
00622 Mat Mat::rowRange(const Range& r) const
00623 {
00624     return Mat(*this, r, Range::all());
00625 }
00626 
00627 inline
00628 Mat Mat::colRange(int startcol, int endcol) const
00629 {
00630     return Mat(*this, Range::all(), Range(startcol, endcol));
00631 }
00632 
00633 inline
00634 Mat Mat::colRange(const Range& r) const
00635 {
00636     return Mat(*this, Range::all(), r);
00637 }
00638 
00639 inline
00640 Mat Mat::clone() const
00641 {
00642     Mat m;
00643     copyTo(m);
00644     return m;
00645 }
00646 
00647 inline
00648 void Mat::assignTo( Mat& m, int _type ) const
00649 {
00650     if( _type < 0 )
00651         m = *this;
00652     else
00653         convertTo(m, _type);
00654 }
00655 
00656 inline
00657 void Mat::create(int _rows, int _cols, int _type)
00658 {
00659     _type &= TYPE_MASK;
00660     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
00661         return;
00662     int sz[] = {_rows, _cols};
00663     create(2, sz, _type);
00664 }
00665 
00666 inline
00667 void Mat::create(Size _sz, int _type)
00668 {
00669     create(_sz.height, _sz.width, _type);
00670 }
00671 
00672 inline
00673 void Mat::addref()
00674 {
00675     if( u )
00676         CV_XADD(&u->refcount, 1);
00677 }
00678 
00679 inline void Mat::release()
00680 {
00681     if( u && CV_XADD(&u->refcount, -1) == 1 )
00682         deallocate();
00683     u = NULL;
00684     datastart = dataend = datalimit = data = 0;
00685     for(int i = 0; i < dims; i++)
00686         size.p[i] = 0;
00687 }
00688 
00689 inline
00690 Mat Mat::operator()( Range _rowRange, Range _colRange ) const
00691 {
00692     return Mat(*this, _rowRange, _colRange);
00693 }
00694 
00695 inline
00696 Mat Mat::operator()( const Rect& roi ) const
00697 {
00698     return Mat(*this, roi);
00699 }
00700 
00701 inline
00702 Mat Mat::operator()(const Range* ranges) const
00703 {
00704     return Mat(*this, ranges);
00705 }
00706 
00707 inline
00708 bool Mat::isContinuous() const
00709 {
00710     return (flags  & CONTINUOUS_FLAG) != 0;
00711 }
00712 
00713 inline
00714 bool Mat::isSubmatrix() const
00715 {
00716     return (flags  & SUBMATRIX_FLAG) != 0;
00717 }
00718 
00719 inline
00720 size_t Mat::elemSize() const
00721 {
00722     return dims > 0 ? step.p[dims - 1] : 0;
00723 }
00724 
00725 inline
00726 size_t Mat::elemSize1() const
00727 {
00728     return CV_ELEM_SIZE1(flags );
00729 }
00730 
00731 inline
00732 int Mat::type() const
00733 {
00734     return CV_MAT_TYPE(flags );
00735 }
00736 
00737 inline
00738 int Mat::depth() const
00739 {
00740     return CV_MAT_DEPTH(flags );
00741 }
00742 
00743 inline
00744 int Mat::channels() const
00745 {
00746     return CV_MAT_CN(flags );
00747 }
00748 
00749 inline
00750 size_t Mat::step1(int i) const
00751 {
00752     return step.p[i] / elemSize1();
00753 }
00754 
00755 inline
00756 bool Mat::empty() const
00757 {
00758     return data == 0 || total() == 0;
00759 }
00760 
00761 inline
00762 size_t Mat::total() const
00763 {
00764     if( dims <= 2 )
00765         return (size_t)rows * cols;
00766     size_t p = 1;
00767     for( int i = 0; i < dims; i++ )
00768         p *= size[i];
00769     return p;
00770 }
00771 
00772 inline
00773 uchar* Mat::ptr(int y)
00774 {
00775     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00776     return data + step.p[0] * y;
00777 }
00778 
00779 inline
00780 const uchar* Mat::ptr(int y) const
00781 {
00782     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00783     return data + step.p[0] * y;
00784 }
00785 
00786 template<typename _Tp> inline
00787 _Tp* Mat::ptr(int y)
00788 {
00789     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00790     return (_Tp*)(data + step.p[0] * y);
00791 }
00792 
00793 template<typename _Tp> inline
00794 const _Tp* Mat::ptr(int y) const
00795 {
00796     CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
00797     return (const _Tp*)(data + step.p[0] * y);
00798 }
00799 
00800 inline
00801 uchar* Mat::ptr(int i0, int i1)
00802 {
00803     CV_DbgAssert(dims >= 2);
00804     CV_DbgAssert(data);
00805     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00806     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00807     return data + i0 * step.p[0] + i1 * step.p[1];
00808 }
00809 
00810 inline
00811 const uchar* Mat::ptr(int i0, int i1) const
00812 {
00813     CV_DbgAssert(dims >= 2);
00814     CV_DbgAssert(data);
00815     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00816     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00817     return data + i0 * step.p[0] + i1 * step.p[1];
00818 }
00819 
00820 template<typename _Tp> inline
00821 _Tp* Mat::ptr(int i0, int i1)
00822 {
00823     CV_DbgAssert(dims >= 2);
00824     CV_DbgAssert(data);
00825     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00826     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00827     return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
00828 }
00829 
00830 template<typename _Tp> inline
00831 const _Tp* Mat::ptr(int i0, int i1) const
00832 {
00833     CV_DbgAssert(dims >= 2);
00834     CV_DbgAssert(data);
00835     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00836     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00837     return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
00838 }
00839 
00840 inline
00841 uchar* Mat::ptr(int i0, int i1, int i2)
00842 {
00843     CV_DbgAssert(dims >= 3);
00844     CV_DbgAssert(data);
00845     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00846     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00847     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00848     return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
00849 }
00850 
00851 inline
00852 const uchar* Mat::ptr(int i0, int i1, int i2) const
00853 {
00854     CV_DbgAssert(dims >= 3);
00855     CV_DbgAssert(data);
00856     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00857     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00858     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00859     return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
00860 }
00861 
00862 template<typename _Tp> inline
00863 _Tp* Mat::ptr(int i0, int i1, int i2)
00864 {
00865     CV_DbgAssert(dims >= 3);
00866     CV_DbgAssert(data);
00867     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00868     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00869     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00870     return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
00871 }
00872 
00873 template<typename _Tp> inline
00874 const _Tp* Mat::ptr(int i0, int i1, int i2) const
00875 {
00876     CV_DbgAssert(dims >= 3);
00877     CV_DbgAssert(data);
00878     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00879     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00880     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00881     return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
00882 }
00883 
00884 inline
00885 uchar* Mat::ptr(const int* idx)
00886 {
00887     int i, d = dims;
00888     uchar* p = data;
00889     CV_DbgAssert( d >= 1 && p );
00890     for( i = 0; i < d; i++ )
00891     {
00892         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
00893         p += idx[i] * step.p[i];
00894     }
00895     return p;
00896 }
00897 
00898 inline
00899 const uchar* Mat::ptr(const int* idx) const
00900 {
00901     int i, d = dims;
00902     uchar* p = data;
00903     CV_DbgAssert( d >= 1 && p );
00904     for( i = 0; i < d; i++ )
00905     {
00906         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
00907         p += idx[i] * step.p[i];
00908     }
00909     return p;
00910 }
00911 
00912 template<typename _Tp> inline
00913 _Tp& Mat::at(int i0, int i1)
00914 {
00915     CV_DbgAssert(dims <= 2);
00916     CV_DbgAssert(data);
00917     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00918     CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00919     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00920     return ((_Tp*)(data + step.p[0] * i0))[i1];
00921 }
00922 
00923 template<typename _Tp> inline
00924 const _Tp& Mat::at(int i0, int i1) const
00925 {
00926     CV_DbgAssert(dims <= 2);
00927     CV_DbgAssert(data);
00928     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00929     CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00930     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00931     return ((const _Tp*)(data + step.p[0] * i0))[i1];
00932 }
00933 
00934 template<typename _Tp> inline
00935 _Tp& Mat::at(Point pt)
00936 {
00937     CV_DbgAssert(dims <= 2);
00938     CV_DbgAssert(data);
00939     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
00940     CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00941     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00942     return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
00943 }
00944 
00945 template<typename _Tp> inline
00946 const _Tp& Mat::at(Point pt) const
00947 {
00948     CV_DbgAssert(dims <= 2);
00949     CV_DbgAssert(data);
00950     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
00951     CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00952     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00953     return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
00954 }
00955 
00956 template<typename _Tp> inline
00957 _Tp& Mat::at(int i0)
00958 {
00959     CV_DbgAssert(dims <= 2);
00960     CV_DbgAssert(data);
00961     CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1]));
00962     CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type));
00963     if( isContinuous() || size.p[0] == 1 )
00964         return ((_Tp*)data)[i0];
00965     if( size.p[1] == 1 )
00966         return *(_Tp*)(data + step.p[0] * i0);
00967     int i = i0 / cols, j = i0 - i * cols;
00968     return ((_Tp*)(data + step.p[0] * i))[j];
00969 }
00970 
00971 template<typename _Tp> inline
00972 const _Tp& Mat::at(int i0) const
00973 {
00974     CV_DbgAssert(dims <= 2);
00975     CV_DbgAssert(data);
00976     CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1]));
00977     CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type));
00978     if( isContinuous() || size.p[0] == 1 )
00979         return ((const _Tp*)data)[i0];
00980     if( size.p[1] == 1 )
00981         return *(const _Tp*)(data + step.p[0] * i0);
00982     int i = i0 / cols, j = i0 - i * cols;
00983     return ((const _Tp*)(data + step.p[0] * i))[j];
00984 }
00985 
00986 template<typename _Tp> inline
00987 _Tp& Mat::at(int i0, int i1, int i2)
00988 {
00989     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00990     return *(_Tp*)ptr(i0, i1, i2);
00991 }
00992 
00993 template<typename _Tp> inline
00994 const _Tp& Mat::at(int i0, int i1, int i2) const
00995 {
00996     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00997     return *(const _Tp*)ptr(i0, i1, i2);
00998 }
00999 
01000 template<typename _Tp> inline
01001 _Tp& Mat::at(const int* idx)
01002 {
01003     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01004     return *(_Tp*)ptr(idx);
01005 }
01006 
01007 template<typename _Tp> inline
01008 const _Tp& Mat::at(const int* idx) const
01009 {
01010     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01011     return *(const _Tp*)ptr(idx);
01012 }
01013 
01014 template<typename _Tp, int n> inline
01015 _Tp& Mat::at(const Vec<int, n>& idx)
01016 {
01017     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01018     return *(_Tp*)ptr(idx.val);
01019 }
01020 
01021 template<typename _Tp, int n> inline
01022 const _Tp& Mat::at(const Vec<int, n>& idx) const
01023 {
01024     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01025     return *(const _Tp*)ptr(idx.val);
01026 }
01027 
01028 template<typename _Tp> inline
01029 MatConstIterator_<_Tp> Mat::begin() const
01030 {
01031     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01032     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
01033 }
01034 
01035 template<typename _Tp> inline
01036 MatConstIterator_<_Tp> Mat::end() const
01037 {
01038     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01039     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
01040     it += total();
01041     return it;
01042 }
01043 
01044 template<typename _Tp> inline
01045 MatIterator_<_Tp> Mat::begin()
01046 {
01047     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01048     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
01049 }
01050 
01051 template<typename _Tp> inline
01052 MatIterator_<_Tp> Mat::end()
01053 {
01054     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01055     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
01056     it += total();
01057     return it;
01058 }
01059 
01060 template<typename _Tp, typename Functor> inline
01061 void Mat::forEach(const Functor& operation) {
01062     this->forEach_impl<_Tp>(operation);
01063 }
01064 
01065 template<typename _Tp, typename Functor> inline
01066 void Mat::forEach(const Functor& operation) const {
01067     // call as not const
01068     (const_cast<Mat*>(this))->forEach<const _Tp>(operation);
01069 }
01070 
01071 template<typename _Tp> inline
01072 Mat::operator std::vector<_Tp>() const
01073 {
01074     std::vector<_Tp> v;
01075     copyTo(v);
01076     return v;
01077 }
01078 
01079 template<typename _Tp, int n> inline
01080 Mat::operator Vec<_Tp, n>() const
01081 {
01082     CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
01083                rows + cols - 1 == n && channels() == 1 );
01084 
01085     if( isContinuous() && type() == DataType<_Tp>::type )
01086         return Vec<_Tp, n>((_Tp*)data);
01087     Vec<_Tp, n> v;
01088     Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
01089     convertTo(tmp, tmp.type());
01090     return v;
01091 }
01092 
01093 template<typename _Tp, int m, int n> inline
01094 Mat::operator Matx<_Tp, m, n>() const
01095 {
01096     CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
01097 
01098     if( isContinuous() && type() == DataType<_Tp>::type )
01099         return Matx<_Tp, m, n>((_Tp*)data);
01100     Matx<_Tp, m, n> mtx;
01101     Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
01102     convertTo(tmp, tmp.type());
01103     return mtx;
01104 }
01105 
01106 template<typename _Tp> inline
01107 void Mat::push_back(const _Tp& elem)
01108 {
01109     if( !data )
01110     {
01111         *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
01112         return;
01113     }
01114     CV_Assert(DataType<_Tp>::type == type() && cols == 1
01115               /* && dims == 2 (cols == 1 implies dims == 2) */);
01116     const uchar* tmp = dataend + step[0];
01117     if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
01118     {
01119         *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
01120         dataend = tmp;
01121     }
01122     else
01123         push_back_(&elem);
01124 }
01125 
01126 template<typename _Tp> inline
01127 void Mat::push_back(const Mat_<_Tp>& m)
01128 {
01129     push_back((const Mat&)m);
01130 }
01131 
01132 template<> inline
01133 void Mat::push_back(const MatExpr& expr)
01134 {
01135     push_back(static_cast<Mat>(expr));
01136 }
01137 
01138 #ifdef CV_CXX_MOVE_SEMANTICS
01139 
01140 inline
01141 Mat::Mat(Mat&& m)
01142     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
01143       datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
01144       u(m.u), size(&rows)
01145 {
01146     if (m.dims <= 2)  // move new step/size info
01147     {
01148         step[0] = m.step[0];
01149         step[1] = m.step[1];
01150     }
01151     else
01152     {
01153         CV_DbgAssert(m.step.p != m.step.buf);
01154         step.p = m.step.p;
01155         size.p = m.size.p;
01156         m.step.p = m.step.buf;
01157         m.size.p = &m.rows;
01158     }
01159     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
01160     m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
01161     m.allocator = NULL;
01162     m.u = NULL;
01163 }
01164 
01165 inline
01166 Mat& Mat::operator = (Mat&& m)
01167 {
01168     release();
01169     flags  = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; data = m.data;
01170     datastart = m.datastart; dataend = m.dataend; datalimit = m.datalimit; allocator = m.allocator;
01171     u = m.u;
01172     if (step.p != step.buf) // release self step/size
01173     {
01174         fastFree(step.p);
01175         step.p = step.buf;
01176         size.p = &rows;
01177     }
01178     if (m.dims <= 2) // move new step/size info
01179     {
01180         step[0] = m.step[0];
01181         step[1] = m.step[1];
01182     }
01183     else
01184     {
01185         CV_DbgAssert(m.step.p != m.step.buf);
01186         step.p = m.step.p;
01187         size.p = m.size.p;
01188         m.step.p = m.step.buf;
01189         m.size.p = &m.rows;
01190     }
01191     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
01192     m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
01193     m.allocator = NULL;
01194     m.u = NULL;
01195     return *this;
01196 }
01197 
01198 #endif
01199 
01200 
01201 ///////////////////////////// MatSize ////////////////////////////
01202 
01203 inline
01204 MatSize::MatSize(int* _p)
01205     : p(_p) {}
01206 
01207 inline
01208 Size MatSize::operator()() const
01209 {
01210     CV_DbgAssert(p[-1] <= 2);
01211     return Size(p[1], p[0]);
01212 }
01213 
01214 inline
01215 const int& MatSize::operator[](int i) const
01216 {
01217     return p[i];
01218 }
01219 
01220 inline
01221 int& MatSize::operator[](int i)
01222 {
01223     return p[i];
01224 }
01225 
01226 inline
01227 MatSize::operator const int*() const
01228 {
01229     return p;
01230 }
01231 
01232 inline
01233 bool MatSize::operator == (const MatSize& sz) const
01234 {
01235     int d = p[-1];
01236     int dsz = sz.p[-1];
01237     if( d != dsz )
01238         return false;
01239     if( d == 2 )
01240         return p[0] == sz.p[0] && p[1] == sz.p[1];
01241 
01242     for( int i = 0; i < d; i++ )
01243         if( p[i] != sz.p[i] )
01244             return false;
01245     return true;
01246 }
01247 
01248 inline
01249 bool MatSize::operator != (const MatSize& sz) const
01250 {
01251     return !(*this == sz);
01252 }
01253 
01254 
01255 
01256 ///////////////////////////// MatStep ////////////////////////////
01257 
01258 inline
01259 MatStep::MatStep()
01260 {
01261     p = buf; p[0] = p[1] = 0;
01262 }
01263 
01264 inline
01265 MatStep::MatStep(size_t s)
01266 {
01267     p = buf; p[0] = s; p[1] = 0;
01268 }
01269 
01270 inline
01271 const size_t& MatStep::operator[](int i) const
01272 {
01273     return p[i];
01274 }
01275 
01276 inline
01277 size_t& MatStep::operator[](int i)
01278 {
01279     return p[i];
01280 }
01281 
01282 inline MatStep::operator size_t() const
01283 {
01284     CV_DbgAssert( p == buf );
01285     return buf[0];
01286 }
01287 
01288 inline MatStep& MatStep::operator = (size_t s)
01289 {
01290     CV_DbgAssert( p == buf );
01291     buf[0] = s;
01292     return *this;
01293 }
01294 
01295 
01296 
01297 ////////////////////////////// Mat_<_Tp> ////////////////////////////
01298 
01299 template<typename _Tp> inline
01300 Mat_<_Tp>::Mat_()
01301     : Mat()
01302 {
01303     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01304 }
01305 
01306 template<typename _Tp> inline
01307 Mat_<_Tp>::Mat_(int _rows, int _cols)
01308     : Mat(_rows, _cols, DataType<_Tp>::type)
01309 {
01310 }
01311 
01312 template<typename _Tp> inline
01313 Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
01314     : Mat(_rows, _cols, DataType<_Tp>::type)
01315 {
01316     *this = value;
01317 }
01318 
01319 template<typename _Tp> inline
01320 Mat_<_Tp>::Mat_(Size _sz)
01321     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
01322 {}
01323 
01324 template<typename _Tp> inline
01325 Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
01326     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
01327 {
01328     *this = value;
01329 }
01330 
01331 template<typename _Tp> inline
01332 Mat_<_Tp>::Mat_(int _dims, const int* _sz)
01333     : Mat(_dims, _sz, DataType<_Tp>::type)
01334 {}
01335 
01336 template<typename _Tp> inline
01337 Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
01338     : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s))
01339 {}
01340 
01341 template<typename _Tp> inline
01342 Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
01343     : Mat(m, ranges)
01344 {}
01345 
01346 template<typename _Tp> inline
01347 Mat_<_Tp>::Mat_(const Mat& m)
01348     : Mat()
01349 {
01350     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01351     *this = m;
01352 }
01353 
01354 template<typename _Tp> inline
01355 Mat_<_Tp>::Mat_(const Mat_& m)
01356     : Mat(m)
01357 {}
01358 
01359 template<typename _Tp> inline
01360 Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
01361     : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps)
01362 {}
01363 
01364 template<typename _Tp> inline
01365 Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
01366     : Mat(m, _rowRange, _colRange)
01367 {}
01368 
01369 template<typename _Tp> inline
01370 Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
01371     : Mat(m, roi)
01372 {}
01373 
01374 template<typename _Tp> template<int n> inline
01375 Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
01376     : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
01377 {
01378     CV_Assert(n%DataType<_Tp>::channels == 0);
01379     if( copyData )
01380         *this = clone();
01381 }
01382 
01383 template<typename _Tp> template<int m, int n> inline
01384 Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& M, bool copyData)
01385     : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
01386 {
01387     CV_Assert(n % DataType<_Tp>::channels == 0);
01388     if( copyData )
01389         *this = clone();
01390 }
01391 
01392 template<typename _Tp> inline
01393 Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
01394     : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
01395 {
01396     CV_Assert(2 % DataType<_Tp>::channels == 0);
01397     if( copyData )
01398         *this = clone();
01399 }
01400 
01401 template<typename _Tp> inline
01402 Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
01403     : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
01404 {
01405     CV_Assert(3 % DataType<_Tp>::channels == 0);
01406     if( copyData )
01407         *this = clone();
01408 }
01409 
01410 template<typename _Tp> inline
01411 Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
01412     : Mat(commaInitializer)
01413 {}
01414 
01415 template<typename _Tp> inline
01416 Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
01417     : Mat(vec, copyData)
01418 {}
01419 
01420 template<typename _Tp> inline
01421 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
01422 {
01423     if( DataType<_Tp>::type == m.type() )
01424     {
01425         Mat::operator = (m);
01426         return *this;
01427     }
01428     if( DataType<_Tp>::depth == m.depth() )
01429     {
01430         return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
01431     }
01432     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
01433     m.convertTo(*this, type());
01434     return *this;
01435 }
01436 
01437 template<typename _Tp> inline
01438 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
01439 {
01440     Mat::operator=(m);
01441     return *this;
01442 }
01443 
01444 template<typename _Tp> inline
01445 Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
01446 {
01447     typedef typename DataType<_Tp>::vec_type VT;
01448     Mat::operator=(Scalar((const VT&)s));
01449     return *this;
01450 }
01451 
01452 template<typename _Tp> inline
01453 void Mat_<_Tp>::create(int _rows, int _cols)
01454 {
01455     Mat::create(_rows, _cols, DataType<_Tp>::type);
01456 }
01457 
01458 template<typename _Tp> inline
01459 void Mat_<_Tp>::create(Size _sz)
01460 {
01461     Mat::create(_sz, DataType<_Tp>::type);
01462 }
01463 
01464 template<typename _Tp> inline
01465 void Mat_<_Tp>::create(int _dims, const int* _sz)
01466 {
01467     Mat::create(_dims, _sz, DataType<_Tp>::type);
01468 }
01469 
01470 template<typename _Tp> inline
01471 Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
01472 {
01473     return Mat_<_Tp>(Mat::cross(m));
01474 }
01475 
01476 template<typename _Tp> template<typename T2> inline
01477 Mat_<_Tp>::operator Mat_<T2>() const
01478 {
01479     return Mat_<T2>(*this);
01480 }
01481 
01482 template<typename _Tp> inline
01483 Mat_<_Tp> Mat_<_Tp>::row(int y) const
01484 {
01485     return Mat_(*this, Range(y, y+1), Range::all());
01486 }
01487 
01488 template<typename _Tp> inline
01489 Mat_<_Tp> Mat_<_Tp>::col(int x) const
01490 {
01491     return Mat_(*this, Range::all(), Range(x, x+1));
01492 }
01493 
01494 template<typename _Tp> inline
01495 Mat_<_Tp> Mat_<_Tp>::diag(int d) const
01496 {
01497     return Mat_(Mat::diag(d));
01498 }
01499 
01500 template<typename _Tp> inline
01501 Mat_<_Tp> Mat_<_Tp>::clone() const
01502 {
01503     return Mat_(Mat::clone());
01504 }
01505 
01506 template<typename _Tp> inline
01507 size_t Mat_<_Tp>::elemSize() const
01508 {
01509     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
01510     return sizeof(_Tp);
01511 }
01512 
01513 template<typename _Tp> inline
01514 size_t Mat_<_Tp>::elemSize1() const
01515 {
01516     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels );
01517     return sizeof(_Tp) / DataType<_Tp>::channels;
01518 }
01519 
01520 template<typename _Tp> inline
01521 int Mat_<_Tp>::type() const
01522 {
01523     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
01524     return DataType<_Tp>::type;
01525 }
01526 
01527 template<typename _Tp> inline
01528 int Mat_<_Tp>::depth() const
01529 {
01530     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
01531     return DataType<_Tp>::depth;
01532 }
01533 
01534 template<typename _Tp> inline
01535 int Mat_<_Tp>::channels() const
01536 {
01537     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
01538     return DataType<_Tp>::channels;
01539 }
01540 
01541 template<typename _Tp> inline
01542 size_t Mat_<_Tp>::stepT(int i) const
01543 {
01544     return step.p[i] / elemSize();
01545 }
01546 
01547 template<typename _Tp> inline
01548 size_t Mat_<_Tp>::step1(int i) const
01549 {
01550     return step.p[i] / elemSize1();
01551 }
01552 
01553 template<typename _Tp> inline
01554 Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
01555 {
01556     return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));
01557 }
01558 
01559 template<typename _Tp> inline
01560 Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
01561 {
01562     return Mat_<_Tp>(*this, _rowRange, _colRange);
01563 }
01564 
01565 template<typename _Tp> inline
01566 Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
01567 {
01568     return Mat_<_Tp>(*this, roi);
01569 }
01570 
01571 template<typename _Tp> inline
01572 Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
01573 {
01574     return Mat_<_Tp>(*this, ranges);
01575 }
01576 
01577 template<typename _Tp> inline
01578 _Tp* Mat_<_Tp>::operator [](int y)
01579 {
01580     CV_DbgAssert( 0 <= y && y < rows );
01581     return (_Tp*)(data + y*step.p[0]);
01582 }
01583 
01584 template<typename _Tp> inline
01585 const _Tp* Mat_<_Tp>::operator [](int y) const
01586 {
01587     CV_DbgAssert( 0 <= y && y < rows );
01588     return (const _Tp*)(data + y*step.p[0]);
01589 }
01590 
01591 template<typename _Tp> inline
01592 _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
01593 {
01594     CV_DbgAssert(dims <= 2);
01595     CV_DbgAssert(data);
01596     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
01597     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
01598     CV_DbgAssert(type() == DataType<_Tp>::type);
01599     return ((_Tp*)(data + step.p[0] * i0))[i1];
01600 }
01601 
01602 template<typename _Tp> inline
01603 const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
01604 {
01605     CV_DbgAssert(dims <= 2);
01606     CV_DbgAssert(data);
01607     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
01608     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
01609     CV_DbgAssert(type() == DataType<_Tp>::type);
01610     return ((const _Tp*)(data + step.p[0] * i0))[i1];
01611 }
01612 
01613 template<typename _Tp> inline
01614 _Tp& Mat_<_Tp>::operator ()(Point pt)
01615 {
01616     CV_DbgAssert(dims <= 2);
01617     CV_DbgAssert(data);
01618     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
01619     CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]);
01620     CV_DbgAssert(type() == DataType<_Tp>::type);
01621     return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
01622 }
01623 
01624 template<typename _Tp> inline
01625 const _Tp& Mat_<_Tp>::operator ()(Point pt) const
01626 {
01627     CV_DbgAssert(dims <= 2);
01628     CV_DbgAssert(data);
01629     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
01630     CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]);
01631     CV_DbgAssert(type() == DataType<_Tp>::type);
01632     return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
01633 }
01634 
01635 template<typename _Tp> inline
01636 _Tp& Mat_<_Tp>::operator ()(const int* idx)
01637 {
01638     return Mat::at<_Tp>(idx);
01639 }
01640 
01641 template<typename _Tp> inline
01642 const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
01643 {
01644     return Mat::at<_Tp>(idx);
01645 }
01646 
01647 template<typename _Tp> template<int n> inline
01648 _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
01649 {
01650     return Mat::at<_Tp>(idx);
01651 }
01652 
01653 template<typename _Tp> template<int n> inline
01654 const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
01655 {
01656     return Mat::at<_Tp>(idx);
01657 }
01658 
01659 template<typename _Tp> inline
01660 _Tp& Mat_<_Tp>::operator ()(int i0)
01661 {
01662     return this->at<_Tp>(i0);
01663 }
01664 
01665 template<typename _Tp> inline
01666 const _Tp& Mat_<_Tp>::operator ()(int i0) const
01667 {
01668     return this->at<_Tp>(i0);
01669 }
01670 
01671 template<typename _Tp> inline
01672 _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
01673 {
01674     return this->at<_Tp>(i0, i1, i2);
01675 }
01676 
01677 template<typename _Tp> inline
01678 const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
01679 {
01680     return this->at<_Tp>(i0, i1, i2);
01681 }
01682 
01683 template<typename _Tp> inline
01684 Mat_<_Tp>::operator std::vector<_Tp>() const
01685 {
01686     std::vector<_Tp> v;
01687     copyTo(v);
01688     return v;
01689 }
01690 
01691 template<typename _Tp> template<int n> inline
01692 Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
01693 {
01694     CV_Assert(n % DataType<_Tp>::channels == 0);
01695 
01696 #if defined _MSC_VER
01697     const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround)
01698     return pMat->operator Vec<typename DataType<_Tp>::channel_type, n>();
01699 #else
01700     return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
01701 #endif
01702 }
01703 
01704 template<typename _Tp> template<int m, int n> inline
01705 Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
01706 {
01707     CV_Assert(n % DataType<_Tp>::channels == 0);
01708 
01709 #if defined _MSC_VER
01710     const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround)
01711     Matx<typename DataType<_Tp>::channel_type, m, n> res = pMat->operator Matx<typename DataType<_Tp>::channel_type, m, n>();
01712     return res;
01713 #else
01714     Matx<typename DataType<_Tp>::channel_type, m, n> res = this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
01715     return res;
01716 #endif
01717 }
01718 
01719 template<typename _Tp> inline
01720 MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
01721 {
01722     return Mat::begin<_Tp>();
01723 }
01724 
01725 template<typename _Tp> inline
01726 MatConstIterator_<_Tp> Mat_<_Tp>::end() const
01727 {
01728     return Mat::end<_Tp>();
01729 }
01730 
01731 template<typename _Tp> inline
01732 MatIterator_<_Tp> Mat_<_Tp>::begin()
01733 {
01734     return Mat::begin<_Tp>();
01735 }
01736 
01737 template<typename _Tp> inline
01738 MatIterator_<_Tp> Mat_<_Tp>::end()
01739 {
01740     return Mat::end<_Tp>();
01741 }
01742 
01743 template<typename _Tp> template<typename Functor> inline
01744 void Mat_<_Tp>::forEach(const Functor& operation) {
01745     Mat::forEach<_Tp, Functor>(operation);
01746 }
01747 
01748 template<typename _Tp> template<typename Functor> inline
01749 void Mat_<_Tp>::forEach(const Functor& operation) const {
01750     Mat::forEach<_Tp, Functor>(operation);
01751 }
01752 
01753 #ifdef CV_CXX_MOVE_SEMANTICS
01754 
01755 template<typename _Tp> inline
01756 Mat_<_Tp>::Mat_(Mat_&& m)
01757     : Mat(m)
01758 {
01759 }
01760 
01761 template<typename _Tp> inline
01762 Mat_<_Tp>& Mat_<_Tp>::operator = (Mat_&& m)
01763 {
01764     Mat::operator = (m);
01765     return *this;
01766 }
01767 
01768 template<typename _Tp> inline
01769 Mat_<_Tp>::Mat_(Mat&& m)
01770     : Mat()
01771 {
01772     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01773     *this = m;
01774 }
01775 
01776 template<typename _Tp> inline
01777 Mat_<_Tp>& Mat_<_Tp>::operator = (Mat&& m)
01778 {
01779     if( DataType<_Tp>::type == m.type() )
01780     {
01781         Mat::operator = ((Mat&&)m);
01782         return *this;
01783     }
01784     if( DataType<_Tp>::depth == m.depth() )
01785     {
01786         Mat::operator = ((Mat&&)m.reshape(DataType<_Tp>::channels, m.dims, 0));
01787         return *this;
01788     }
01789     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
01790     m.convertTo(*this, type());
01791     return *this;
01792 }
01793 
01794 template<typename _Tp> inline
01795 Mat_<_Tp>::Mat_(MatExpr&& e)
01796     : Mat()
01797 {
01798     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01799     *this = Mat(e);
01800 }
01801 
01802 #endif
01803 
01804 ///////////////////////////// SparseMat /////////////////////////////
01805 
01806 inline
01807 SparseMat::SparseMat()
01808     : flags(MAGIC_VAL), hdr(0)
01809 {}
01810 
01811 inline
01812 SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
01813     : flags(MAGIC_VAL), hdr(0)
01814 {
01815     create(_dims, _sizes, _type);
01816 }
01817 
01818 inline
01819 SparseMat::SparseMat(const SparseMat& m)
01820     : flags(m.flags), hdr(m.hdr)
01821 {
01822     addref();
01823 }
01824 
01825 inline
01826 SparseMat::~SparseMat()
01827 {
01828     release();
01829 }
01830 
01831 inline
01832 SparseMat& SparseMat::operator = (const SparseMat& m)
01833 {
01834     if( this != &m )
01835     {
01836         if( m.hdr )
01837             CV_XADD(&m.hdr->refcount, 1);
01838         release();
01839         flags = m.flags;
01840         hdr = m.hdr;
01841     }
01842     return *this;
01843 }
01844 
01845 inline
01846 SparseMat& SparseMat::operator = (const Mat& m)
01847 {
01848     return (*this = SparseMat(m));
01849 }
01850 
01851 inline
01852 SparseMat SparseMat::clone() const
01853 {
01854     SparseMat temp;
01855     this->copyTo(temp);
01856     return temp;
01857 }
01858 
01859 inline
01860 void SparseMat::assignTo( SparseMat& m, int _type ) const
01861 {
01862     if( _type < 0 )
01863         m = *this;
01864     else
01865         convertTo(m, _type);
01866 }
01867 
01868 inline
01869 void SparseMat::addref()
01870 {
01871     if( hdr )
01872         CV_XADD(&hdr->refcount, 1);
01873 }
01874 
01875 inline
01876 void SparseMat::release()
01877 {
01878     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
01879         delete hdr;
01880     hdr = 0;
01881 }
01882 
01883 inline
01884 size_t SparseMat::elemSize() const
01885 {
01886     return CV_ELEM_SIZE(flags);
01887 }
01888 
01889 inline
01890 size_t SparseMat::elemSize1() const
01891 {
01892     return CV_ELEM_SIZE1(flags);
01893 }
01894 
01895 inline
01896 int SparseMat::type() const
01897 {
01898     return CV_MAT_TYPE(flags);
01899 }
01900 
01901 inline
01902 int SparseMat::depth() const
01903 {
01904     return CV_MAT_DEPTH(flags);
01905 }
01906 
01907 inline
01908 int SparseMat::channels() const
01909 {
01910     return CV_MAT_CN(flags);
01911 }
01912 
01913 inline
01914 const int* SparseMat::size() const
01915 {
01916     return hdr ? hdr->size : 0;
01917 }
01918 
01919 inline
01920 int SparseMat::size(int i) const
01921 {
01922     if( hdr )
01923     {
01924         CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
01925         return hdr->size[i];
01926     }
01927     return 0;
01928 }
01929 
01930 inline
01931 int SparseMat::dims() const
01932 {
01933     return hdr ? hdr->dims : 0;
01934 }
01935 
01936 inline
01937 size_t SparseMat::nzcount() const
01938 {
01939     return hdr ? hdr->nodeCount : 0;
01940 }
01941 
01942 inline
01943 size_t SparseMat::hash(int i0) const
01944 {
01945     return (size_t)i0;
01946 }
01947 
01948 inline
01949 size_t SparseMat::hash(int i0, int i1) const
01950 {
01951     return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
01952 }
01953 
01954 inline
01955 size_t SparseMat::hash(int i0, int i1, int i2) const
01956 {
01957     return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
01958 }
01959 
01960 inline
01961 size_t SparseMat::hash(const int* idx) const
01962 {
01963     size_t h = (unsigned)idx[0];
01964     if( !hdr )
01965         return 0;
01966     int d = hdr->dims;
01967     for(int i = 1; i < d; i++ )
01968         h = h * HASH_SCALE + (unsigned)idx[i];
01969     return h;
01970 }
01971 
01972 template<typename _Tp> inline
01973 _Tp& SparseMat::ref(int i0, size_t* hashval)
01974 {
01975     return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval);
01976 }
01977 
01978 template<typename _Tp> inline
01979 _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
01980 {
01981     return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval);
01982 }
01983 
01984 template<typename _Tp> inline
01985 _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
01986 {
01987     return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval);
01988 }
01989 
01990 template<typename _Tp> inline
01991 _Tp& SparseMat::ref(const int* idx, size_t* hashval)
01992 {
01993     return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval);
01994 }
01995 
01996 template<typename _Tp> inline
01997 _Tp SparseMat::value(int i0, size_t* hashval) const
01998 {
01999     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
02000     return p ? *p : _Tp();
02001 }
02002 
02003 template<typename _Tp> inline
02004 _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
02005 {
02006     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
02007     return p ? *p : _Tp();
02008 }
02009 
02010 template<typename _Tp> inline
02011 _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
02012 {
02013     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
02014     return p ? *p : _Tp();
02015 }
02016 
02017 template<typename _Tp> inline
02018 _Tp SparseMat::value(const int* idx, size_t* hashval) const
02019 {
02020     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
02021     return p ? *p : _Tp();
02022 }
02023 
02024 template<typename _Tp> inline
02025 const _Tp* SparseMat::find(int i0, size_t* hashval) const
02026 {
02027     return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
02028 }
02029 
02030 template<typename _Tp> inline
02031 const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
02032 {
02033     return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
02034 }
02035 
02036 template<typename _Tp> inline
02037 const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
02038 {
02039     return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
02040 }
02041 
02042 template<typename _Tp> inline
02043 const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
02044 {
02045     return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
02046 }
02047 
02048 template<typename _Tp> inline
02049 _Tp& SparseMat::value(Node* n)
02050 {
02051     return *(_Tp*)((uchar*)n + hdr->valueOffset);
02052 }
02053 
02054 template<typename _Tp> inline
02055 const _Tp& SparseMat::value(const Node* n) const
02056 {
02057     return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
02058 }
02059 
02060 inline
02061 SparseMat::Node* SparseMat::node(size_t nidx)
02062 {
02063     return (Node*)(void*)&hdr->pool[nidx];
02064 }
02065 
02066 inline
02067 const SparseMat::Node* SparseMat::node(size_t nidx) const
02068 {
02069     return (const Node*)(const void*)&hdr->pool[nidx];
02070 }
02071 
02072 inline
02073 SparseMatIterator SparseMat::begin()
02074 {
02075     return SparseMatIterator(this);
02076 }
02077 
02078 inline
02079 SparseMatConstIterator SparseMat::begin() const
02080 {
02081     return SparseMatConstIterator(this);
02082 }
02083 
02084 inline
02085 SparseMatIterator SparseMat::end()
02086 {
02087     SparseMatIterator it(this);
02088     it.seekEnd();
02089     return it;
02090 }
02091 
02092 inline
02093 SparseMatConstIterator SparseMat::end() const
02094 {
02095     SparseMatConstIterator it(this);
02096     it.seekEnd();
02097     return it;
02098 }
02099 
02100 template<typename _Tp> inline
02101 SparseMatIterator_<_Tp> SparseMat::begin()
02102 {
02103     return SparseMatIterator_<_Tp>(this);
02104 }
02105 
02106 template<typename _Tp> inline
02107 SparseMatConstIterator_<_Tp> SparseMat::begin() const
02108 {
02109     return SparseMatConstIterator_<_Tp>(this);
02110 }
02111 
02112 template<typename _Tp> inline
02113 SparseMatIterator_<_Tp> SparseMat::end()
02114 {
02115     SparseMatIterator_<_Tp> it(this);
02116     it.seekEnd();
02117     return it;
02118 }
02119 
02120 template<typename _Tp> inline
02121 SparseMatConstIterator_<_Tp> SparseMat::end() const
02122 {
02123     SparseMatConstIterator_<_Tp> it(this);
02124     it.seekEnd();
02125     return it;
02126 }
02127 
02128 
02129 
02130 ///////////////////////////// SparseMat_ ////////////////////////////
02131 
02132 template<typename _Tp> inline
02133 SparseMat_<_Tp>::SparseMat_()
02134 {
02135     flags = MAGIC_VAL | DataType<_Tp>::type;
02136 }
02137 
02138 template<typename _Tp> inline
02139 SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
02140     : SparseMat(_dims, _sizes, DataType<_Tp>::type)
02141 {}
02142 
02143 template<typename _Tp> inline
02144 SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
02145 {
02146     if( m.type() == DataType<_Tp>::type )
02147         *this = (const SparseMat_<_Tp>&)m;
02148     else
02149         m.convertTo(*this, DataType<_Tp>::type);
02150 }
02151 
02152 template<typename _Tp> inline
02153 SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
02154 {
02155     this->flags = m.flags;
02156     this->hdr = m.hdr;
02157     if( this->hdr )
02158         CV_XADD(&this->hdr->refcount, 1);
02159 }
02160 
02161 template<typename _Tp> inline
02162 SparseMat_<_Tp>::SparseMat_(const Mat& m)
02163 {
02164     SparseMat sm(m);
02165     *this = sm;
02166 }
02167 
02168 template<typename _Tp> inline
02169 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
02170 {
02171     if( this != &m )
02172     {
02173         if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
02174         release();
02175         flags = m.flags;
02176         hdr = m.hdr;
02177     }
02178     return *this;
02179 }
02180 
02181 template<typename _Tp> inline
02182 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m)
02183 {
02184     if( m.type() == DataType<_Tp>::type )
02185         return (*this = (const SparseMat_<_Tp>&)m);
02186     m.convertTo(*this, DataType<_Tp>::type);
02187     return *this;
02188 }
02189 
02190 template<typename _Tp> inline
02191 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
02192 {
02193     return (*this = SparseMat(m));
02194 }
02195 
02196 template<typename _Tp> inline
02197 SparseMat_<_Tp> SparseMat_<_Tp>::clone() const
02198 {
02199     SparseMat_<_Tp> m;
02200     this->copyTo(m);
02201     return m;
02202 }
02203 
02204 template<typename _Tp> inline
02205 void SparseMat_<_Tp>::create(int _dims, const int* _sizes)
02206 {
02207     SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
02208 }
02209 
02210 template<typename _Tp> inline
02211 int SparseMat_<_Tp>::type() const
02212 {
02213     return DataType<_Tp>::type;
02214 }
02215 
02216 template<typename _Tp> inline
02217 int SparseMat_<_Tp>::depth() const
02218 {
02219     return DataType<_Tp>::depth;
02220 }
02221 
02222 template<typename _Tp> inline
02223 int SparseMat_<_Tp>::channels() const
02224 {
02225     return DataType<_Tp>::channels;
02226 }
02227 
02228 template<typename _Tp> inline
02229 _Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval)
02230 {
02231     return SparseMat::ref<_Tp>(i0, hashval);
02232 }
02233 
02234 template<typename _Tp> inline
02235 _Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
02236 {
02237     return SparseMat::value<_Tp>(i0, hashval);
02238 }
02239 
02240 template<typename _Tp> inline
02241 _Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
02242 {
02243     return SparseMat::ref<_Tp>(i0, i1, hashval);
02244 }
02245 
02246 template<typename _Tp> inline
02247 _Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
02248 {
02249     return SparseMat::value<_Tp>(i0, i1, hashval);
02250 }
02251 
02252 template<typename _Tp> inline
02253 _Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
02254 {
02255     return SparseMat::ref<_Tp>(i0, i1, i2, hashval);
02256 }
02257 
02258 template<typename _Tp> inline
02259 _Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
02260 {
02261     return SparseMat::value<_Tp>(i0, i1, i2, hashval);
02262 }
02263 
02264 template<typename _Tp> inline
02265 _Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
02266 {
02267     return SparseMat::ref<_Tp>(idx, hashval);
02268 }
02269 
02270 template<typename _Tp> inline
02271 _Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
02272 {
02273     return SparseMat::value<_Tp>(idx, hashval);
02274 }
02275 
02276 template<typename _Tp> inline
02277 SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
02278 {
02279     return SparseMatIterator_<_Tp>(this);
02280 }
02281 
02282 template<typename _Tp> inline
02283 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
02284 {
02285     return SparseMatConstIterator_<_Tp>(this);
02286 }
02287 
02288 template<typename _Tp> inline
02289 SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
02290 {
02291     SparseMatIterator_<_Tp> it(this);
02292     it.seekEnd();
02293     return it;
02294 }
02295 
02296 template<typename _Tp> inline
02297 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
02298 {
02299     SparseMatConstIterator_<_Tp> it(this);
02300     it.seekEnd();
02301     return it;
02302 }
02303 
02304 
02305 
02306 ////////////////////////// MatConstIterator /////////////////////////
02307 
02308 inline
02309 MatConstIterator::MatConstIterator()
02310     : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
02311 {}
02312 
02313 inline
02314 MatConstIterator::MatConstIterator(const Mat* _m)
02315     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
02316 {
02317     if( m && m->isContinuous() )
02318     {
02319         sliceStart = m->ptr();
02320         sliceEnd = sliceStart + m->total()*elemSize;
02321     }
02322     seek((const int*)0);
02323 }
02324 
02325 inline
02326 MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
02327     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
02328 {
02329     CV_Assert(m && m->dims <= 2);
02330     if( m->isContinuous() )
02331     {
02332         sliceStart = m->ptr();
02333         sliceEnd = sliceStart + m->total()*elemSize;
02334     }
02335     int idx[] = {_row, _col};
02336     seek(idx);
02337 }
02338 
02339 inline
02340 MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
02341     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
02342 {
02343     CV_Assert(m && m->dims <= 2);
02344     if( m->isContinuous() )
02345     {
02346         sliceStart = m->ptr();
02347         sliceEnd = sliceStart + m->total()*elemSize;
02348     }
02349     int idx[] = {_pt.y, _pt.x};
02350     seek(idx);
02351 }
02352 
02353 inline
02354 MatConstIterator::MatConstIterator(const MatConstIterator& it)
02355     : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
02356 {}
02357 
02358 inline
02359 MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
02360 {
02361     m = it.m; elemSize = it.elemSize; ptr = it.ptr;
02362     sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
02363     return *this;
02364 }
02365 
02366 inline
02367 const uchar* MatConstIterator::operator *() const
02368 {
02369     return ptr;
02370 }
02371 
02372 inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
02373 {
02374     if( !m || ofs == 0 )
02375         return *this;
02376     ptrdiff_t ofsb = ofs*elemSize;
02377     ptr += ofsb;
02378     if( ptr < sliceStart || sliceEnd <= ptr )
02379     {
02380         ptr -= ofsb;
02381         seek(ofs, true);
02382     }
02383     return *this;
02384 }
02385 
02386 inline
02387 MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
02388 {
02389     return (*this += -ofs);
02390 }
02391 
02392 inline
02393 MatConstIterator& MatConstIterator::operator --()
02394 {
02395     if( m && (ptr -= elemSize) < sliceStart )
02396     {
02397         ptr += elemSize;
02398         seek(-1, true);
02399     }
02400     return *this;
02401 }
02402 
02403 inline
02404 MatConstIterator MatConstIterator::operator --(int)
02405 {
02406     MatConstIterator b = *this;
02407     *this += -1;
02408     return b;
02409 }
02410 
02411 inline
02412 MatConstIterator& MatConstIterator::operator ++()
02413 {
02414     if( m && (ptr += elemSize) >= sliceEnd )
02415     {
02416         ptr -= elemSize;
02417         seek(1, true);
02418     }
02419     return *this;
02420 }
02421 
02422 inline MatConstIterator MatConstIterator::operator ++(int)
02423 {
02424     MatConstIterator b = *this;
02425     *this += 1;
02426     return b;
02427 }
02428 
02429 
02430 static inline
02431 bool operator == (const MatConstIterator& a, const MatConstIterator& b)
02432 {
02433     return a.m == b.m && a.ptr == b.ptr;
02434 }
02435 
02436 static inline
02437 bool operator != (const MatConstIterator& a, const MatConstIterator& b)
02438 {
02439     return !(a == b);
02440 }
02441 
02442 static inline
02443 bool operator < (const MatConstIterator& a, const MatConstIterator& b)
02444 {
02445     return a.ptr < b.ptr;
02446 }
02447 
02448 static inline
02449 bool operator > (const MatConstIterator& a, const MatConstIterator& b)
02450 {
02451     return a.ptr > b.ptr;
02452 }
02453 
02454 static inline
02455 bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
02456 {
02457     return a.ptr <= b.ptr;
02458 }
02459 
02460 static inline
02461 bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
02462 {
02463     return a.ptr >= b.ptr;
02464 }
02465 
02466 static inline
02467 ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
02468 {
02469     if( a.m != b.m )
02470         return ((size_t)(-1) >> 1);
02471     if( a.sliceEnd == b.sliceEnd )
02472         return (b.ptr - a.ptr)/b.elemSize;
02473 
02474     return b.lpos() - a.lpos();
02475 }
02476 
02477 static inline
02478 MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
02479 {
02480     MatConstIterator b = a;
02481     return b += ofs;
02482 }
02483 
02484 static inline
02485 MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
02486 {
02487     MatConstIterator b = a;
02488     return b += ofs;
02489 }
02490 
02491 static inline
02492 MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
02493 {
02494     MatConstIterator b = a;
02495     return b += -ofs;
02496 }
02497 
02498 
02499 inline
02500 const uchar* MatConstIterator::operator [](ptrdiff_t i) const
02501 {
02502     return *(*this + i);
02503 }
02504 
02505 
02506 
02507 ///////////////////////// MatConstIterator_ /////////////////////////
02508 
02509 template<typename _Tp> inline
02510 MatConstIterator_<_Tp>::MatConstIterator_()
02511 {}
02512 
02513 template<typename _Tp> inline
02514 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
02515     : MatConstIterator(_m)
02516 {}
02517 
02518 template<typename _Tp> inline
02519 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
02520     : MatConstIterator(_m, _row, _col)
02521 {}
02522 
02523 template<typename _Tp> inline
02524 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
02525     : MatConstIterator(_m, _pt)
02526 {}
02527 
02528 template<typename _Tp> inline
02529 MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
02530     : MatConstIterator(it)
02531 {}
02532 
02533 template<typename _Tp> inline
02534 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
02535 {
02536     MatConstIterator::operator = (it);
02537     return *this;
02538 }
02539 
02540 template<typename _Tp> inline
02541 _Tp MatConstIterator_<_Tp>::operator *() const
02542 {
02543     return *(_Tp*)(this->ptr);
02544 }
02545 
02546 template<typename _Tp> inline
02547 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
02548 {
02549     MatConstIterator::operator += (ofs);
02550     return *this;
02551 }
02552 
02553 template<typename _Tp> inline
02554 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
02555 {
02556     return (*this += -ofs);
02557 }
02558 
02559 template<typename _Tp> inline
02560 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
02561 {
02562     MatConstIterator::operator --();
02563     return *this;
02564 }
02565 
02566 template<typename _Tp> inline
02567 MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
02568 {
02569     MatConstIterator_ b = *this;
02570     MatConstIterator::operator --();
02571     return b;
02572 }
02573 
02574 template<typename _Tp> inline
02575 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
02576 {
02577     MatConstIterator::operator ++();
02578     return *this;
02579 }
02580 
02581 template<typename _Tp> inline
02582 MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
02583 {
02584     MatConstIterator_ b = *this;
02585     MatConstIterator::operator ++();
02586     return b;
02587 }
02588 
02589 
02590 template<typename _Tp> inline
02591 Point MatConstIterator_<_Tp>::pos() const
02592 {
02593     if( !m )
02594         return Point();
02595     CV_DbgAssert( m->dims <= 2 );
02596     if( m->isContinuous() )
02597     {
02598         ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
02599         int y = (int)(ofs / m->cols);
02600         int x = (int)(ofs - (ptrdiff_t)y * m->cols);
02601         return Point(x, y);
02602     }
02603     else
02604     {
02605         ptrdiff_t ofs = (uchar*)ptr - m->data;
02606         int y = (int)(ofs / m->step);
02607         int x = (int)((ofs - y * m->step)/sizeof(_Tp));
02608         return Point(x, y);
02609     }
02610 }
02611 
02612 
02613 template<typename _Tp> static inline
02614 bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
02615 {
02616     return a.m == b.m && a.ptr == b.ptr;
02617 }
02618 
02619 template<typename _Tp> static inline
02620 bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
02621 {
02622     return a.m != b.m || a.ptr != b.ptr;
02623 }
02624 
02625 template<typename _Tp> static inline
02626 MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
02627 {
02628     MatConstIterator t = (const MatConstIterator&)a + ofs;
02629     return (MatConstIterator_<_Tp>&)t;
02630 }
02631 
02632 template<typename _Tp> static inline
02633 MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
02634 {
02635     MatConstIterator t = (const MatConstIterator&)a + ofs;
02636     return (MatConstIterator_<_Tp>&)t;
02637 }
02638 
02639 template<typename _Tp> static inline
02640 MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
02641 {
02642     MatConstIterator t = (const MatConstIterator&)a - ofs;
02643     return (MatConstIterator_<_Tp>&)t;
02644 }
02645 
02646 template<typename _Tp> inline
02647 _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
02648 {
02649     return *(_Tp*)MatConstIterator::operator [](i);
02650 }
02651 
02652 
02653 
02654 //////////////////////////// MatIterator_ ///////////////////////////
02655 
02656 template<typename _Tp> inline
02657 MatIterator_<_Tp>::MatIterator_()
02658     : MatConstIterator_<_Tp>()
02659 {}
02660 
02661 template<typename _Tp> inline
02662 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
02663     : MatConstIterator_<_Tp>(_m)
02664 {}
02665 
02666 template<typename _Tp> inline
02667 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
02668     : MatConstIterator_<_Tp>(_m, _row, _col)
02669 {}
02670 
02671 template<typename _Tp> inline
02672 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt)
02673     : MatConstIterator_<_Tp>(_m, _pt)
02674 {}
02675 
02676 template<typename _Tp> inline
02677 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx)
02678     : MatConstIterator_<_Tp>(_m, _idx)
02679 {}
02680 
02681 template<typename _Tp> inline
02682 MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
02683     : MatConstIterator_<_Tp>(it)
02684 {}
02685 
02686 template<typename _Tp> inline
02687 MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
02688 {
02689     MatConstIterator::operator = (it);
02690     return *this;
02691 }
02692 
02693 template<typename _Tp> inline
02694 _Tp& MatIterator_<_Tp>::operator *() const
02695 {
02696     return *(_Tp*)(this->ptr);
02697 }
02698 
02699 template<typename _Tp> inline
02700 MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
02701 {
02702     MatConstIterator::operator += (ofs);
02703     return *this;
02704 }
02705 
02706 template<typename _Tp> inline
02707 MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
02708 {
02709     MatConstIterator::operator += (-ofs);
02710     return *this;
02711 }
02712 
02713 template<typename _Tp> inline
02714 MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
02715 {
02716     MatConstIterator::operator --();
02717     return *this;
02718 }
02719 
02720 template<typename _Tp> inline
02721 MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
02722 {
02723     MatIterator_ b = *this;
02724     MatConstIterator::operator --();
02725     return b;
02726 }
02727 
02728 template<typename _Tp> inline
02729 MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
02730 {
02731     MatConstIterator::operator ++();
02732     return *this;
02733 }
02734 
02735 template<typename _Tp> inline
02736 MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
02737 {
02738     MatIterator_ b = *this;
02739     MatConstIterator::operator ++();
02740     return b;
02741 }
02742 
02743 template<typename _Tp> inline
02744 _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
02745 {
02746     return *(*this + i);
02747 }
02748 
02749 
02750 template<typename _Tp> static inline
02751 bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
02752 {
02753     return a.m == b.m && a.ptr == b.ptr;
02754 }
02755 
02756 template<typename _Tp> static inline
02757 bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
02758 {
02759     return a.m != b.m || a.ptr != b.ptr;
02760 }
02761 
02762 template<typename _Tp> static inline
02763 MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
02764 {
02765     MatConstIterator t = (const MatConstIterator&)a + ofs;
02766     return (MatIterator_<_Tp>&)t;
02767 }
02768 
02769 template<typename _Tp> static inline
02770 MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
02771 {
02772     MatConstIterator t = (const MatConstIterator&)a + ofs;
02773     return (MatIterator_<_Tp>&)t;
02774 }
02775 
02776 template<typename _Tp> static inline
02777 MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
02778 {
02779     MatConstIterator t = (const MatConstIterator&)a - ofs;
02780     return (MatIterator_<_Tp>&)t;
02781 }
02782 
02783 
02784 
02785 /////////////////////// SparseMatConstIterator //////////////////////
02786 
02787 inline
02788 SparseMatConstIterator::SparseMatConstIterator()
02789     : m(0), hashidx(0), ptr(0)
02790 {}
02791 
02792 inline
02793 SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
02794     : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
02795 {}
02796 
02797 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
02798 {
02799     if( this != &it )
02800     {
02801         m = it.m;
02802         hashidx = it.hashidx;
02803         ptr = it.ptr;
02804     }
02805     return *this;
02806 }
02807 
02808 template<typename _Tp> inline
02809 const _Tp& SparseMatConstIterator::value() const
02810 {
02811     return *(const _Tp*)ptr;
02812 }
02813 
02814 inline
02815 const SparseMat::Node* SparseMatConstIterator::node() const
02816 {
02817     return (ptr && m && m->hdr) ? (const SparseMat::Node*)(const void*)(ptr - m->hdr->valueOffset) : 0;
02818 }
02819 
02820 inline
02821 SparseMatConstIterator SparseMatConstIterator::operator ++(int)
02822 {
02823     SparseMatConstIterator it = *this;
02824     ++*this;
02825     return it;
02826 }
02827 
02828 inline
02829 void SparseMatConstIterator::seekEnd()
02830 {
02831     if( m && m->hdr )
02832     {
02833         hashidx = m->hdr->hashtab.size();
02834         ptr = 0;
02835     }
02836 }
02837 
02838 
02839 static inline
02840 bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
02841 {
02842     return it1.m == it2.m && it1.ptr == it2.ptr;
02843 }
02844 
02845 static inline
02846 bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
02847 {
02848     return !(it1 == it2);
02849 }
02850 
02851 
02852 
02853 ///////////////////////// SparseMatIterator /////////////////////////
02854 
02855 inline
02856 SparseMatIterator::SparseMatIterator()
02857 {}
02858 
02859 inline
02860 SparseMatIterator::SparseMatIterator(SparseMat* _m)
02861     : SparseMatConstIterator(_m)
02862 {}
02863 
02864 inline
02865 SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
02866     : SparseMatConstIterator(it)
02867 {}
02868 
02869 inline
02870 SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
02871 {
02872     (SparseMatConstIterator&)*this = it;
02873     return *this;
02874 }
02875 
02876 template<typename _Tp> inline
02877 _Tp& SparseMatIterator::value() const
02878 {
02879     return *(_Tp*)ptr;
02880 }
02881 
02882 inline
02883 SparseMat::Node* SparseMatIterator::node() const
02884 {
02885     return (SparseMat::Node*)SparseMatConstIterator::node();
02886 }
02887 
02888 inline
02889 SparseMatIterator& SparseMatIterator::operator ++()
02890 {
02891     SparseMatConstIterator::operator ++();
02892     return *this;
02893 }
02894 
02895 inline
02896 SparseMatIterator SparseMatIterator::operator ++(int)
02897 {
02898     SparseMatIterator it = *this;
02899     ++*this;
02900     return it;
02901 }
02902 
02903 
02904 
02905 ////////////////////// SparseMatConstIterator_ //////////////////////
02906 
02907 template<typename _Tp> inline
02908 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
02909 {}
02910 
02911 template<typename _Tp> inline
02912 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
02913     : SparseMatConstIterator(_m)
02914 {}
02915 
02916 template<typename _Tp> inline
02917 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
02918     : SparseMatConstIterator(_m)
02919 {
02920     CV_Assert( _m->type() == DataType<_Tp>::type );
02921 }
02922 
02923 template<typename _Tp> inline
02924 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
02925     : SparseMatConstIterator(it)
02926 {}
02927 
02928 template<typename _Tp> inline
02929 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
02930 {
02931     return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
02932          (*reinterpret_cast<SparseMatConstIterator*>(this) =
02933            reinterpret_cast<const SparseMatConstIterator&>(it));
02934 }
02935 
02936 template<typename _Tp> inline
02937 const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
02938 {
02939     return *(const _Tp*)this->ptr;
02940 }
02941 
02942 template<typename _Tp> inline
02943 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
02944 {
02945     SparseMatConstIterator::operator ++();
02946     return *this;
02947 }
02948 
02949 template<typename _Tp> inline
02950 SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
02951 {
02952     SparseMatConstIterator_<_Tp> it = *this;
02953     SparseMatConstIterator::operator ++();
02954     return it;
02955 }
02956 
02957 
02958 
02959 ///////////////////////// SparseMatIterator_ ////////////////////////
02960 
02961 template<typename _Tp> inline
02962 SparseMatIterator_<_Tp>::SparseMatIterator_()
02963 {}
02964 
02965 template<typename _Tp> inline
02966 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
02967     : SparseMatConstIterator_<_Tp>(_m)
02968 {}
02969 
02970 template<typename _Tp> inline
02971 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
02972     : SparseMatConstIterator_<_Tp>(_m)
02973 {}
02974 
02975 template<typename _Tp> inline
02976 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
02977     : SparseMatConstIterator_<_Tp>(it)
02978 {}
02979 
02980 template<typename _Tp> inline
02981 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
02982 {
02983     return reinterpret_cast<SparseMatIterator_<_Tp>&>
02984          (*reinterpret_cast<SparseMatConstIterator*>(this) =
02985            reinterpret_cast<const SparseMatConstIterator&>(it));
02986 }
02987 
02988 template<typename _Tp> inline
02989 _Tp& SparseMatIterator_<_Tp>::operator *() const
02990 {
02991     return *(_Tp*)this->ptr;
02992 }
02993 
02994 template<typename _Tp> inline
02995 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
02996 {
02997     SparseMatConstIterator::operator ++();
02998     return *this;
02999 }
03000 
03001 template<typename _Tp> inline
03002 SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
03003 {
03004     SparseMatIterator_<_Tp> it = *this;
03005     SparseMatConstIterator::operator ++();
03006     return it;
03007 }
03008 
03009 
03010 
03011 //////////////////////// MatCommaInitializer_ ///////////////////////
03012 
03013 template<typename _Tp> inline
03014 MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
03015     : it(_m)
03016 {}
03017 
03018 template<typename _Tp> template<typename T2> inline
03019 MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v)
03020 {
03021     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
03022     *this->it = _Tp(v);
03023     ++this->it;
03024     return *this;
03025 }
03026 
03027 template<typename _Tp> inline
03028 MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
03029 {
03030     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
03031     return Mat_<_Tp>(*this->it.m);
03032 }
03033 
03034 
03035 template<typename _Tp, typename T2> static inline
03036 MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
03037 {
03038     MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
03039     return (commaInitializer, val);
03040 }
03041 
03042 
03043 
03044 ///////////////////////// Matrix Expressions ////////////////////////
03045 
03046 inline
03047 Mat& Mat::operator = (const MatExpr& e)
03048 {
03049     e.op->assign(e, *this);
03050     return *this;
03051 }
03052 
03053 template<typename _Tp> inline
03054 Mat_<_Tp>::Mat_(const MatExpr& e)
03055 {
03056     e.op->assign(e, *this, DataType<_Tp>::type);
03057 }
03058 
03059 template<typename _Tp> inline
03060 Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
03061 {
03062     e.op->assign(e, *this, DataType<_Tp>::type);
03063     return *this;
03064 }
03065 
03066 template<typename _Tp> inline
03067 MatExpr Mat_<_Tp>::zeros(int rows, int cols)
03068 {
03069     return Mat::zeros(rows, cols, DataType<_Tp>::type);
03070 }
03071 
03072 template<typename _Tp> inline
03073 MatExpr Mat_<_Tp>::zeros(Size sz)
03074 {
03075     return Mat::zeros(sz, DataType<_Tp>::type);
03076 }
03077 
03078 template<typename _Tp> inline
03079 MatExpr Mat_<_Tp>::ones(int rows, int cols)
03080 {
03081     return Mat::ones(rows, cols, DataType<_Tp>::type);
03082 }
03083 
03084 template<typename _Tp> inline
03085 MatExpr Mat_<_Tp>::ones(Size sz)
03086 {
03087     return Mat::ones(sz, DataType<_Tp>::type);
03088 }
03089 
03090 template<typename _Tp> inline
03091 MatExpr Mat_<_Tp>::eye(int rows, int cols)
03092 {
03093     return Mat::eye(rows, cols, DataType<_Tp>::type);
03094 }
03095 
03096 template<typename _Tp> inline
03097 MatExpr Mat_<_Tp>::eye(Size sz)
03098 {
03099     return Mat::eye(sz, DataType<_Tp>::type);
03100 }
03101 
03102 inline
03103 MatExpr::MatExpr()
03104     : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
03105 {}
03106 
03107 inline
03108 MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b,
03109                  const Mat& _c, double _alpha, double _beta, const Scalar& _s)
03110     : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s)
03111 {}
03112 
03113 inline
03114 MatExpr::operator Mat() const
03115 {
03116     Mat m;
03117     op->assign(*this, m);
03118     return m;
03119 }
03120 
03121 template<typename _Tp> inline
03122 MatExpr::operator Mat_<_Tp>() const
03123 {
03124     Mat_<_Tp> m;
03125     op->assign(*this, m, DataType<_Tp>::type);
03126     return m;
03127 }
03128 
03129 
03130 template<typename _Tp> static inline
03131 MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
03132 {
03133     return cv::min((const Mat&)a, (const Mat&)b);
03134 }
03135 
03136 template<typename _Tp> static inline
03137 MatExpr min(const Mat_<_Tp>& a, double s)
03138 {
03139     return cv::min((const Mat&)a, s);
03140 }
03141 
03142 template<typename _Tp> static inline
03143 MatExpr min(double s, const Mat_<_Tp>& a)
03144 {
03145     return cv::min((const Mat&)a, s);
03146 }
03147 
03148 template<typename _Tp> static inline
03149 MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
03150 {
03151     return cv::max((const Mat&)a, (const Mat&)b);
03152 }
03153 
03154 template<typename _Tp> static inline
03155 MatExpr max(const Mat_<_Tp>& a, double s)
03156 {
03157     return cv::max((const Mat&)a, s);
03158 }
03159 
03160 template<typename _Tp> static inline
03161 MatExpr max(double s, const Mat_<_Tp>& a)
03162 {
03163     return cv::max((const Mat&)a, s);
03164 }
03165 
03166 template<typename _Tp> static inline
03167 MatExpr abs(const Mat_<_Tp>& m)
03168 {
03169     return cv::abs((const Mat&)m);
03170 }
03171 
03172 
03173 static inline
03174 Mat& operator += (Mat& a, const MatExpr& b)
03175 {
03176     b.op->augAssignAdd(b, a);
03177     return a;
03178 }
03179 
03180 static inline
03181 const Mat& operator += (const Mat& a, const MatExpr& b)
03182 {
03183     b.op->augAssignAdd(b, (Mat&)a);
03184     return a;
03185 }
03186 
03187 template<typename _Tp> static inline
03188 Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b)
03189 {
03190     b.op->augAssignAdd(b, a);
03191     return a;
03192 }
03193 
03194 template<typename _Tp> static inline
03195 const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
03196 {
03197     b.op->augAssignAdd(b, (Mat&)a);
03198     return a;
03199 }
03200 
03201 static inline
03202 Mat& operator -= (Mat& a, const MatExpr& b)
03203 {
03204     b.op->augAssignSubtract(b, a);
03205     return a;
03206 }
03207 
03208 static inline
03209 const Mat& operator -= (const Mat& a, const MatExpr& b)
03210 {
03211     b.op->augAssignSubtract(b, (Mat&)a);
03212     return a;
03213 }
03214 
03215 template<typename _Tp> static inline
03216 Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b)
03217 {
03218     b.op->augAssignSubtract(b, a);
03219     return a;
03220 }
03221 
03222 template<typename _Tp> static inline
03223 const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
03224 {
03225     b.op->augAssignSubtract(b, (Mat&)a);
03226     return a;
03227 }
03228 
03229 static inline
03230 Mat& operator *= (Mat& a, const MatExpr& b)
03231 {
03232     b.op->augAssignMultiply(b, a);
03233     return a;
03234 }
03235 
03236 static inline
03237 const Mat& operator *= (const Mat& a, const MatExpr& b)
03238 {
03239     b.op->augAssignMultiply(b, (Mat&)a);
03240     return a;
03241 }
03242 
03243 template<typename _Tp> static inline
03244 Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b)
03245 {
03246     b.op->augAssignMultiply(b, a);
03247     return a;
03248 }
03249 
03250 template<typename _Tp> static inline
03251 const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
03252 {
03253     b.op->augAssignMultiply(b, (Mat&)a);
03254     return a;
03255 }
03256 
03257 static inline
03258 Mat& operator /= (Mat& a, const MatExpr& b)
03259 {
03260     b.op->augAssignDivide(b, a);
03261     return a;
03262 }
03263 
03264 static inline
03265 const Mat& operator /= (const Mat& a, const MatExpr& b)
03266 {
03267     b.op->augAssignDivide(b, (Mat&)a);
03268     return a;
03269 }
03270 
03271 template<typename _Tp> static inline
03272 Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b)
03273 {
03274     b.op->augAssignDivide(b, a);
03275     return a;
03276 }
03277 
03278 template<typename _Tp> static inline
03279 const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
03280 {
03281     b.op->augAssignDivide(b, (Mat&)a);
03282     return a;
03283 }
03284 
03285 
03286 //////////////////////////////// UMat ////////////////////////////////
03287 
03288 inline
03289 UMat::UMat(UMatUsageFlags _usageFlags)
03290 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03291 {}
03292 
03293 inline
03294 UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
03295 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03296 {
03297     create(_rows, _cols, _type);
03298 }
03299 
03300 inline
03301 UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
03302 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03303 {
03304     create(_rows, _cols, _type);
03305     *this = _s;
03306 }
03307 
03308 inline
03309 UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
03310 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03311 {
03312     create( _sz.height, _sz.width, _type );
03313 }
03314 
03315 inline
03316 UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
03317 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03318 {
03319     create(_sz.height, _sz.width, _type);
03320     *this = _s;
03321 }
03322 
03323 inline
03324 UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
03325 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03326 {
03327     create(_dims, _sz, _type);
03328 }
03329 
03330 inline
03331 UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
03332 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03333 {
03334     create(_dims, _sz, _type);
03335     *this = _s;
03336 }
03337 
03338 inline
03339 UMat::UMat(const UMat& m)
03340 : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
03341   usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
03342 {
03343     addref();
03344     if( m.dims <= 2 )
03345     {
03346         step[0] = m.step[0]; step[1] = m.step[1];
03347     }
03348     else
03349     {
03350         dims = 0;
03351         copySize(m);
03352     }
03353 }
03354 
03355 
03356 template<typename _Tp> inline
03357 UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
03358 : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
03359 cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
03360 {
03361     if(vec.empty())
03362         return;
03363     if( !copyData )
03364     {
03365         // !!!TODO!!!
03366         CV_Error(Error::StsNotImplemented, "");
03367     }
03368     else
03369         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
03370 }
03371 
03372 
03373 inline
03374 UMat& UMat::operator = (const UMat& m)
03375 {
03376     if( this != &m )
03377     {
03378         const_cast<UMat&>(m).addref();
03379         release();
03380         flags  = m.flags;
03381         if( dims <= 2 && m.dims <= 2 )
03382         {
03383             dims = m.dims;
03384             rows = m.rows;
03385             cols = m.cols;
03386             step[0] = m.step[0];
03387             step[1] = m.step[1];
03388         }
03389         else
03390             copySize(m);
03391         allocator = m.allocator;
03392         if (usageFlags == USAGE_DEFAULT)
03393             usageFlags = m.usageFlags;
03394         u = m.u;
03395         offset = m.offset;
03396     }
03397     return *this;
03398 }
03399 
03400 inline
03401 UMat UMat::row(int y) const
03402 {
03403     return UMat(*this, Range(y, y + 1), Range::all());
03404 }
03405 
03406 inline
03407 UMat UMat::col(int x) const
03408 {
03409     return UMat(*this, Range::all(), Range(x, x + 1));
03410 }
03411 
03412 inline
03413 UMat UMat::rowRange(int startrow, int endrow) const
03414 {
03415     return UMat(*this, Range(startrow, endrow), Range::all());
03416 }
03417 
03418 inline
03419 UMat UMat::rowRange(const Range& r) const
03420 {
03421     return UMat(*this, r, Range::all());
03422 }
03423 
03424 inline
03425 UMat UMat::colRange(int startcol, int endcol) const
03426 {
03427     return UMat(*this, Range::all(), Range(startcol, endcol));
03428 }
03429 
03430 inline
03431 UMat UMat::colRange(const Range& r) const
03432 {
03433     return UMat(*this, Range::all(), r);
03434 }
03435 
03436 inline
03437 UMat UMat::clone() const
03438 {
03439     UMat m;
03440     copyTo(m);
03441     return m;
03442 }
03443 
03444 inline
03445 void UMat::assignTo( UMat& m, int _type ) const
03446 {
03447     if( _type < 0 )
03448         m = *this;
03449     else
03450         convertTo(m, _type);
03451 }
03452 
03453 inline
03454 void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
03455 {
03456     _type &= TYPE_MASK;
03457     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u )
03458         return;
03459     int sz[] = {_rows, _cols};
03460     create(2, sz, _type, _usageFlags);
03461 }
03462 
03463 inline
03464 void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
03465 {
03466     create(_sz.height, _sz.width, _type, _usageFlags);
03467 }
03468 
03469 inline
03470 void UMat::addref()
03471 {
03472     if( u )
03473         CV_XADD(&(u->urefcount), 1);
03474 }
03475 
03476 inline void UMat::release()
03477 {
03478     if( u && CV_XADD(&(u->urefcount), -1) == 1 )
03479         deallocate();
03480     for(int i = 0; i < dims; i++)
03481         size.p[i] = 0;
03482     u = 0;
03483 }
03484 
03485 inline
03486 UMat UMat::operator()( Range _rowRange, Range _colRange ) const
03487 {
03488     return UMat(*this, _rowRange, _colRange);
03489 }
03490 
03491 inline
03492 UMat UMat::operator()( const Rect& roi ) const
03493 {
03494     return UMat(*this, roi);
03495 }
03496 
03497 inline
03498 UMat UMat::operator()(const Range* ranges) const
03499 {
03500     return UMat(*this, ranges);
03501 }
03502 
03503 inline
03504 bool UMat::isContinuous() const
03505 {
03506     return (flags  & CONTINUOUS_FLAG) != 0;
03507 }
03508 
03509 inline
03510 bool UMat::isSubmatrix() const
03511 {
03512     return (flags  & SUBMATRIX_FLAG) != 0;
03513 }
03514 
03515 inline
03516 size_t UMat::elemSize() const
03517 {
03518     return dims > 0 ? step.p[dims - 1] : 0;
03519 }
03520 
03521 inline
03522 size_t UMat::elemSize1() const
03523 {
03524     return CV_ELEM_SIZE1(flags );
03525 }
03526 
03527 inline
03528 int UMat::type() const
03529 {
03530     return CV_MAT_TYPE(flags );
03531 }
03532 
03533 inline
03534 int UMat::depth() const
03535 {
03536     return CV_MAT_DEPTH(flags );
03537 }
03538 
03539 inline
03540 int UMat::channels() const
03541 {
03542     return CV_MAT_CN(flags );
03543 }
03544 
03545 inline
03546 size_t UMat::step1(int i) const
03547 {
03548     return step.p[i] / elemSize1();
03549 }
03550 
03551 inline
03552 bool UMat::empty() const
03553 {
03554     return u == 0 || total() == 0;
03555 }
03556 
03557 inline
03558 size_t UMat::total() const
03559 {
03560     if( dims <= 2 )
03561         return (size_t)rows * cols;
03562     size_t p = 1;
03563     for( int i = 0; i < dims; i++ )
03564         p *= size[i];
03565     return p;
03566 }
03567 
03568 #ifdef CV_CXX_MOVE_SEMANTICS
03569 
03570 inline
03571 UMat::UMat(UMat&& m)
03572 : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
03573   usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
03574 {
03575     if (m.dims <= 2)  // move new step/size info
03576     {
03577         step[0] = m.step[0];
03578         step[1] = m.step[1];
03579     }
03580     else
03581     {
03582         CV_DbgAssert(m.step.p != m.step.buf);
03583         step.p = m.step.p;
03584         size.p = m.size.p;
03585         m.step.p = m.step.buf;
03586         m.size.p = &m.rows;
03587     }
03588     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
03589     m.allocator = NULL;
03590     m.u = NULL;
03591     m.offset = 0;
03592 }
03593 
03594 inline
03595 UMat& UMat::operator = (UMat&& m)
03596 {
03597     release();
03598     flags  = m.flags; dims = m.dims; rows = m.rows; cols = m.cols;
03599     allocator = m.allocator; usageFlags = m.usageFlags;
03600     u = m.u;
03601     offset = m.offset;
03602     if (step.p != step.buf) // release self step/size
03603     {
03604         fastFree(step.p);
03605         step.p = step.buf;
03606         size.p = &rows;
03607     }
03608     if (m.dims <= 2) // move new step/size info
03609     {
03610         step[0] = m.step[0];
03611         step[1] = m.step[1];
03612     }
03613     else
03614     {
03615         CV_DbgAssert(m.step.p != m.step.buf);
03616         step.p = m.step.p;
03617         size.p = m.size.p;
03618         m.step.p = m.step.buf;
03619         m.size.p = &m.rows;
03620     }
03621     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
03622     m.allocator = NULL;
03623     m.u = NULL;
03624     m.offset = 0;
03625     return *this;
03626 }
03627 
03628 #endif
03629 
03630 
03631 inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
03632 inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
03633 inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }
03634 inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; }
03635 inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; }
03636 inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; }
03637 
03638 inline void UMatData::markDeviceMemMapped(bool flag)
03639 {
03640   if(flag)
03641     flags |= DEVICE_MEM_MAPPED;
03642   else
03643     flags &= ~DEVICE_MEM_MAPPED;
03644 }
03645 
03646 inline void UMatData::markHostCopyObsolete(bool flag)
03647 {
03648     if(flag)
03649         flags |= HOST_COPY_OBSOLETE;
03650     else
03651         flags &= ~HOST_COPY_OBSOLETE;
03652 }
03653 inline void UMatData::markDeviceCopyObsolete(bool flag)
03654 {
03655     if(flag)
03656         flags |= DEVICE_COPY_OBSOLETE;
03657     else
03658         flags &= ~DEVICE_COPY_OBSOLETE;
03659 }
03660 
03661 inline UMatDataAutoLock::UMatDataAutoLock(UMatData* _u) : u(_u) { u->lock(); }
03662 inline UMatDataAutoLock::~UMatDataAutoLock() { u->unlock(); }
03663 
03664 //! @endcond
03665 
03666 } //cv
03667 
03668 #endif
03669