Home | History | Annotate | Download | only in core
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                          License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
     15 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
     16 // Copyright (C) 2015, Itseez Inc., all rights reserved.
     17 // Third party copyrights are property of their respective owners.
     18 //
     19 // Redistribution and use in source and binary forms, with or without modification,
     20 // are permitted provided that the following conditions are met:
     21 //
     22 //   * Redistribution's of source code must retain the above copyright notice,
     23 //     this list of conditions and the following disclaimer.
     24 //
     25 //   * Redistribution's in binary form must reproduce the above copyright notice,
     26 //     this list of conditions and the following disclaimer in the documentation
     27 //     and/or other materials provided with the distribution.
     28 //
     29 //   * The name of the copyright holders may not be used to endorse or promote products
     30 //     derived from this software without specific prior written permission.
     31 //
     32 // This software is provided by the copyright holders and contributors "as is" and
     33 // any express or implied warranties, including, but not limited to, the implied
     34 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     35 // In no event shall the Intel Corporation or contributors be liable for any direct,
     36 // indirect, incidental, special, exemplary, or consequential damages
     37 // (including, but not limited to, procurement of substitute goods or services;
     38 // loss of use, data, or profits; or business interruption) however caused
     39 // and on any theory of liability, whether in contract, strict liability,
     40 // or tort (including negligence or otherwise) arising in any way out of
     41 // the use of this software, even if advised of the possibility of such damage.
     42 //
     43 //M*/
     44 
     45 #ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
     46 #define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
     47 
     48 #ifndef __cplusplus
     49 #  error mat.inl.hpp header must be compiled as C++
     50 #endif
     51 
     52 namespace cv
     53 {
     54 
     55 //! @cond IGNORED
     56 
     57 //////////////////////// Input/Output Arrays ////////////////////////
     58 
     59 inline void _InputArray::init(int _flags, const void* _obj)
     60 { flags = _flags; obj = (void*)_obj; }
     61 
     62 inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
     63 { flags = _flags; obj = (void*)_obj; sz = _sz; }
     64 
     65 inline void* _InputArray::getObj() const { return obj; }
     66 inline int _InputArray::getFlags() const { return flags; }
     67 inline Size _InputArray::getSz() const { return sz; }
     68 
     69 inline _InputArray::_InputArray() { init(NONE, 0); }
     70 inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
     71 inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
     72 inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
     73 inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
     74 inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }
     75 
     76 template<typename _Tp> inline
     77 _InputArray::_InputArray(const std::vector<_Tp>& vec)
     78 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
     79 
     80 inline
     81 _InputArray::_InputArray(const std::vector<bool>& vec)
     82 { init(FIXED_TYPE + STD_BOOL_VECTOR + DataType<bool>::type + ACCESS_READ, &vec); }
     83 
     84 template<typename _Tp> inline
     85 _InputArray::_InputArray(const std::vector<std::vector<_Tp> >& vec)
     86 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
     87 
     88 template<typename _Tp> inline
     89 _InputArray::_InputArray(const std::vector<Mat_<_Tp> >& vec)
     90 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_READ, &vec); }
     91 
     92 template<typename _Tp, int m, int n> inline
     93 _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
     94 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, &mtx, Size(n, m)); }
     95 
     96 template<typename _Tp> inline
     97 _InputArray::_InputArray(const _Tp* vec, int n)
     98 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, vec, Size(n, 1)); }
     99 
    100 template<typename _Tp> inline
    101 _InputArray::_InputArray(const Mat_<_Tp>& m)
    102 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_READ, &m); }
    103 
    104 inline _InputArray::_InputArray(const double& val)
    105 { init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); }
    106 
    107 inline _InputArray::_InputArray(const MatExpr& expr)
    108 { init(FIXED_TYPE + FIXED_SIZE + EXPR + ACCESS_READ, &expr); }
    109 
    110 inline _InputArray::_InputArray(const cuda::GpuMat& d_mat)
    111 { init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
    112 
    113 inline _InputArray::_InputArray(const ogl::Buffer& buf)
    114 { init(OPENGL_BUFFER + ACCESS_READ, &buf); }
    115 
    116 inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
    117 { init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
    118 
    119 inline _InputArray::~_InputArray() {}
    120 
    121 inline Mat _InputArray::getMat(int i) const
    122 {
    123     if( kind() == MAT && i < 0 )
    124         return *(const Mat*)obj;
    125     return getMat_(i);
    126 }
    127 
    128 inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }
    129 inline bool _InputArray::isUMat() const  { return kind() == _InputArray::UMAT; }
    130 inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
    131 inline bool _InputArray::isUMatVector() const  { return kind() == _InputArray::STD_VECTOR_UMAT; }
    132 inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; }
    133 
    134 ////////////////////////////////////////////////////////////////////////////////////////
    135 
    136 inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
    137 inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
    138 inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
    139 inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
    140 inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
    141 inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
    142 
    143 template<typename _Tp> inline
    144 _OutputArray::_OutputArray(std::vector<_Tp>& vec)
    145 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
    146 
    147 inline
    148 _OutputArray::_OutputArray(std::vector<bool>&)
    149 { CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an output array\n"); }
    150 
    151 template<typename _Tp> inline
    152 _OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
    153 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
    154 
    155 template<typename _Tp> inline
    156 _OutputArray::_OutputArray(std::vector<Mat_<_Tp> >& vec)
    157 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
    158 
    159 template<typename _Tp> inline
    160 _OutputArray::_OutputArray(Mat_<_Tp>& m)
    161 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
    162 
    163 template<typename _Tp, int m, int n> inline
    164 _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
    165 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
    166 
    167 template<typename _Tp> inline
    168 _OutputArray::_OutputArray(_Tp* vec, int n)
    169 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
    170 
    171 template<typename _Tp> inline
    172 _OutputArray::_OutputArray(const std::vector<_Tp>& vec)
    173 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
    174 
    175 template<typename _Tp> inline
    176 _OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
    177 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
    178 
    179 template<typename _Tp> inline
    180 _OutputArray::_OutputArray(const std::vector<Mat_<_Tp> >& vec)
    181 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
    182 
    183 template<typename _Tp> inline
    184 _OutputArray::_OutputArray(const Mat_<_Tp>& m)
    185 { init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
    186 
    187 template<typename _Tp, int m, int n> inline
    188 _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
    189 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
    190 
    191 template<typename _Tp> inline
    192 _OutputArray::_OutputArray(const _Tp* vec, int n)
    193 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
    194 
    195 inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat)
    196 { init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
    197 
    198 inline _OutputArray::_OutputArray(ogl::Buffer& buf)
    199 { init(OPENGL_BUFFER + ACCESS_WRITE, &buf); }
    200 
    201 inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem)
    202 { init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
    203 
    204 inline _OutputArray::_OutputArray(const Mat& m)
    205 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); }
    206 
    207 inline _OutputArray::_OutputArray(const std::vector<Mat>& vec)
    208 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
    209 
    210 inline _OutputArray::_OutputArray(const UMat& m)
    211 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); }
    212 
    213 inline _OutputArray::_OutputArray(const std::vector<UMat>& vec)
    214 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
    215 
    216 inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat)
    217 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
    218 
    219 inline _OutputArray::_OutputArray(const ogl::Buffer& buf)
    220 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); }
    221 
    222 inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
    223 { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
    224 
    225 ///////////////////////////////////////////////////////////////////////////////////////////
    226 
    227 inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
    228 inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
    229 inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
    230 inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
    231 inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
    232 inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); }
    233 
    234 template<typename _Tp> inline
    235 _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
    236 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
    237 
    238 inline _InputOutputArray::_InputOutputArray(std::vector<bool>&)
    239 { CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an input/output array\n"); }
    240 
    241 template<typename _Tp> inline
    242 _InputOutputArray::_InputOutputArray(std::vector<std::vector<_Tp> >& vec)
    243 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
    244 
    245 template<typename _Tp> inline
    246 _InputOutputArray::_InputOutputArray(std::vector<Mat_<_Tp> >& vec)
    247 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
    248 
    249 template<typename _Tp> inline
    250 _InputOutputArray::_InputOutputArray(Mat_<_Tp>& m)
    251 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
    252 
    253 template<typename _Tp, int m, int n> inline
    254 _InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx)
    255 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
    256 
    257 template<typename _Tp> inline
    258 _InputOutputArray::_InputOutputArray(_Tp* vec, int n)
    259 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
    260 
    261 template<typename _Tp> inline
    262 _InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec)
    263 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
    264 
    265 template<typename _Tp> inline
    266 _InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec)
    267 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
    268 
    269 template<typename _Tp> inline
    270 _InputOutputArray::_InputOutputArray(const std::vector<Mat_<_Tp> >& vec)
    271 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
    272 
    273 template<typename _Tp> inline
    274 _InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m)
    275 { init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
    276 
    277 template<typename _Tp, int m, int n> inline
    278 _InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx)
    279 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
    280 
    281 template<typename _Tp> inline
    282 _InputOutputArray::_InputOutputArray(const _Tp* vec, int n)
    283 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
    284 
    285 inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat)
    286 { init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
    287 
    288 inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf)
    289 { init(OPENGL_BUFFER + ACCESS_RW, &buf); }
    290 
    291 inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem)
    292 { init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
    293 
    294 inline _InputOutputArray::_InputOutputArray(const Mat& m)
    295 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); }
    296 
    297 inline _InputOutputArray::_InputOutputArray(const std::vector<Mat>& vec)
    298 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); }
    299 
    300 inline _InputOutputArray::_InputOutputArray(const UMat& m)
    301 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); }
    302 
    303 inline _InputOutputArray::_InputOutputArray(const std::vector<UMat>& vec)
    304 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); }
    305 
    306 inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat)
    307 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
    308 
    309 inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf)
    310 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); }
    311 
    312 inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
    313 { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
    314 
    315 //////////////////////////////////////////// Mat //////////////////////////////////////////
    316 
    317 inline
    318 Mat::Mat()
    319     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    320       datalimit(0), allocator(0), u(0), size(&rows)
    321 {}
    322 
    323 inline
    324 Mat::Mat(int _rows, int _cols, int _type)
    325     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    326       datalimit(0), allocator(0), u(0), size(&rows)
    327 {
    328     create(_rows, _cols, _type);
    329 }
    330 
    331 inline
    332 Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
    333     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    334       datalimit(0), allocator(0), u(0), size(&rows)
    335 {
    336     create(_rows, _cols, _type);
    337     *this = _s;
    338 }
    339 
    340 inline
    341 Mat::Mat(Size _sz, int _type)
    342     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    343       datalimit(0), allocator(0), u(0), size(&rows)
    344 {
    345     create( _sz.height, _sz.width, _type );
    346 }
    347 
    348 inline
    349 Mat::Mat(Size _sz, int _type, const Scalar& _s)
    350     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    351       datalimit(0), allocator(0), u(0), size(&rows)
    352 {
    353     create(_sz.height, _sz.width, _type);
    354     *this = _s;
    355 }
    356 
    357 inline
    358 Mat::Mat(int _dims, const int* _sz, int _type)
    359     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    360       datalimit(0), allocator(0), u(0), size(&rows)
    361 {
    362     create(_dims, _sz, _type);
    363 }
    364 
    365 inline
    366 Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
    367     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
    368       datalimit(0), allocator(0), u(0), size(&rows)
    369 {
    370     create(_dims, _sz, _type);
    371     *this = _s;
    372 }
    373 
    374 inline
    375 Mat::Mat(const Mat& m)
    376     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
    377       datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
    378       u(m.u), size(&rows)
    379 {
    380     if( u )
    381         CV_XADD(&u->refcount, 1);
    382     if( m.dims <= 2 )
    383     {
    384         step[0] = m.step[0]; step[1] = m.step[1];
    385     }
    386     else
    387     {
    388         dims = 0;
    389         copySize(m);
    390     }
    391 }
    392 
    393 inline
    394 Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
    395     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
    396       data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
    397       allocator(0), u(0), size(&rows)
    398 {
    399     size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
    400     size_t minstep = cols * esz;
    401     if( _step == AUTO_STEP )
    402     {
    403         _step = minstep;
    404         flags |= CONTINUOUS_FLAG;
    405     }
    406     else
    407     {
    408         if( rows == 1 ) _step = minstep;
    409         CV_DbgAssert( _step >= minstep );
    410 
    411         if (_step % esz1 != 0)
    412         {
    413             CV_Error(Error::BadStep, "Step must be a multiple of esz1");
    414         }
    415 
    416         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
    417     }
    418     step[0] = _step;
    419     step[1] = esz;
    420     datalimit = datastart + _step * rows;
    421     dataend = datalimit - _step + minstep;
    422 }
    423 
    424 inline
    425 Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
    426     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
    427       data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
    428       allocator(0), u(0), size(&rows)
    429 {
    430     size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
    431     size_t minstep = cols*esz;
    432     if( _step == AUTO_STEP )
    433     {
    434         _step = minstep;
    435         flags |= CONTINUOUS_FLAG;
    436     }
    437     else
    438     {
    439         if( rows == 1 ) _step = minstep;
    440         CV_DbgAssert( _step >= minstep );
    441 
    442         if (_step % esz1 != 0)
    443         {
    444             CV_Error(Error::BadStep, "Step must be a multiple of esz1");
    445         }
    446 
    447         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
    448     }
    449     step[0] = _step;
    450     step[1] = esz;
    451     datalimit = datastart + _step*rows;
    452     dataend = datalimit - _step + minstep;
    453 }
    454 
    455 template<typename _Tp> inline
    456 Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
    457     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
    458       cols(1), data(0), datastart(0), dataend(0), allocator(0), u(0), size(&rows)
    459 {
    460     if(vec.empty())
    461         return;
    462     if( !copyData )
    463     {
    464         step[0] = step[1] = sizeof(_Tp);
    465         datastart = data = (uchar*)&vec[0];
    466         datalimit = dataend = datastart + rows * step[0];
    467     }
    468     else
    469         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
    470 }
    471 
    472 template<typename _Tp, int n> inline
    473 Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
    474     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
    475       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
    476 {
    477     if( !copyData )
    478     {
    479         step[0] = step[1] = sizeof(_Tp);
    480         datastart = data = (uchar*)vec.val;
    481         datalimit = dataend = datastart + rows * step[0];
    482     }
    483     else
    484         Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
    485 }
    486 
    487 
    488 template<typename _Tp, int m, int n> inline
    489 Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
    490     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
    491       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
    492 {
    493     if( !copyData )
    494     {
    495         step[0] = cols * sizeof(_Tp);
    496         step[1] = sizeof(_Tp);
    497         datastart = data = (uchar*)M.val;
    498         datalimit = dataend = datastart + rows * step[0];
    499     }
    500     else
    501         Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
    502 }
    503 
    504 template<typename _Tp> inline
    505 Mat::Mat(const Point_<_Tp>& pt, bool copyData)
    506     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
    507       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
    508 {
    509     if( !copyData )
    510     {
    511         step[0] = step[1] = sizeof(_Tp);
    512         datastart = data = (uchar*)&pt.x;
    513         datalimit = dataend = datastart + rows * step[0];
    514     }
    515     else
    516     {
    517         create(2, 1, DataType<_Tp>::type);
    518         ((_Tp*)data)[0] = pt.x;
    519         ((_Tp*)data)[1] = pt.y;
    520     }
    521 }
    522 
    523 template<typename _Tp> inline
    524 Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
    525     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
    526       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
    527 {
    528     if( !copyData )
    529     {
    530         step[0] = step[1] = sizeof(_Tp);
    531         datastart = data = (uchar*)&pt.x;
    532         datalimit = dataend = datastart + rows * step[0];
    533     }
    534     else
    535     {
    536         create(3, 1, DataType<_Tp>::type);
    537         ((_Tp*)data)[0] = pt.x;
    538         ((_Tp*)data)[1] = pt.y;
    539         ((_Tp*)data)[2] = pt.z;
    540     }
    541 }
    542 
    543 template<typename _Tp> inline
    544 Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
    545     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
    546       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
    547 {
    548     *this = commaInitializer.operator Mat_<_Tp>();
    549 }
    550 
    551 inline
    552 Mat::~Mat()
    553 {
    554     release();
    555     if( step.p != step.buf )
    556         fastFree(step.p);
    557 }
    558 
    559 inline
    560 Mat& Mat::operator = (const Mat& m)
    561 {
    562     if( this != &m )
    563     {
    564         if( m.u )
    565             CV_XADD(&m.u->refcount, 1);
    566         release();
    567         flags = m.flags;
    568         if( dims <= 2 && m.dims <= 2 )
    569         {
    570             dims = m.dims;
    571             rows = m.rows;
    572             cols = m.cols;
    573             step[0] = m.step[0];
    574             step[1] = m.step[1];
    575         }
    576         else
    577             copySize(m);
    578         data = m.data;
    579         datastart = m.datastart;
    580         dataend = m.dataend;
    581         datalimit = m.datalimit;
    582         allocator = m.allocator;
    583         u = m.u;
    584     }
    585     return *this;
    586 }
    587 
    588 inline
    589 Mat Mat::row(int y) const
    590 {
    591     return Mat(*this, Range(y, y + 1), Range::all());
    592 }
    593 
    594 inline
    595 Mat Mat::col(int x) const
    596 {
    597     return Mat(*this, Range::all(), Range(x, x + 1));
    598 }
    599 
    600 inline
    601 Mat Mat::rowRange(int startrow, int endrow) const
    602 {
    603     return Mat(*this, Range(startrow, endrow), Range::all());
    604 }
    605 
    606 inline
    607 Mat Mat::rowRange(const Range& r) const
    608 {
    609     return Mat(*this, r, Range::all());
    610 }
    611 
    612 inline
    613 Mat Mat::colRange(int startcol, int endcol) const
    614 {
    615     return Mat(*this, Range::all(), Range(startcol, endcol));
    616 }
    617 
    618 inline
    619 Mat Mat::colRange(const Range& r) const
    620 {
    621     return Mat(*this, Range::all(), r);
    622 }
    623 
    624 inline
    625 Mat Mat::clone() const
    626 {
    627     Mat m;
    628     copyTo(m);
    629     return m;
    630 }
    631 
    632 inline
    633 void Mat::assignTo( Mat& m, int _type ) const
    634 {
    635     if( _type < 0 )
    636         m = *this;
    637     else
    638         convertTo(m, _type);
    639 }
    640 
    641 inline
    642 void Mat::create(int _rows, int _cols, int _type)
    643 {
    644     _type &= TYPE_MASK;
    645     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
    646         return;
    647     int sz[] = {_rows, _cols};
    648     create(2, sz, _type);
    649 }
    650 
    651 inline
    652 void Mat::create(Size _sz, int _type)
    653 {
    654     create(_sz.height, _sz.width, _type);
    655 }
    656 
    657 inline
    658 void Mat::addref()
    659 {
    660     if( u )
    661         CV_XADD(&u->refcount, 1);
    662 }
    663 
    664 inline void Mat::release()
    665 {
    666     if( u && CV_XADD(&u->refcount, -1) == 1 )
    667         deallocate();
    668     u = NULL;
    669     datastart = dataend = datalimit = data = 0;
    670     for(int i = 0; i < dims; i++)
    671         size.p[i] = 0;
    672 }
    673 
    674 inline
    675 Mat Mat::operator()( Range _rowRange, Range _colRange ) const
    676 {
    677     return Mat(*this, _rowRange, _colRange);
    678 }
    679 
    680 inline
    681 Mat Mat::operator()( const Rect& roi ) const
    682 {
    683     return Mat(*this, roi);
    684 }
    685 
    686 inline
    687 Mat Mat::operator()(const Range* ranges) const
    688 {
    689     return Mat(*this, ranges);
    690 }
    691 
    692 inline
    693 bool Mat::isContinuous() const
    694 {
    695     return (flags & CONTINUOUS_FLAG) != 0;
    696 }
    697 
    698 inline
    699 bool Mat::isSubmatrix() const
    700 {
    701     return (flags & SUBMATRIX_FLAG) != 0;
    702 }
    703 
    704 inline
    705 size_t Mat::elemSize() const
    706 {
    707     return dims > 0 ? step.p[dims - 1] : 0;
    708 }
    709 
    710 inline
    711 size_t Mat::elemSize1() const
    712 {
    713     return CV_ELEM_SIZE1(flags);
    714 }
    715 
    716 inline
    717 int Mat::type() const
    718 {
    719     return CV_MAT_TYPE(flags);
    720 }
    721 
    722 inline
    723 int Mat::depth() const
    724 {
    725     return CV_MAT_DEPTH(flags);
    726 }
    727 
    728 inline
    729 int Mat::channels() const
    730 {
    731     return CV_MAT_CN(flags);
    732 }
    733 
    734 inline
    735 size_t Mat::step1(int i) const
    736 {
    737     return step.p[i] / elemSize1();
    738 }
    739 
    740 inline
    741 bool Mat::empty() const
    742 {
    743     return data == 0 || total() == 0;
    744 }
    745 
    746 inline
    747 size_t Mat::total() const
    748 {
    749     if( dims <= 2 )
    750         return (size_t)rows * cols;
    751     size_t p = 1;
    752     for( int i = 0; i < dims; i++ )
    753         p *= size[i];
    754     return p;
    755 }
    756 
    757 inline
    758 uchar* Mat::ptr(int y)
    759 {
    760     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
    761     return data + step.p[0] * y;
    762 }
    763 
    764 inline
    765 const uchar* Mat::ptr(int y) const
    766 {
    767     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
    768     return data + step.p[0] * y;
    769 }
    770 
    771 template<typename _Tp> inline
    772 _Tp* Mat::ptr(int y)
    773 {
    774     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
    775     return (_Tp*)(data + step.p[0] * y);
    776 }
    777 
    778 template<typename _Tp> inline
    779 const _Tp* Mat::ptr(int y) const
    780 {
    781     CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
    782     return (const _Tp*)(data + step.p[0] * y);
    783 }
    784 
    785 inline
    786 uchar* Mat::ptr(int i0, int i1)
    787 {
    788     CV_DbgAssert( dims >= 2 && data &&
    789                   (unsigned)i0 < (unsigned)size.p[0] &&
    790                   (unsigned)i1 < (unsigned)size.p[1] );
    791     return data + i0 * step.p[0] + i1 * step.p[1];
    792 }
    793 
    794 inline
    795 const uchar* Mat::ptr(int i0, int i1) const
    796 {
    797     CV_DbgAssert( dims >= 2 && data &&
    798                  (unsigned)i0 < (unsigned)size.p[0] &&
    799                  (unsigned)i1 < (unsigned)size.p[1] );
    800     return data + i0 * step.p[0] + i1 * step.p[1];
    801 }
    802 
    803 template<typename _Tp> inline
    804 _Tp* Mat::ptr(int i0, int i1)
    805 {
    806     CV_DbgAssert( dims >= 2 && data &&
    807                   (unsigned)i0 < (unsigned)size.p[0] &&
    808                   (unsigned)i1 < (unsigned)size.p[1] );
    809     return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
    810 }
    811 
    812 template<typename _Tp> inline
    813 const _Tp* Mat::ptr(int i0, int i1) const
    814 {
    815     CV_DbgAssert( dims >= 2 && data &&
    816                   (unsigned)i0 < (unsigned)size.p[0] &&
    817                   (unsigned)i1 < (unsigned)size.p[1] );
    818     return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
    819 }
    820 
    821 inline
    822 uchar* Mat::ptr(int i0, int i1, int i2)
    823 {
    824     CV_DbgAssert( dims >= 3 && data &&
    825                   (unsigned)i0 < (unsigned)size.p[0] &&
    826                   (unsigned)i1 < (unsigned)size.p[1] &&
    827                   (unsigned)i2 < (unsigned)size.p[2] );
    828     return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
    829 }
    830 
    831 inline
    832 const uchar* Mat::ptr(int i0, int i1, int i2) const
    833 {
    834     CV_DbgAssert( dims >= 3 && data &&
    835                   (unsigned)i0 < (unsigned)size.p[0] &&
    836                   (unsigned)i1 < (unsigned)size.p[1] &&
    837                   (unsigned)i2 < (unsigned)size.p[2] );
    838     return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
    839 }
    840 
    841 template<typename _Tp> inline
    842 _Tp* Mat::ptr(int i0, int i1, int i2)
    843 {
    844     CV_DbgAssert( dims >= 3 && data &&
    845                   (unsigned)i0 < (unsigned)size.p[0] &&
    846                   (unsigned)i1 < (unsigned)size.p[1] &&
    847                   (unsigned)i2 < (unsigned)size.p[2] );
    848     return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
    849 }
    850 
    851 template<typename _Tp> inline
    852 const _Tp* Mat::ptr(int i0, int i1, int i2) const
    853 {
    854     CV_DbgAssert( dims >= 3 && data &&
    855                   (unsigned)i0 < (unsigned)size.p[0] &&
    856                   (unsigned)i1 < (unsigned)size.p[1] &&
    857                   (unsigned)i2 < (unsigned)size.p[2] );
    858     return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
    859 }
    860 
    861 inline
    862 uchar* Mat::ptr(const int* idx)
    863 {
    864     int i, d = dims;
    865     uchar* p = data;
    866     CV_DbgAssert( d >= 1 && p );
    867     for( i = 0; i < d; i++ )
    868     {
    869         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
    870         p += idx[i] * step.p[i];
    871     }
    872     return p;
    873 }
    874 
    875 inline
    876 const uchar* Mat::ptr(const int* idx) const
    877 {
    878     int i, d = dims;
    879     uchar* p = data;
    880     CV_DbgAssert( d >= 1 && p );
    881     for( i = 0; i < d; i++ )
    882     {
    883         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
    884         p += idx[i] * step.p[i];
    885     }
    886     return p;
    887 }
    888 
    889 template<typename _Tp> inline
    890 _Tp& Mat::at(int i0, int i1)
    891 {
    892     CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
    893         (unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
    894         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
    895     return ((_Tp*)(data + step.p[0] * i0))[i1];
    896 }
    897 
    898 template<typename _Tp> inline
    899 const _Tp& Mat::at(int i0, int i1) const
    900 {
    901     CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
    902         (unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
    903         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
    904     return ((const _Tp*)(data + step.p[0] * i0))[i1];
    905 }
    906 
    907 template<typename _Tp> inline
    908 _Tp& Mat::at(Point pt)
    909 {
    910     CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
    911         (unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
    912         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
    913     return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
    914 }
    915 
    916 template<typename _Tp> inline
    917 const _Tp& Mat::at(Point pt) const
    918 {
    919     CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
    920         (unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()) &&
    921         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
    922     return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
    923 }
    924 
    925 template<typename _Tp> inline
    926 _Tp& Mat::at(int i0)
    927 {
    928     CV_DbgAssert( dims <= 2 && data &&
    929                  (unsigned)i0 < (unsigned)(size.p[0] * size.p[1]) &&
    930                  elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    931     if( isContinuous() || size.p[0] == 1 )
    932         return ((_Tp*)data)[i0];
    933     if( size.p[1] == 1 )
    934         return *(_Tp*)(data + step.p[0] * i0);
    935     int i = i0 / cols, j = i0 - i * cols;
    936     return ((_Tp*)(data + step.p[0] * i))[j];
    937 }
    938 
    939 template<typename _Tp> inline
    940 const _Tp& Mat::at(int i0) const
    941 {
    942     CV_DbgAssert( dims <= 2 && data &&
    943                  (unsigned)i0 < (unsigned)(size.p[0] * size.p[1]) &&
    944                  elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    945     if( isContinuous() || size.p[0] == 1 )
    946         return ((const _Tp*)data)[i0];
    947     if( size.p[1] == 1 )
    948         return *(const _Tp*)(data + step.p[0] * i0);
    949     int i = i0 / cols, j = i0 - i * cols;
    950     return ((const _Tp*)(data + step.p[0] * i))[j];
    951 }
    952 
    953 template<typename _Tp> inline
    954 _Tp& Mat::at(int i0, int i1, int i2)
    955 {
    956     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    957     return *(_Tp*)ptr(i0, i1, i2);
    958 }
    959 
    960 template<typename _Tp> inline
    961 const _Tp& Mat::at(int i0, int i1, int i2) const
    962 {
    963     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    964     return *(const _Tp*)ptr(i0, i1, i2);
    965 }
    966 
    967 template<typename _Tp> inline
    968 _Tp& Mat::at(const int* idx)
    969 {
    970     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    971     return *(_Tp*)ptr(idx);
    972 }
    973 
    974 template<typename _Tp> inline
    975 const _Tp& Mat::at(const int* idx) const
    976 {
    977     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    978     return *(const _Tp*)ptr(idx);
    979 }
    980 
    981 template<typename _Tp, int n> inline
    982 _Tp& Mat::at(const Vec<int, n>& idx)
    983 {
    984     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    985     return *(_Tp*)ptr(idx.val);
    986 }
    987 
    988 template<typename _Tp, int n> inline
    989 const _Tp& Mat::at(const Vec<int, n>& idx) const
    990 {
    991     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
    992     return *(const _Tp*)ptr(idx.val);
    993 }
    994 
    995 template<typename _Tp> inline
    996 MatConstIterator_<_Tp> Mat::begin() const
    997 {
    998     CV_DbgAssert( elemSize() == sizeof(_Tp) );
    999     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
   1000 }
   1001 
   1002 template<typename _Tp> inline
   1003 MatConstIterator_<_Tp> Mat::end() const
   1004 {
   1005     CV_DbgAssert( elemSize() == sizeof(_Tp) );
   1006     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
   1007     it += total();
   1008     return it;
   1009 }
   1010 
   1011 template<typename _Tp> inline
   1012 MatIterator_<_Tp> Mat::begin()
   1013 {
   1014     CV_DbgAssert( elemSize() == sizeof(_Tp) );
   1015     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
   1016 }
   1017 
   1018 template<typename _Tp> inline
   1019 MatIterator_<_Tp> Mat::end()
   1020 {
   1021     CV_DbgAssert( elemSize() == sizeof(_Tp) );
   1022     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
   1023     it += total();
   1024     return it;
   1025 }
   1026 
   1027 template<typename _Tp, typename Functor> inline
   1028 void Mat::forEach(const Functor& operation) {
   1029     this->forEach_impl<_Tp>(operation);
   1030 }
   1031 
   1032 template<typename _Tp, typename Functor> inline
   1033 void Mat::forEach(const Functor& operation) const {
   1034     // call as not const
   1035     (const_cast<Mat*>(this))->forEach<const _Tp>(operation);
   1036 }
   1037 
   1038 template<typename _Tp> inline
   1039 Mat::operator std::vector<_Tp>() const
   1040 {
   1041     std::vector<_Tp> v;
   1042     copyTo(v);
   1043     return v;
   1044 }
   1045 
   1046 template<typename _Tp, int n> inline
   1047 Mat::operator Vec<_Tp, n>() const
   1048 {
   1049     CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
   1050                rows + cols - 1 == n && channels() == 1 );
   1051 
   1052     if( isContinuous() && type() == DataType<_Tp>::type )
   1053         return Vec<_Tp, n>((_Tp*)data);
   1054     Vec<_Tp, n> v;
   1055     Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
   1056     convertTo(tmp, tmp.type());
   1057     return v;
   1058 }
   1059 
   1060 template<typename _Tp, int m, int n> inline
   1061 Mat::operator Matx<_Tp, m, n>() const
   1062 {
   1063     CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
   1064 
   1065     if( isContinuous() && type() == DataType<_Tp>::type )
   1066         return Matx<_Tp, m, n>((_Tp*)data);
   1067     Matx<_Tp, m, n> mtx;
   1068     Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
   1069     convertTo(tmp, tmp.type());
   1070     return mtx;
   1071 }
   1072 
   1073 template<typename _Tp> inline
   1074 void Mat::push_back(const _Tp& elem)
   1075 {
   1076     if( !data )
   1077     {
   1078         *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
   1079         return;
   1080     }
   1081     CV_Assert(DataType<_Tp>::type == type() && cols == 1
   1082               /* && dims == 2 (cols == 1 implies dims == 2) */);
   1083     const uchar* tmp = dataend + step[0];
   1084     if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
   1085     {
   1086         *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
   1087         dataend = tmp;
   1088     }
   1089     else
   1090         push_back_(&elem);
   1091 }
   1092 
   1093 template<typename _Tp> inline
   1094 void Mat::push_back(const Mat_<_Tp>& m)
   1095 {
   1096     push_back((const Mat&)m);
   1097 }
   1098 
   1099 ///////////////////////////// MatSize ////////////////////////////
   1100 
   1101 inline
   1102 MatSize::MatSize(int* _p)
   1103     : p(_p) {}
   1104 
   1105 inline
   1106 Size MatSize::operator()() const
   1107 {
   1108     CV_DbgAssert(p[-1] <= 2);
   1109     return Size(p[1], p[0]);
   1110 }
   1111 
   1112 inline
   1113 const int& MatSize::operator[](int i) const
   1114 {
   1115     return p[i];
   1116 }
   1117 
   1118 inline
   1119 int& MatSize::operator[](int i)
   1120 {
   1121     return p[i];
   1122 }
   1123 
   1124 inline
   1125 MatSize::operator const int*() const
   1126 {
   1127     return p;
   1128 }
   1129 
   1130 inline
   1131 bool MatSize::operator == (const MatSize& sz) const
   1132 {
   1133     int d = p[-1];
   1134     int dsz = sz.p[-1];
   1135     if( d != dsz )
   1136         return false;
   1137     if( d == 2 )
   1138         return p[0] == sz.p[0] && p[1] == sz.p[1];
   1139 
   1140     for( int i = 0; i < d; i++ )
   1141         if( p[i] != sz.p[i] )
   1142             return false;
   1143     return true;
   1144 }
   1145 
   1146 inline
   1147 bool MatSize::operator != (const MatSize& sz) const
   1148 {
   1149     return !(*this == sz);
   1150 }
   1151 
   1152 
   1153 
   1154 ///////////////////////////// MatStep ////////////////////////////
   1155 
   1156 inline
   1157 MatStep::MatStep()
   1158 {
   1159     p = buf; p[0] = p[1] = 0;
   1160 }
   1161 
   1162 inline
   1163 MatStep::MatStep(size_t s)
   1164 {
   1165     p = buf; p[0] = s; p[1] = 0;
   1166 }
   1167 
   1168 inline
   1169 const size_t& MatStep::operator[](int i) const
   1170 {
   1171     return p[i];
   1172 }
   1173 
   1174 inline
   1175 size_t& MatStep::operator[](int i)
   1176 {
   1177     return p[i];
   1178 }
   1179 
   1180 inline MatStep::operator size_t() const
   1181 {
   1182     CV_DbgAssert( p == buf );
   1183     return buf[0];
   1184 }
   1185 
   1186 inline MatStep& MatStep::operator = (size_t s)
   1187 {
   1188     CV_DbgAssert( p == buf );
   1189     buf[0] = s;
   1190     return *this;
   1191 }
   1192 
   1193 
   1194 
   1195 ////////////////////////////// Mat_<_Tp> ////////////////////////////
   1196 
   1197 template<typename _Tp> inline
   1198 Mat_<_Tp>::Mat_()
   1199     : Mat()
   1200 {
   1201     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
   1202 }
   1203 
   1204 template<typename _Tp> inline
   1205 Mat_<_Tp>::Mat_(int _rows, int _cols)
   1206     : Mat(_rows, _cols, DataType<_Tp>::type)
   1207 {
   1208 }
   1209 
   1210 template<typename _Tp> inline
   1211 Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
   1212     : Mat(_rows, _cols, DataType<_Tp>::type)
   1213 {
   1214     *this = value;
   1215 }
   1216 
   1217 template<typename _Tp> inline
   1218 Mat_<_Tp>::Mat_(Size _sz)
   1219     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
   1220 {}
   1221 
   1222 template<typename _Tp> inline
   1223 Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
   1224     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
   1225 {
   1226     *this = value;
   1227 }
   1228 
   1229 template<typename _Tp> inline
   1230 Mat_<_Tp>::Mat_(int _dims, const int* _sz)
   1231     : Mat(_dims, _sz, DataType<_Tp>::type)
   1232 {}
   1233 
   1234 template<typename _Tp> inline
   1235 Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
   1236     : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s))
   1237 {}
   1238 
   1239 template<typename _Tp> inline
   1240 Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
   1241     : Mat(m, ranges)
   1242 {}
   1243 
   1244 template<typename _Tp> inline
   1245 Mat_<_Tp>::Mat_(const Mat& m)
   1246     : Mat()
   1247 {
   1248     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
   1249     *this = m;
   1250 }
   1251 
   1252 template<typename _Tp> inline
   1253 Mat_<_Tp>::Mat_(const Mat_& m)
   1254     : Mat(m)
   1255 {}
   1256 
   1257 template<typename _Tp> inline
   1258 Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
   1259     : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps)
   1260 {}
   1261 
   1262 template<typename _Tp> inline
   1263 Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
   1264     : Mat(m, _rowRange, _colRange)
   1265 {}
   1266 
   1267 template<typename _Tp> inline
   1268 Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
   1269     : Mat(m, roi)
   1270 {}
   1271 
   1272 template<typename _Tp> template<int n> inline
   1273 Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
   1274     : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
   1275 {
   1276     CV_Assert(n%DataType<_Tp>::channels == 0);
   1277     if( copyData )
   1278         *this = clone();
   1279 }
   1280 
   1281 template<typename _Tp> template<int m, int n> inline
   1282 Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& M, bool copyData)
   1283     : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
   1284 {
   1285     CV_Assert(n % DataType<_Tp>::channels == 0);
   1286     if( copyData )
   1287         *this = clone();
   1288 }
   1289 
   1290 template<typename _Tp> inline
   1291 Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
   1292     : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
   1293 {
   1294     CV_Assert(2 % DataType<_Tp>::channels == 0);
   1295     if( copyData )
   1296         *this = clone();
   1297 }
   1298 
   1299 template<typename _Tp> inline
   1300 Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
   1301     : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
   1302 {
   1303     CV_Assert(3 % DataType<_Tp>::channels == 0);
   1304     if( copyData )
   1305         *this = clone();
   1306 }
   1307 
   1308 template<typename _Tp> inline
   1309 Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
   1310     : Mat(commaInitializer)
   1311 {}
   1312 
   1313 template<typename _Tp> inline
   1314 Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
   1315     : Mat(vec, copyData)
   1316 {}
   1317 
   1318 template<typename _Tp> inline
   1319 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
   1320 {
   1321     if( DataType<_Tp>::type == m.type() )
   1322     {
   1323         Mat::operator = (m);
   1324         return *this;
   1325     }
   1326     if( DataType<_Tp>::depth == m.depth() )
   1327     {
   1328         return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
   1329     }
   1330     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
   1331     m.convertTo(*this, type());
   1332     return *this;
   1333 }
   1334 
   1335 template<typename _Tp> inline
   1336 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
   1337 {
   1338     Mat::operator=(m);
   1339     return *this;
   1340 }
   1341 
   1342 template<typename _Tp> inline
   1343 Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
   1344 {
   1345     typedef typename DataType<_Tp>::vec_type VT;
   1346     Mat::operator=(Scalar((const VT&)s));
   1347     return *this;
   1348 }
   1349 
   1350 template<typename _Tp> inline
   1351 void Mat_<_Tp>::create(int _rows, int _cols)
   1352 {
   1353     Mat::create(_rows, _cols, DataType<_Tp>::type);
   1354 }
   1355 
   1356 template<typename _Tp> inline
   1357 void Mat_<_Tp>::create(Size _sz)
   1358 {
   1359     Mat::create(_sz, DataType<_Tp>::type);
   1360 }
   1361 
   1362 template<typename _Tp> inline
   1363 void Mat_<_Tp>::create(int _dims, const int* _sz)
   1364 {
   1365     Mat::create(_dims, _sz, DataType<_Tp>::type);
   1366 }
   1367 
   1368 template<typename _Tp> inline
   1369 Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
   1370 {
   1371     return Mat_<_Tp>(Mat::cross(m));
   1372 }
   1373 
   1374 template<typename _Tp> template<typename T2> inline
   1375 Mat_<_Tp>::operator Mat_<T2>() const
   1376 {
   1377     return Mat_<T2>(*this);
   1378 }
   1379 
   1380 template<typename _Tp> inline
   1381 Mat_<_Tp> Mat_<_Tp>::row(int y) const
   1382 {
   1383     return Mat_(*this, Range(y, y+1), Range::all());
   1384 }
   1385 
   1386 template<typename _Tp> inline
   1387 Mat_<_Tp> Mat_<_Tp>::col(int x) const
   1388 {
   1389     return Mat_(*this, Range::all(), Range(x, x+1));
   1390 }
   1391 
   1392 template<typename _Tp> inline
   1393 Mat_<_Tp> Mat_<_Tp>::diag(int d) const
   1394 {
   1395     return Mat_(Mat::diag(d));
   1396 }
   1397 
   1398 template<typename _Tp> inline
   1399 Mat_<_Tp> Mat_<_Tp>::clone() const
   1400 {
   1401     return Mat_(Mat::clone());
   1402 }
   1403 
   1404 template<typename _Tp> inline
   1405 size_t Mat_<_Tp>::elemSize() const
   1406 {
   1407     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
   1408     return sizeof(_Tp);
   1409 }
   1410 
   1411 template<typename _Tp> inline
   1412 size_t Mat_<_Tp>::elemSize1() const
   1413 {
   1414     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels );
   1415     return sizeof(_Tp) / DataType<_Tp>::channels;
   1416 }
   1417 
   1418 template<typename _Tp> inline
   1419 int Mat_<_Tp>::type() const
   1420 {
   1421     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
   1422     return DataType<_Tp>::type;
   1423 }
   1424 
   1425 template<typename _Tp> inline
   1426 int Mat_<_Tp>::depth() const
   1427 {
   1428     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
   1429     return DataType<_Tp>::depth;
   1430 }
   1431 
   1432 template<typename _Tp> inline
   1433 int Mat_<_Tp>::channels() const
   1434 {
   1435     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
   1436     return DataType<_Tp>::channels;
   1437 }
   1438 
   1439 template<typename _Tp> inline
   1440 size_t Mat_<_Tp>::stepT(int i) const
   1441 {
   1442     return step.p[i] / elemSize();
   1443 }
   1444 
   1445 template<typename _Tp> inline
   1446 size_t Mat_<_Tp>::step1(int i) const
   1447 {
   1448     return step.p[i] / elemSize1();
   1449 }
   1450 
   1451 template<typename _Tp> inline
   1452 Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
   1453 {
   1454     return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));
   1455 }
   1456 
   1457 template<typename _Tp> inline
   1458 Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
   1459 {
   1460     return Mat_<_Tp>(*this, _rowRange, _colRange);
   1461 }
   1462 
   1463 template<typename _Tp> inline
   1464 Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
   1465 {
   1466     return Mat_<_Tp>(*this, roi);
   1467 }
   1468 
   1469 template<typename _Tp> inline
   1470 Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
   1471 {
   1472     return Mat_<_Tp>(*this, ranges);
   1473 }
   1474 
   1475 template<typename _Tp> inline
   1476 _Tp* Mat_<_Tp>::operator [](int y)
   1477 {
   1478     CV_DbgAssert( 0 <= y && y < rows );
   1479     return (_Tp*)(data + y*step.p[0]);
   1480 }
   1481 
   1482 template<typename _Tp> inline
   1483 const _Tp* Mat_<_Tp>::operator [](int y) const
   1484 {
   1485     CV_DbgAssert( 0 <= y && y < rows );
   1486     return (const _Tp*)(data + y*step.p[0]);
   1487 }
   1488 
   1489 template<typename _Tp> inline
   1490 _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
   1491 {
   1492     CV_DbgAssert( dims <= 2 && data &&
   1493                   (unsigned)i0 < (unsigned)size.p[0] &&
   1494                   (unsigned)i1 < (unsigned)size.p[1] &&
   1495                   type() == DataType<_Tp>::type );
   1496     return ((_Tp*)(data + step.p[0] * i0))[i1];
   1497 }
   1498 
   1499 template<typename _Tp> inline
   1500 const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
   1501 {
   1502     CV_DbgAssert( dims <= 2 && data &&
   1503                   (unsigned)i0 < (unsigned)size.p[0] &&
   1504                   (unsigned)i1 < (unsigned)size.p[1] &&
   1505                   type() == DataType<_Tp>::type );
   1506     return ((const _Tp*)(data + step.p[0] * i0))[i1];
   1507 }
   1508 
   1509 template<typename _Tp> inline
   1510 _Tp& Mat_<_Tp>::operator ()(Point pt)
   1511 {
   1512     CV_DbgAssert( dims <= 2 && data &&
   1513                   (unsigned)pt.y < (unsigned)size.p[0] &&
   1514                   (unsigned)pt.x < (unsigned)size.p[1] &&
   1515                   type() == DataType<_Tp>::type );
   1516     return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
   1517 }
   1518 
   1519 template<typename _Tp> inline
   1520 const _Tp& Mat_<_Tp>::operator ()(Point pt) const
   1521 {
   1522     CV_DbgAssert( dims <= 2 && data &&
   1523                   (unsigned)pt.y < (unsigned)size.p[0] &&
   1524                   (unsigned)pt.x < (unsigned)size.p[1] &&
   1525                  type() == DataType<_Tp>::type );
   1526     return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
   1527 }
   1528 
   1529 template<typename _Tp> inline
   1530 _Tp& Mat_<_Tp>::operator ()(const int* idx)
   1531 {
   1532     return Mat::at<_Tp>(idx);
   1533 }
   1534 
   1535 template<typename _Tp> inline
   1536 const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
   1537 {
   1538     return Mat::at<_Tp>(idx);
   1539 }
   1540 
   1541 template<typename _Tp> template<int n> inline
   1542 _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
   1543 {
   1544     return Mat::at<_Tp>(idx);
   1545 }
   1546 
   1547 template<typename _Tp> template<int n> inline
   1548 const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
   1549 {
   1550     return Mat::at<_Tp>(idx);
   1551 }
   1552 
   1553 template<typename _Tp> inline
   1554 _Tp& Mat_<_Tp>::operator ()(int i0)
   1555 {
   1556     return this->at<_Tp>(i0);
   1557 }
   1558 
   1559 template<typename _Tp> inline
   1560 const _Tp& Mat_<_Tp>::operator ()(int i0) const
   1561 {
   1562     return this->at<_Tp>(i0);
   1563 }
   1564 
   1565 template<typename _Tp> inline
   1566 _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
   1567 {
   1568     return this->at<_Tp>(i0, i1, i2);
   1569 }
   1570 
   1571 template<typename _Tp> inline
   1572 const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
   1573 {
   1574     return this->at<_Tp>(i0, i1, i2);
   1575 }
   1576 
   1577 template<typename _Tp> inline
   1578 Mat_<_Tp>::operator std::vector<_Tp>() const
   1579 {
   1580     std::vector<_Tp> v;
   1581     copyTo(v);
   1582     return v;
   1583 }
   1584 
   1585 template<typename _Tp> template<int n> inline
   1586 Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
   1587 {
   1588     CV_Assert(n % DataType<_Tp>::channels == 0);
   1589     return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
   1590 }
   1591 
   1592 template<typename _Tp> template<int m, int n> inline
   1593 Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
   1594 {
   1595     CV_Assert(n % DataType<_Tp>::channels == 0);
   1596 
   1597     Matx<typename DataType<_Tp>::channel_type, m, n> res = this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
   1598     return res;
   1599 }
   1600 
   1601 template<typename _Tp> inline
   1602 MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
   1603 {
   1604     return Mat::begin<_Tp>();
   1605 }
   1606 
   1607 template<typename _Tp> inline
   1608 MatConstIterator_<_Tp> Mat_<_Tp>::end() const
   1609 {
   1610     return Mat::end<_Tp>();
   1611 }
   1612 
   1613 template<typename _Tp> inline
   1614 MatIterator_<_Tp> Mat_<_Tp>::begin()
   1615 {
   1616     return Mat::begin<_Tp>();
   1617 }
   1618 
   1619 template<typename _Tp> inline
   1620 MatIterator_<_Tp> Mat_<_Tp>::end()
   1621 {
   1622     return Mat::end<_Tp>();
   1623 }
   1624 
   1625 template<typename _Tp> template<typename Functor> inline
   1626 void Mat_<_Tp>::forEach(const Functor& operation) {
   1627     Mat::forEach<_Tp, Functor>(operation);
   1628 }
   1629 
   1630 template<typename _Tp> template<typename Functor> inline
   1631 void Mat_<_Tp>::forEach(const Functor& operation) const {
   1632     Mat::forEach<_Tp, Functor>(operation);
   1633 }
   1634 
   1635 ///////////////////////////// SparseMat /////////////////////////////
   1636 
   1637 inline
   1638 SparseMat::SparseMat()
   1639     : flags(MAGIC_VAL), hdr(0)
   1640 {}
   1641 
   1642 inline
   1643 SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
   1644     : flags(MAGIC_VAL), hdr(0)
   1645 {
   1646     create(_dims, _sizes, _type);
   1647 }
   1648 
   1649 inline
   1650 SparseMat::SparseMat(const SparseMat& m)
   1651     : flags(m.flags), hdr(m.hdr)
   1652 {
   1653     addref();
   1654 }
   1655 
   1656 inline
   1657 SparseMat::~SparseMat()
   1658 {
   1659     release();
   1660 }
   1661 
   1662 inline
   1663 SparseMat& SparseMat::operator = (const SparseMat& m)
   1664 {
   1665     if( this != &m )
   1666     {
   1667         if( m.hdr )
   1668             CV_XADD(&m.hdr->refcount, 1);
   1669         release();
   1670         flags = m.flags;
   1671         hdr = m.hdr;
   1672     }
   1673     return *this;
   1674 }
   1675 
   1676 inline
   1677 SparseMat& SparseMat::operator = (const Mat& m)
   1678 {
   1679     return (*this = SparseMat(m));
   1680 }
   1681 
   1682 inline
   1683 SparseMat SparseMat::clone() const
   1684 {
   1685     SparseMat temp;
   1686     this->copyTo(temp);
   1687     return temp;
   1688 }
   1689 
   1690 inline
   1691 void SparseMat::assignTo( SparseMat& m, int _type ) const
   1692 {
   1693     if( _type < 0 )
   1694         m = *this;
   1695     else
   1696         convertTo(m, _type);
   1697 }
   1698 
   1699 inline
   1700 void SparseMat::addref()
   1701 {
   1702     if( hdr )
   1703         CV_XADD(&hdr->refcount, 1);
   1704 }
   1705 
   1706 inline
   1707 void SparseMat::release()
   1708 {
   1709     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
   1710         delete hdr;
   1711     hdr = 0;
   1712 }
   1713 
   1714 inline
   1715 size_t SparseMat::elemSize() const
   1716 {
   1717     return CV_ELEM_SIZE(flags);
   1718 }
   1719 
   1720 inline
   1721 size_t SparseMat::elemSize1() const
   1722 {
   1723     return CV_ELEM_SIZE1(flags);
   1724 }
   1725 
   1726 inline
   1727 int SparseMat::type() const
   1728 {
   1729     return CV_MAT_TYPE(flags);
   1730 }
   1731 
   1732 inline
   1733 int SparseMat::depth() const
   1734 {
   1735     return CV_MAT_DEPTH(flags);
   1736 }
   1737 
   1738 inline
   1739 int SparseMat::channels() const
   1740 {
   1741     return CV_MAT_CN(flags);
   1742 }
   1743 
   1744 inline
   1745 const int* SparseMat::size() const
   1746 {
   1747     return hdr ? hdr->size : 0;
   1748 }
   1749 
   1750 inline
   1751 int SparseMat::size(int i) const
   1752 {
   1753     if( hdr )
   1754     {
   1755         CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
   1756         return hdr->size[i];
   1757     }
   1758     return 0;
   1759 }
   1760 
   1761 inline
   1762 int SparseMat::dims() const
   1763 {
   1764     return hdr ? hdr->dims : 0;
   1765 }
   1766 
   1767 inline
   1768 size_t SparseMat::nzcount() const
   1769 {
   1770     return hdr ? hdr->nodeCount : 0;
   1771 }
   1772 
   1773 inline
   1774 size_t SparseMat::hash(int i0) const
   1775 {
   1776     return (size_t)i0;
   1777 }
   1778 
   1779 inline
   1780 size_t SparseMat::hash(int i0, int i1) const
   1781 {
   1782     return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
   1783 }
   1784 
   1785 inline
   1786 size_t SparseMat::hash(int i0, int i1, int i2) const
   1787 {
   1788     return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
   1789 }
   1790 
   1791 inline
   1792 size_t SparseMat::hash(const int* idx) const
   1793 {
   1794     size_t h = (unsigned)idx[0];
   1795     if( !hdr )
   1796         return 0;
   1797     int d = hdr->dims;
   1798     for(int i = 1; i < d; i++ )
   1799         h = h * HASH_SCALE + (unsigned)idx[i];
   1800     return h;
   1801 }
   1802 
   1803 template<typename _Tp> inline
   1804 _Tp& SparseMat::ref(int i0, size_t* hashval)
   1805 {
   1806     return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval);
   1807 }
   1808 
   1809 template<typename _Tp> inline
   1810 _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
   1811 {
   1812     return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval);
   1813 }
   1814 
   1815 template<typename _Tp> inline
   1816 _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
   1817 {
   1818     return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval);
   1819 }
   1820 
   1821 template<typename _Tp> inline
   1822 _Tp& SparseMat::ref(const int* idx, size_t* hashval)
   1823 {
   1824     return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval);
   1825 }
   1826 
   1827 template<typename _Tp> inline
   1828 _Tp SparseMat::value(int i0, size_t* hashval) const
   1829 {
   1830     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
   1831     return p ? *p : _Tp();
   1832 }
   1833 
   1834 template<typename _Tp> inline
   1835 _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
   1836 {
   1837     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
   1838     return p ? *p : _Tp();
   1839 }
   1840 
   1841 template<typename _Tp> inline
   1842 _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
   1843 {
   1844     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
   1845     return p ? *p : _Tp();
   1846 }
   1847 
   1848 template<typename _Tp> inline
   1849 _Tp SparseMat::value(const int* idx, size_t* hashval) const
   1850 {
   1851     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
   1852     return p ? *p : _Tp();
   1853 }
   1854 
   1855 template<typename _Tp> inline
   1856 const _Tp* SparseMat::find(int i0, size_t* hashval) const
   1857 {
   1858     return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
   1859 }
   1860 
   1861 template<typename _Tp> inline
   1862 const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
   1863 {
   1864     return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
   1865 }
   1866 
   1867 template<typename _Tp> inline
   1868 const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
   1869 {
   1870     return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
   1871 }
   1872 
   1873 template<typename _Tp> inline
   1874 const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
   1875 {
   1876     return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
   1877 }
   1878 
   1879 template<typename _Tp> inline
   1880 _Tp& SparseMat::value(Node* n)
   1881 {
   1882     return *(_Tp*)((uchar*)n + hdr->valueOffset);
   1883 }
   1884 
   1885 template<typename _Tp> inline
   1886 const _Tp& SparseMat::value(const Node* n) const
   1887 {
   1888     return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
   1889 }
   1890 
   1891 inline
   1892 SparseMat::Node* SparseMat::node(size_t nidx)
   1893 {
   1894     return (Node*)(void*)&hdr->pool[nidx];
   1895 }
   1896 
   1897 inline
   1898 const SparseMat::Node* SparseMat::node(size_t nidx) const
   1899 {
   1900     return (const Node*)(const void*)&hdr->pool[nidx];
   1901 }
   1902 
   1903 inline
   1904 SparseMatIterator SparseMat::begin()
   1905 {
   1906     return SparseMatIterator(this);
   1907 }
   1908 
   1909 inline
   1910 SparseMatConstIterator SparseMat::begin() const
   1911 {
   1912     return SparseMatConstIterator(this);
   1913 }
   1914 
   1915 inline
   1916 SparseMatIterator SparseMat::end()
   1917 {
   1918     SparseMatIterator it(this);
   1919     it.seekEnd();
   1920     return it;
   1921 }
   1922 
   1923 inline
   1924 SparseMatConstIterator SparseMat::end() const
   1925 {
   1926     SparseMatConstIterator it(this);
   1927     it.seekEnd();
   1928     return it;
   1929 }
   1930 
   1931 template<typename _Tp> inline
   1932 SparseMatIterator_<_Tp> SparseMat::begin()
   1933 {
   1934     return SparseMatIterator_<_Tp>(this);
   1935 }
   1936 
   1937 template<typename _Tp> inline
   1938 SparseMatConstIterator_<_Tp> SparseMat::begin() const
   1939 {
   1940     return SparseMatConstIterator_<_Tp>(this);
   1941 }
   1942 
   1943 template<typename _Tp> inline
   1944 SparseMatIterator_<_Tp> SparseMat::end()
   1945 {
   1946     SparseMatIterator_<_Tp> it(this);
   1947     it.seekEnd();
   1948     return it;
   1949 }
   1950 
   1951 template<typename _Tp> inline
   1952 SparseMatConstIterator_<_Tp> SparseMat::end() const
   1953 {
   1954     SparseMatConstIterator_<_Tp> it(this);
   1955     it.seekEnd();
   1956     return it;
   1957 }
   1958 
   1959 
   1960 
   1961 ///////////////////////////// SparseMat_ ////////////////////////////
   1962 
   1963 template<typename _Tp> inline
   1964 SparseMat_<_Tp>::SparseMat_()
   1965 {
   1966     flags = MAGIC_VAL | DataType<_Tp>::type;
   1967 }
   1968 
   1969 template<typename _Tp> inline
   1970 SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
   1971     : SparseMat(_dims, _sizes, DataType<_Tp>::type)
   1972 {}
   1973 
   1974 template<typename _Tp> inline
   1975 SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
   1976 {
   1977     if( m.type() == DataType<_Tp>::type )
   1978         *this = (const SparseMat_<_Tp>&)m;
   1979     else
   1980         m.convertTo(*this, DataType<_Tp>::type);
   1981 }
   1982 
   1983 template<typename _Tp> inline
   1984 SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
   1985 {
   1986     this->flags = m.flags;
   1987     this->hdr = m.hdr;
   1988     if( this->hdr )
   1989         CV_XADD(&this->hdr->refcount, 1);
   1990 }
   1991 
   1992 template<typename _Tp> inline
   1993 SparseMat_<_Tp>::SparseMat_(const Mat& m)
   1994 {
   1995     SparseMat sm(m);
   1996     *this = sm;
   1997 }
   1998 
   1999 template<typename _Tp> inline
   2000 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
   2001 {
   2002     if( this != &m )
   2003     {
   2004         if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
   2005         release();
   2006         flags = m.flags;
   2007         hdr = m.hdr;
   2008     }
   2009     return *this;
   2010 }
   2011 
   2012 template<typename _Tp> inline
   2013 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m)
   2014 {
   2015     if( m.type() == DataType<_Tp>::type )
   2016         return (*this = (const SparseMat_<_Tp>&)m);
   2017     m.convertTo(*this, DataType<_Tp>::type);
   2018     return *this;
   2019 }
   2020 
   2021 template<typename _Tp> inline
   2022 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
   2023 {
   2024     return (*this = SparseMat(m));
   2025 }
   2026 
   2027 template<typename _Tp> inline
   2028 SparseMat_<_Tp> SparseMat_<_Tp>::clone() const
   2029 {
   2030     SparseMat_<_Tp> m;
   2031     this->copyTo(m);
   2032     return m;
   2033 }
   2034 
   2035 template<typename _Tp> inline
   2036 void SparseMat_<_Tp>::create(int _dims, const int* _sizes)
   2037 {
   2038     SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
   2039 }
   2040 
   2041 template<typename _Tp> inline
   2042 int SparseMat_<_Tp>::type() const
   2043 {
   2044     return DataType<_Tp>::type;
   2045 }
   2046 
   2047 template<typename _Tp> inline
   2048 int SparseMat_<_Tp>::depth() const
   2049 {
   2050     return DataType<_Tp>::depth;
   2051 }
   2052 
   2053 template<typename _Tp> inline
   2054 int SparseMat_<_Tp>::channels() const
   2055 {
   2056     return DataType<_Tp>::channels;
   2057 }
   2058 
   2059 template<typename _Tp> inline
   2060 _Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval)
   2061 {
   2062     return SparseMat::ref<_Tp>(i0, hashval);
   2063 }
   2064 
   2065 template<typename _Tp> inline
   2066 _Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
   2067 {
   2068     return SparseMat::value<_Tp>(i0, hashval);
   2069 }
   2070 
   2071 template<typename _Tp> inline
   2072 _Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
   2073 {
   2074     return SparseMat::ref<_Tp>(i0, i1, hashval);
   2075 }
   2076 
   2077 template<typename _Tp> inline
   2078 _Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
   2079 {
   2080     return SparseMat::value<_Tp>(i0, i1, hashval);
   2081 }
   2082 
   2083 template<typename _Tp> inline
   2084 _Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
   2085 {
   2086     return SparseMat::ref<_Tp>(i0, i1, i2, hashval);
   2087 }
   2088 
   2089 template<typename _Tp> inline
   2090 _Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
   2091 {
   2092     return SparseMat::value<_Tp>(i0, i1, i2, hashval);
   2093 }
   2094 
   2095 template<typename _Tp> inline
   2096 _Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
   2097 {
   2098     return SparseMat::ref<_Tp>(idx, hashval);
   2099 }
   2100 
   2101 template<typename _Tp> inline
   2102 _Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
   2103 {
   2104     return SparseMat::value<_Tp>(idx, hashval);
   2105 }
   2106 
   2107 template<typename _Tp> inline
   2108 SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
   2109 {
   2110     return SparseMatIterator_<_Tp>(this);
   2111 }
   2112 
   2113 template<typename _Tp> inline
   2114 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
   2115 {
   2116     return SparseMatConstIterator_<_Tp>(this);
   2117 }
   2118 
   2119 template<typename _Tp> inline
   2120 SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
   2121 {
   2122     SparseMatIterator_<_Tp> it(this);
   2123     it.seekEnd();
   2124     return it;
   2125 }
   2126 
   2127 template<typename _Tp> inline
   2128 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
   2129 {
   2130     SparseMatConstIterator_<_Tp> it(this);
   2131     it.seekEnd();
   2132     return it;
   2133 }
   2134 
   2135 
   2136 
   2137 ////////////////////////// MatConstIterator /////////////////////////
   2138 
   2139 inline
   2140 MatConstIterator::MatConstIterator()
   2141     : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
   2142 {}
   2143 
   2144 inline
   2145 MatConstIterator::MatConstIterator(const Mat* _m)
   2146     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
   2147 {
   2148     if( m && m->isContinuous() )
   2149     {
   2150         sliceStart = m->ptr();
   2151         sliceEnd = sliceStart + m->total()*elemSize;
   2152     }
   2153     seek((const int*)0);
   2154 }
   2155 
   2156 inline
   2157 MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
   2158     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
   2159 {
   2160     CV_Assert(m && m->dims <= 2);
   2161     if( m->isContinuous() )
   2162     {
   2163         sliceStart = m->ptr();
   2164         sliceEnd = sliceStart + m->total()*elemSize;
   2165     }
   2166     int idx[] = {_row, _col};
   2167     seek(idx);
   2168 }
   2169 
   2170 inline
   2171 MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
   2172     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
   2173 {
   2174     CV_Assert(m && m->dims <= 2);
   2175     if( m->isContinuous() )
   2176     {
   2177         sliceStart = m->ptr();
   2178         sliceEnd = sliceStart + m->total()*elemSize;
   2179     }
   2180     int idx[] = {_pt.y, _pt.x};
   2181     seek(idx);
   2182 }
   2183 
   2184 inline
   2185 MatConstIterator::MatConstIterator(const MatConstIterator& it)
   2186     : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
   2187 {}
   2188 
   2189 inline
   2190 MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
   2191 {
   2192     m = it.m; elemSize = it.elemSize; ptr = it.ptr;
   2193     sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
   2194     return *this;
   2195 }
   2196 
   2197 inline
   2198 const uchar* MatConstIterator::operator *() const
   2199 {
   2200     return ptr;
   2201 }
   2202 
   2203 inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
   2204 {
   2205     if( !m || ofs == 0 )
   2206         return *this;
   2207     ptrdiff_t ofsb = ofs*elemSize;
   2208     ptr += ofsb;
   2209     if( ptr < sliceStart || sliceEnd <= ptr )
   2210     {
   2211         ptr -= ofsb;
   2212         seek(ofs, true);
   2213     }
   2214     return *this;
   2215 }
   2216 
   2217 inline
   2218 MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
   2219 {
   2220     return (*this += -ofs);
   2221 }
   2222 
   2223 inline
   2224 MatConstIterator& MatConstIterator::operator --()
   2225 {
   2226     if( m && (ptr -= elemSize) < sliceStart )
   2227     {
   2228         ptr += elemSize;
   2229         seek(-1, true);
   2230     }
   2231     return *this;
   2232 }
   2233 
   2234 inline
   2235 MatConstIterator MatConstIterator::operator --(int)
   2236 {
   2237     MatConstIterator b = *this;
   2238     *this += -1;
   2239     return b;
   2240 }
   2241 
   2242 inline
   2243 MatConstIterator& MatConstIterator::operator ++()
   2244 {
   2245     if( m && (ptr += elemSize) >= sliceEnd )
   2246     {
   2247         ptr -= elemSize;
   2248         seek(1, true);
   2249     }
   2250     return *this;
   2251 }
   2252 
   2253 inline MatConstIterator MatConstIterator::operator ++(int)
   2254 {
   2255     MatConstIterator b = *this;
   2256     *this += 1;
   2257     return b;
   2258 }
   2259 
   2260 
   2261 static inline
   2262 bool operator == (const MatConstIterator& a, const MatConstIterator& b)
   2263 {
   2264     return a.m == b.m && a.ptr == b.ptr;
   2265 }
   2266 
   2267 static inline
   2268 bool operator != (const MatConstIterator& a, const MatConstIterator& b)
   2269 {
   2270     return !(a == b);
   2271 }
   2272 
   2273 static inline
   2274 bool operator < (const MatConstIterator& a, const MatConstIterator& b)
   2275 {
   2276     return a.ptr < b.ptr;
   2277 }
   2278 
   2279 static inline
   2280 bool operator > (const MatConstIterator& a, const MatConstIterator& b)
   2281 {
   2282     return a.ptr > b.ptr;
   2283 }
   2284 
   2285 static inline
   2286 bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
   2287 {
   2288     return a.ptr <= b.ptr;
   2289 }
   2290 
   2291 static inline
   2292 bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
   2293 {
   2294     return a.ptr >= b.ptr;
   2295 }
   2296 
   2297 static inline
   2298 ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
   2299 {
   2300     if( a.m != b.m )
   2301         return ((size_t)(-1) >> 1);
   2302     if( a.sliceEnd == b.sliceEnd )
   2303         return (b.ptr - a.ptr)/b.elemSize;
   2304 
   2305     return b.lpos() - a.lpos();
   2306 }
   2307 
   2308 static inline
   2309 MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
   2310 {
   2311     MatConstIterator b = a;
   2312     return b += ofs;
   2313 }
   2314 
   2315 static inline
   2316 MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
   2317 {
   2318     MatConstIterator b = a;
   2319     return b += ofs;
   2320 }
   2321 
   2322 static inline
   2323 MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
   2324 {
   2325     MatConstIterator b = a;
   2326     return b += -ofs;
   2327 }
   2328 
   2329 
   2330 inline
   2331 const uchar* MatConstIterator::operator [](ptrdiff_t i) const
   2332 {
   2333     return *(*this + i);
   2334 }
   2335 
   2336 
   2337 
   2338 ///////////////////////// MatConstIterator_ /////////////////////////
   2339 
   2340 template<typename _Tp> inline
   2341 MatConstIterator_<_Tp>::MatConstIterator_()
   2342 {}
   2343 
   2344 template<typename _Tp> inline
   2345 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
   2346     : MatConstIterator(_m)
   2347 {}
   2348 
   2349 template<typename _Tp> inline
   2350 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
   2351     : MatConstIterator(_m, _row, _col)
   2352 {}
   2353 
   2354 template<typename _Tp> inline
   2355 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
   2356     : MatConstIterator(_m, _pt)
   2357 {}
   2358 
   2359 template<typename _Tp> inline
   2360 MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
   2361     : MatConstIterator(it)
   2362 {}
   2363 
   2364 template<typename _Tp> inline
   2365 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
   2366 {
   2367     MatConstIterator::operator = (it);
   2368     return *this;
   2369 }
   2370 
   2371 template<typename _Tp> inline
   2372 _Tp MatConstIterator_<_Tp>::operator *() const
   2373 {
   2374     return *(_Tp*)(this->ptr);
   2375 }
   2376 
   2377 template<typename _Tp> inline
   2378 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
   2379 {
   2380     MatConstIterator::operator += (ofs);
   2381     return *this;
   2382 }
   2383 
   2384 template<typename _Tp> inline
   2385 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
   2386 {
   2387     return (*this += -ofs);
   2388 }
   2389 
   2390 template<typename _Tp> inline
   2391 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
   2392 {
   2393     MatConstIterator::operator --();
   2394     return *this;
   2395 }
   2396 
   2397 template<typename _Tp> inline
   2398 MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
   2399 {
   2400     MatConstIterator_ b = *this;
   2401     MatConstIterator::operator --();
   2402     return b;
   2403 }
   2404 
   2405 template<typename _Tp> inline
   2406 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
   2407 {
   2408     MatConstIterator::operator ++();
   2409     return *this;
   2410 }
   2411 
   2412 template<typename _Tp> inline
   2413 MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
   2414 {
   2415     MatConstIterator_ b = *this;
   2416     MatConstIterator::operator ++();
   2417     return b;
   2418 }
   2419 
   2420 
   2421 template<typename _Tp> inline
   2422 Point MatConstIterator_<_Tp>::pos() const
   2423 {
   2424     if( !m )
   2425         return Point();
   2426     CV_DbgAssert( m->dims <= 2 );
   2427     if( m->isContinuous() )
   2428     {
   2429         ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
   2430         int y = (int)(ofs / m->cols);
   2431         int x = (int)(ofs - (ptrdiff_t)y * m->cols);
   2432         return Point(x, y);
   2433     }
   2434     else
   2435     {
   2436         ptrdiff_t ofs = (uchar*)ptr - m->data;
   2437         int y = (int)(ofs / m->step);
   2438         int x = (int)((ofs - y * m->step)/sizeof(_Tp));
   2439         return Point(x, y);
   2440     }
   2441 }
   2442 
   2443 
   2444 template<typename _Tp> static inline
   2445 bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
   2446 {
   2447     return a.m == b.m && a.ptr == b.ptr;
   2448 }
   2449 
   2450 template<typename _Tp> static inline
   2451 bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
   2452 {
   2453     return a.m != b.m || a.ptr != b.ptr;
   2454 }
   2455 
   2456 template<typename _Tp> static inline
   2457 MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
   2458 {
   2459     MatConstIterator t = (const MatConstIterator&)a + ofs;
   2460     return (MatConstIterator_<_Tp>&)t;
   2461 }
   2462 
   2463 template<typename _Tp> static inline
   2464 MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
   2465 {
   2466     MatConstIterator t = (const MatConstIterator&)a + ofs;
   2467     return (MatConstIterator_<_Tp>&)t;
   2468 }
   2469 
   2470 template<typename _Tp> static inline
   2471 MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
   2472 {
   2473     MatConstIterator t = (const MatConstIterator&)a - ofs;
   2474     return (MatConstIterator_<_Tp>&)t;
   2475 }
   2476 
   2477 template<typename _Tp> inline
   2478 _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
   2479 {
   2480     return *(_Tp*)MatConstIterator::operator [](i);
   2481 }
   2482 
   2483 
   2484 
   2485 //////////////////////////// MatIterator_ ///////////////////////////
   2486 
   2487 template<typename _Tp> inline
   2488 MatIterator_<_Tp>::MatIterator_()
   2489     : MatConstIterator_<_Tp>()
   2490 {}
   2491 
   2492 template<typename _Tp> inline
   2493 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
   2494     : MatConstIterator_<_Tp>(_m)
   2495 {}
   2496 
   2497 template<typename _Tp> inline
   2498 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
   2499     : MatConstIterator_<_Tp>(_m, _row, _col)
   2500 {}
   2501 
   2502 template<typename _Tp> inline
   2503 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt)
   2504     : MatConstIterator_<_Tp>(_m, _pt)
   2505 {}
   2506 
   2507 template<typename _Tp> inline
   2508 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx)
   2509     : MatConstIterator_<_Tp>(_m, _idx)
   2510 {}
   2511 
   2512 template<typename _Tp> inline
   2513 MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
   2514     : MatConstIterator_<_Tp>(it)
   2515 {}
   2516 
   2517 template<typename _Tp> inline
   2518 MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
   2519 {
   2520     MatConstIterator::operator = (it);
   2521     return *this;
   2522 }
   2523 
   2524 template<typename _Tp> inline
   2525 _Tp& MatIterator_<_Tp>::operator *() const
   2526 {
   2527     return *(_Tp*)(this->ptr);
   2528 }
   2529 
   2530 template<typename _Tp> inline
   2531 MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
   2532 {
   2533     MatConstIterator::operator += (ofs);
   2534     return *this;
   2535 }
   2536 
   2537 template<typename _Tp> inline
   2538 MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
   2539 {
   2540     MatConstIterator::operator += (-ofs);
   2541     return *this;
   2542 }
   2543 
   2544 template<typename _Tp> inline
   2545 MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
   2546 {
   2547     MatConstIterator::operator --();
   2548     return *this;
   2549 }
   2550 
   2551 template<typename _Tp> inline
   2552 MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
   2553 {
   2554     MatIterator_ b = *this;
   2555     MatConstIterator::operator --();
   2556     return b;
   2557 }
   2558 
   2559 template<typename _Tp> inline
   2560 MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
   2561 {
   2562     MatConstIterator::operator ++();
   2563     return *this;
   2564 }
   2565 
   2566 template<typename _Tp> inline
   2567 MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
   2568 {
   2569     MatIterator_ b = *this;
   2570     MatConstIterator::operator ++();
   2571     return b;
   2572 }
   2573 
   2574 template<typename _Tp> inline
   2575 _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
   2576 {
   2577     return *(*this + i);
   2578 }
   2579 
   2580 
   2581 template<typename _Tp> static inline
   2582 bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
   2583 {
   2584     return a.m == b.m && a.ptr == b.ptr;
   2585 }
   2586 
   2587 template<typename _Tp> static inline
   2588 bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
   2589 {
   2590     return a.m != b.m || a.ptr != b.ptr;
   2591 }
   2592 
   2593 template<typename _Tp> static inline
   2594 MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
   2595 {
   2596     MatConstIterator t = (const MatConstIterator&)a + ofs;
   2597     return (MatIterator_<_Tp>&)t;
   2598 }
   2599 
   2600 template<typename _Tp> static inline
   2601 MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
   2602 {
   2603     MatConstIterator t = (const MatConstIterator&)a + ofs;
   2604     return (MatIterator_<_Tp>&)t;
   2605 }
   2606 
   2607 template<typename _Tp> static inline
   2608 MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
   2609 {
   2610     MatConstIterator t = (const MatConstIterator&)a - ofs;
   2611     return (MatIterator_<_Tp>&)t;
   2612 }
   2613 
   2614 
   2615 
   2616 /////////////////////// SparseMatConstIterator //////////////////////
   2617 
   2618 inline
   2619 SparseMatConstIterator::SparseMatConstIterator()
   2620     : m(0), hashidx(0), ptr(0)
   2621 {}
   2622 
   2623 inline
   2624 SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
   2625     : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
   2626 {}
   2627 
   2628 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
   2629 {
   2630     if( this != &it )
   2631     {
   2632         m = it.m;
   2633         hashidx = it.hashidx;
   2634         ptr = it.ptr;
   2635     }
   2636     return *this;
   2637 }
   2638 
   2639 template<typename _Tp> inline
   2640 const _Tp& SparseMatConstIterator::value() const
   2641 {
   2642     return *(const _Tp*)ptr;
   2643 }
   2644 
   2645 inline
   2646 const SparseMat::Node* SparseMatConstIterator::node() const
   2647 {
   2648     return (ptr && m && m->hdr) ? (const SparseMat::Node*)(const void*)(ptr - m->hdr->valueOffset) : 0;
   2649 }
   2650 
   2651 inline
   2652 SparseMatConstIterator SparseMatConstIterator::operator ++(int)
   2653 {
   2654     SparseMatConstIterator it = *this;
   2655     ++*this;
   2656     return it;
   2657 }
   2658 
   2659 inline
   2660 void SparseMatConstIterator::seekEnd()
   2661 {
   2662     if( m && m->hdr )
   2663     {
   2664         hashidx = m->hdr->hashtab.size();
   2665         ptr = 0;
   2666     }
   2667 }
   2668 
   2669 
   2670 static inline
   2671 bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
   2672 {
   2673     return it1.m == it2.m && it1.ptr == it2.ptr;
   2674 }
   2675 
   2676 static inline
   2677 bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
   2678 {
   2679     return !(it1 == it2);
   2680 }
   2681 
   2682 
   2683 
   2684 ///////////////////////// SparseMatIterator /////////////////////////
   2685 
   2686 inline
   2687 SparseMatIterator::SparseMatIterator()
   2688 {}
   2689 
   2690 inline
   2691 SparseMatIterator::SparseMatIterator(SparseMat* _m)
   2692     : SparseMatConstIterator(_m)
   2693 {}
   2694 
   2695 inline
   2696 SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
   2697     : SparseMatConstIterator(it)
   2698 {}
   2699 
   2700 inline
   2701 SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
   2702 {
   2703     (SparseMatConstIterator&)*this = it;
   2704     return *this;
   2705 }
   2706 
   2707 template<typename _Tp> inline
   2708 _Tp& SparseMatIterator::value() const
   2709 {
   2710     return *(_Tp*)ptr;
   2711 }
   2712 
   2713 inline
   2714 SparseMat::Node* SparseMatIterator::node() const
   2715 {
   2716     return (SparseMat::Node*)SparseMatConstIterator::node();
   2717 }
   2718 
   2719 inline
   2720 SparseMatIterator& SparseMatIterator::operator ++()
   2721 {
   2722     SparseMatConstIterator::operator ++();
   2723     return *this;
   2724 }
   2725 
   2726 inline
   2727 SparseMatIterator SparseMatIterator::operator ++(int)
   2728 {
   2729     SparseMatIterator it = *this;
   2730     ++*this;
   2731     return it;
   2732 }
   2733 
   2734 
   2735 
   2736 ////////////////////// SparseMatConstIterator_ //////////////////////
   2737 
   2738 template<typename _Tp> inline
   2739 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
   2740 {}
   2741 
   2742 template<typename _Tp> inline
   2743 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
   2744     : SparseMatConstIterator(_m)
   2745 {}
   2746 
   2747 template<typename _Tp> inline
   2748 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
   2749     : SparseMatConstIterator(_m)
   2750 {
   2751     CV_Assert( _m->type() == DataType<_Tp>::type );
   2752 }
   2753 
   2754 template<typename _Tp> inline
   2755 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
   2756     : SparseMatConstIterator(it)
   2757 {}
   2758 
   2759 template<typename _Tp> inline
   2760 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
   2761 {
   2762     return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
   2763          (*reinterpret_cast<SparseMatConstIterator*>(this) =
   2764            reinterpret_cast<const SparseMatConstIterator&>(it));
   2765 }
   2766 
   2767 template<typename _Tp> inline
   2768 const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
   2769 {
   2770     return *(const _Tp*)this->ptr;
   2771 }
   2772 
   2773 template<typename _Tp> inline
   2774 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
   2775 {
   2776     SparseMatConstIterator::operator ++();
   2777     return *this;
   2778 }
   2779 
   2780 template<typename _Tp> inline
   2781 SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
   2782 {
   2783     SparseMatConstIterator_<_Tp> it = *this;
   2784     SparseMatConstIterator::operator ++();
   2785     return it;
   2786 }
   2787 
   2788 
   2789 
   2790 ///////////////////////// SparseMatIterator_ ////////////////////////
   2791 
   2792 template<typename _Tp> inline
   2793 SparseMatIterator_<_Tp>::SparseMatIterator_()
   2794 {}
   2795 
   2796 template<typename _Tp> inline
   2797 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
   2798     : SparseMatConstIterator_<_Tp>(_m)
   2799 {}
   2800 
   2801 template<typename _Tp> inline
   2802 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
   2803     : SparseMatConstIterator_<_Tp>(_m)
   2804 {}
   2805 
   2806 template<typename _Tp> inline
   2807 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
   2808     : SparseMatConstIterator_<_Tp>(it)
   2809 {}
   2810 
   2811 template<typename _Tp> inline
   2812 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
   2813 {
   2814     return reinterpret_cast<SparseMatIterator_<_Tp>&>
   2815          (*reinterpret_cast<SparseMatConstIterator*>(this) =
   2816            reinterpret_cast<const SparseMatConstIterator&>(it));
   2817 }
   2818 
   2819 template<typename _Tp> inline
   2820 _Tp& SparseMatIterator_<_Tp>::operator *() const
   2821 {
   2822     return *(_Tp*)this->ptr;
   2823 }
   2824 
   2825 template<typename _Tp> inline
   2826 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
   2827 {
   2828     SparseMatConstIterator::operator ++();
   2829     return *this;
   2830 }
   2831 
   2832 template<typename _Tp> inline
   2833 SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
   2834 {
   2835     SparseMatIterator_<_Tp> it = *this;
   2836     SparseMatConstIterator::operator ++();
   2837     return it;
   2838 }
   2839 
   2840 
   2841 
   2842 //////////////////////// MatCommaInitializer_ ///////////////////////
   2843 
   2844 template<typename _Tp> inline
   2845 MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
   2846     : it(_m)
   2847 {}
   2848 
   2849 template<typename _Tp> template<typename T2> inline
   2850 MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v)
   2851 {
   2852     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
   2853     *this->it = _Tp(v);
   2854     ++this->it;
   2855     return *this;
   2856 }
   2857 
   2858 template<typename _Tp> inline
   2859 MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
   2860 {
   2861     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
   2862     return Mat_<_Tp>(*this->it.m);
   2863 }
   2864 
   2865 
   2866 template<typename _Tp, typename T2> static inline
   2867 MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
   2868 {
   2869     MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
   2870     return (commaInitializer, val);
   2871 }
   2872 
   2873 
   2874 
   2875 ///////////////////////// Matrix Expressions ////////////////////////
   2876 
   2877 inline
   2878 Mat& Mat::operator = (const MatExpr& e)
   2879 {
   2880     e.op->assign(e, *this);
   2881     return *this;
   2882 }
   2883 
   2884 template<typename _Tp> inline
   2885 Mat_<_Tp>::Mat_(const MatExpr& e)
   2886 {
   2887     e.op->assign(e, *this, DataType<_Tp>::type);
   2888 }
   2889 
   2890 template<typename _Tp> inline
   2891 Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
   2892 {
   2893     e.op->assign(e, *this, DataType<_Tp>::type);
   2894     return *this;
   2895 }
   2896 
   2897 template<typename _Tp> inline
   2898 MatExpr Mat_<_Tp>::zeros(int rows, int cols)
   2899 {
   2900     return Mat::zeros(rows, cols, DataType<_Tp>::type);
   2901 }
   2902 
   2903 template<typename _Tp> inline
   2904 MatExpr Mat_<_Tp>::zeros(Size sz)
   2905 {
   2906     return Mat::zeros(sz, DataType<_Tp>::type);
   2907 }
   2908 
   2909 template<typename _Tp> inline
   2910 MatExpr Mat_<_Tp>::ones(int rows, int cols)
   2911 {
   2912     return Mat::ones(rows, cols, DataType<_Tp>::type);
   2913 }
   2914 
   2915 template<typename _Tp> inline
   2916 MatExpr Mat_<_Tp>::ones(Size sz)
   2917 {
   2918     return Mat::ones(sz, DataType<_Tp>::type);
   2919 }
   2920 
   2921 template<typename _Tp> inline
   2922 MatExpr Mat_<_Tp>::eye(int rows, int cols)
   2923 {
   2924     return Mat::eye(rows, cols, DataType<_Tp>::type);
   2925 }
   2926 
   2927 template<typename _Tp> inline
   2928 MatExpr Mat_<_Tp>::eye(Size sz)
   2929 {
   2930     return Mat::eye(sz, DataType<_Tp>::type);
   2931 }
   2932 
   2933 inline
   2934 MatExpr::MatExpr()
   2935     : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
   2936 {}
   2937 
   2938 inline
   2939 MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b,
   2940                  const Mat& _c, double _alpha, double _beta, const Scalar& _s)
   2941     : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s)
   2942 {}
   2943 
   2944 inline
   2945 MatExpr::operator Mat() const
   2946 {
   2947     Mat m;
   2948     op->assign(*this, m);
   2949     return m;
   2950 }
   2951 
   2952 template<typename _Tp> inline
   2953 MatExpr::operator Mat_<_Tp>() const
   2954 {
   2955     Mat_<_Tp> m;
   2956     op->assign(*this, m, DataType<_Tp>::type);
   2957     return m;
   2958 }
   2959 
   2960 
   2961 template<typename _Tp> static inline
   2962 MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
   2963 {
   2964     return cv::min((const Mat&)a, (const Mat&)b);
   2965 }
   2966 
   2967 template<typename _Tp> static inline
   2968 MatExpr min(const Mat_<_Tp>& a, double s)
   2969 {
   2970     return cv::min((const Mat&)a, s);
   2971 }
   2972 
   2973 template<typename _Tp> static inline
   2974 MatExpr min(double s, const Mat_<_Tp>& a)
   2975 {
   2976     return cv::min((const Mat&)a, s);
   2977 }
   2978 
   2979 template<typename _Tp> static inline
   2980 MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
   2981 {
   2982     return cv::max((const Mat&)a, (const Mat&)b);
   2983 }
   2984 
   2985 template<typename _Tp> static inline
   2986 MatExpr max(const Mat_<_Tp>& a, double s)
   2987 {
   2988     return cv::max((const Mat&)a, s);
   2989 }
   2990 
   2991 template<typename _Tp> static inline
   2992 MatExpr max(double s, const Mat_<_Tp>& a)
   2993 {
   2994     return cv::max((const Mat&)a, s);
   2995 }
   2996 
   2997 template<typename _Tp> static inline
   2998 MatExpr abs(const Mat_<_Tp>& m)
   2999 {
   3000     return cv::abs((const Mat&)m);
   3001 }
   3002 
   3003 
   3004 static inline
   3005 Mat& operator += (Mat& a, const MatExpr& b)
   3006 {
   3007     b.op->augAssignAdd(b, a);
   3008     return a;
   3009 }
   3010 
   3011 static inline
   3012 const Mat& operator += (const Mat& a, const MatExpr& b)
   3013 {
   3014     b.op->augAssignAdd(b, (Mat&)a);
   3015     return a;
   3016 }
   3017 
   3018 template<typename _Tp> static inline
   3019 Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b)
   3020 {
   3021     b.op->augAssignAdd(b, a);
   3022     return a;
   3023 }
   3024 
   3025 template<typename _Tp> static inline
   3026 const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
   3027 {
   3028     b.op->augAssignAdd(b, (Mat&)a);
   3029     return a;
   3030 }
   3031 
   3032 static inline
   3033 Mat& operator -= (Mat& a, const MatExpr& b)
   3034 {
   3035     b.op->augAssignSubtract(b, a);
   3036     return a;
   3037 }
   3038 
   3039 static inline
   3040 const Mat& operator -= (const Mat& a, const MatExpr& b)
   3041 {
   3042     b.op->augAssignSubtract(b, (Mat&)a);
   3043     return a;
   3044 }
   3045 
   3046 template<typename _Tp> static inline
   3047 Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b)
   3048 {
   3049     b.op->augAssignSubtract(b, a);
   3050     return a;
   3051 }
   3052 
   3053 template<typename _Tp> static inline
   3054 const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
   3055 {
   3056     b.op->augAssignSubtract(b, (Mat&)a);
   3057     return a;
   3058 }
   3059 
   3060 static inline
   3061 Mat& operator *= (Mat& a, const MatExpr& b)
   3062 {
   3063     b.op->augAssignMultiply(b, a);
   3064     return a;
   3065 }
   3066 
   3067 static inline
   3068 const Mat& operator *= (const Mat& a, const MatExpr& b)
   3069 {
   3070     b.op->augAssignMultiply(b, (Mat&)a);
   3071     return a;
   3072 }
   3073 
   3074 template<typename _Tp> static inline
   3075 Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b)
   3076 {
   3077     b.op->augAssignMultiply(b, a);
   3078     return a;
   3079 }
   3080 
   3081 template<typename _Tp> static inline
   3082 const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
   3083 {
   3084     b.op->augAssignMultiply(b, (Mat&)a);
   3085     return a;
   3086 }
   3087 
   3088 static inline
   3089 Mat& operator /= (Mat& a, const MatExpr& b)
   3090 {
   3091     b.op->augAssignDivide(b, a);
   3092     return a;
   3093 }
   3094 
   3095 static inline
   3096 const Mat& operator /= (const Mat& a, const MatExpr& b)
   3097 {
   3098     b.op->augAssignDivide(b, (Mat&)a);
   3099     return a;
   3100 }
   3101 
   3102 template<typename _Tp> static inline
   3103 Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b)
   3104 {
   3105     b.op->augAssignDivide(b, a);
   3106     return a;
   3107 }
   3108 
   3109 template<typename _Tp> static inline
   3110 const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
   3111 {
   3112     b.op->augAssignDivide(b, (Mat&)a);
   3113     return a;
   3114 }
   3115 
   3116 
   3117 //////////////////////////////// UMat ////////////////////////////////
   3118 
   3119 inline
   3120 UMat::UMat(UMatUsageFlags _usageFlags)
   3121 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3122 {}
   3123 
   3124 inline
   3125 UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
   3126 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3127 {
   3128     create(_rows, _cols, _type);
   3129 }
   3130 
   3131 inline
   3132 UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
   3133 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3134 {
   3135     create(_rows, _cols, _type);
   3136     *this = _s;
   3137 }
   3138 
   3139 inline
   3140 UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
   3141 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3142 {
   3143     create( _sz.height, _sz.width, _type );
   3144 }
   3145 
   3146 inline
   3147 UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
   3148 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3149 {
   3150     create(_sz.height, _sz.width, _type);
   3151     *this = _s;
   3152 }
   3153 
   3154 inline
   3155 UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
   3156 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3157 {
   3158     create(_dims, _sz, _type);
   3159 }
   3160 
   3161 inline
   3162 UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
   3163 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
   3164 {
   3165     create(_dims, _sz, _type);
   3166     *this = _s;
   3167 }
   3168 
   3169 inline
   3170 UMat::UMat(const UMat& m)
   3171 : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
   3172   usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
   3173 {
   3174     addref();
   3175     if( m.dims <= 2 )
   3176     {
   3177         step[0] = m.step[0]; step[1] = m.step[1];
   3178     }
   3179     else
   3180     {
   3181         dims = 0;
   3182         copySize(m);
   3183     }
   3184 }
   3185 
   3186 
   3187 template<typename _Tp> inline
   3188 UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
   3189 : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
   3190 cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
   3191 {
   3192     if(vec.empty())
   3193         return;
   3194     if( !copyData )
   3195     {
   3196         // !!!TODO!!!
   3197         CV_Error(Error::StsNotImplemented, "");
   3198     }
   3199     else
   3200         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
   3201 }
   3202 
   3203 
   3204 inline
   3205 UMat& UMat::operator = (const UMat& m)
   3206 {
   3207     if( this != &m )
   3208     {
   3209         const_cast<UMat&>(m).addref();
   3210         release();
   3211         flags = m.flags;
   3212         if( dims <= 2 && m.dims <= 2 )
   3213         {
   3214             dims = m.dims;
   3215             rows = m.rows;
   3216             cols = m.cols;
   3217             step[0] = m.step[0];
   3218             step[1] = m.step[1];
   3219         }
   3220         else
   3221             copySize(m);
   3222         allocator = m.allocator;
   3223         if (usageFlags == USAGE_DEFAULT)
   3224             usageFlags = m.usageFlags;
   3225         u = m.u;
   3226         offset = m.offset;
   3227     }
   3228     return *this;
   3229 }
   3230 
   3231 inline
   3232 UMat UMat::row(int y) const
   3233 {
   3234     return UMat(*this, Range(y, y + 1), Range::all());
   3235 }
   3236 
   3237 inline
   3238 UMat UMat::col(int x) const
   3239 {
   3240     return UMat(*this, Range::all(), Range(x, x + 1));
   3241 }
   3242 
   3243 inline
   3244 UMat UMat::rowRange(int startrow, int endrow) const
   3245 {
   3246     return UMat(*this, Range(startrow, endrow), Range::all());
   3247 }
   3248 
   3249 inline
   3250 UMat UMat::rowRange(const Range& r) const
   3251 {
   3252     return UMat(*this, r, Range::all());
   3253 }
   3254 
   3255 inline
   3256 UMat UMat::colRange(int startcol, int endcol) const
   3257 {
   3258     return UMat(*this, Range::all(), Range(startcol, endcol));
   3259 }
   3260 
   3261 inline
   3262 UMat UMat::colRange(const Range& r) const
   3263 {
   3264     return UMat(*this, Range::all(), r);
   3265 }
   3266 
   3267 inline
   3268 UMat UMat::clone() const
   3269 {
   3270     UMat m;
   3271     copyTo(m);
   3272     return m;
   3273 }
   3274 
   3275 inline
   3276 void UMat::assignTo( UMat& m, int _type ) const
   3277 {
   3278     if( _type < 0 )
   3279         m = *this;
   3280     else
   3281         convertTo(m, _type);
   3282 }
   3283 
   3284 inline
   3285 void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
   3286 {
   3287     _type &= TYPE_MASK;
   3288     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u )
   3289         return;
   3290     int sz[] = {_rows, _cols};
   3291     create(2, sz, _type, _usageFlags);
   3292 }
   3293 
   3294 inline
   3295 void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
   3296 {
   3297     create(_sz.height, _sz.width, _type, _usageFlags);
   3298 }
   3299 
   3300 inline
   3301 void UMat::addref()
   3302 {
   3303     if( u )
   3304         CV_XADD(&(u->urefcount), 1);
   3305 }
   3306 
   3307 inline void UMat::release()
   3308 {
   3309     if( u && CV_XADD(&(u->urefcount), -1) == 1 )
   3310         deallocate();
   3311     for(int i = 0; i < dims; i++)
   3312         size.p[i] = 0;
   3313     u = 0;
   3314 }
   3315 
   3316 inline
   3317 UMat UMat::operator()( Range _rowRange, Range _colRange ) const
   3318 {
   3319     return UMat(*this, _rowRange, _colRange);
   3320 }
   3321 
   3322 inline
   3323 UMat UMat::operator()( const Rect& roi ) const
   3324 {
   3325     return UMat(*this, roi);
   3326 }
   3327 
   3328 inline
   3329 UMat UMat::operator()(const Range* ranges) const
   3330 {
   3331     return UMat(*this, ranges);
   3332 }
   3333 
   3334 inline
   3335 bool UMat::isContinuous() const
   3336 {
   3337     return (flags & CONTINUOUS_FLAG) != 0;
   3338 }
   3339 
   3340 inline
   3341 bool UMat::isSubmatrix() const
   3342 {
   3343     return (flags & SUBMATRIX_FLAG) != 0;
   3344 }
   3345 
   3346 inline
   3347 size_t UMat::elemSize() const
   3348 {
   3349     return dims > 0 ? step.p[dims - 1] : 0;
   3350 }
   3351 
   3352 inline
   3353 size_t UMat::elemSize1() const
   3354 {
   3355     return CV_ELEM_SIZE1(flags);
   3356 }
   3357 
   3358 inline
   3359 int UMat::type() const
   3360 {
   3361     return CV_MAT_TYPE(flags);
   3362 }
   3363 
   3364 inline
   3365 int UMat::depth() const
   3366 {
   3367     return CV_MAT_DEPTH(flags);
   3368 }
   3369 
   3370 inline
   3371 int UMat::channels() const
   3372 {
   3373     return CV_MAT_CN(flags);
   3374 }
   3375 
   3376 inline
   3377 size_t UMat::step1(int i) const
   3378 {
   3379     return step.p[i] / elemSize1();
   3380 }
   3381 
   3382 inline
   3383 bool UMat::empty() const
   3384 {
   3385     return u == 0 || total() == 0;
   3386 }
   3387 
   3388 inline
   3389 size_t UMat::total() const
   3390 {
   3391     if( dims <= 2 )
   3392         return (size_t)rows * cols;
   3393     size_t p = 1;
   3394     for( int i = 0; i < dims; i++ )
   3395         p *= size[i];
   3396     return p;
   3397 }
   3398 
   3399 inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
   3400 inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
   3401 inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }
   3402 inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; }
   3403 inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; }
   3404 inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; }
   3405 
   3406 inline void UMatData::markDeviceMemMapped(bool flag)
   3407 {
   3408   if(flag)
   3409     flags |= DEVICE_MEM_MAPPED;
   3410   else
   3411     flags &= ~DEVICE_MEM_MAPPED;
   3412 }
   3413 
   3414 inline void UMatData::markHostCopyObsolete(bool flag)
   3415 {
   3416     if(flag)
   3417         flags |= HOST_COPY_OBSOLETE;
   3418     else
   3419         flags &= ~HOST_COPY_OBSOLETE;
   3420 }
   3421 inline void UMatData::markDeviceCopyObsolete(bool flag)
   3422 {
   3423     if(flag)
   3424         flags |= DEVICE_COPY_OBSOLETE;
   3425     else
   3426         flags &= ~DEVICE_COPY_OBSOLETE;
   3427 }
   3428 
   3429 inline UMatDataAutoLock::UMatDataAutoLock(UMatData* _u) : u(_u) { u->lock(); }
   3430 inline UMatDataAutoLock::~UMatDataAutoLock() { u->unlock(); }
   3431 
   3432 //! @endcond
   3433 
   3434 } //cv
   3435 
   3436 #endif
   3437