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 
init(int _flags,const void * _obj)59 inline void _InputArray::init(int _flags, const void* _obj)
60 { flags = _flags; obj = (void*)_obj; }
61 
init(int _flags,const void * _obj,Size _sz)62 inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
63 { flags = _flags; obj = (void*)_obj; sz = _sz; }
64 
getObj() const65 inline void* _InputArray::getObj() const { return obj; }
getFlags() const66 inline int _InputArray::getFlags() const { return flags; }
getSz() const67 inline Size _InputArray::getSz() const { return sz; }
68 
_InputArray()69 inline _InputArray::_InputArray() { init(NONE, 0); }
_InputArray(int _flags,void * _obj)70 inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
_InputArray(const Mat & m)71 inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
_InputArray(const std::vector<Mat> & vec)72 inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
_InputArray(const UMat & m)73 inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
_InputArray(const std::vector<UMat> & vec)74 inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }
75 
76 template<typename _Tp> inline
_InputArray(const std::vector<_Tp> & vec)77 _InputArray::_InputArray(const std::vector<_Tp>& vec)
78 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
79 
80 inline
_InputArray(const std::vector<bool> & vec)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
_InputArray(const std::vector<std::vector<_Tp>> & vec)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
_InputArray(const std::vector<Mat_<_Tp>> & vec)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
_InputArray(const Matx<_Tp,m,n> & mtx)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
_InputArray(const _Tp * vec,int n)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
_InputArray(const Mat_<_Tp> & m)101 _InputArray::_InputArray(const Mat_<_Tp>& m)
102 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_READ, &m); }
103 
_InputArray(const double & val)104 inline _InputArray::_InputArray(const double& val)
105 { init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); }
106 
_InputArray(const MatExpr & expr)107 inline _InputArray::_InputArray(const MatExpr& expr)
108 { init(FIXED_TYPE + FIXED_SIZE + EXPR + ACCESS_READ, &expr); }
109 
_InputArray(const cuda::GpuMat & d_mat)110 inline _InputArray::_InputArray(const cuda::GpuMat& d_mat)
111 { init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
112 
_InputArray(const ogl::Buffer & buf)113 inline _InputArray::_InputArray(const ogl::Buffer& buf)
114 { init(OPENGL_BUFFER + ACCESS_READ, &buf); }
115 
_InputArray(const cuda::HostMem & cuda_mem)116 inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
117 { init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
118 
~_InputArray()119 inline _InputArray::~_InputArray() {}
120 
getMat(int i) const121 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 
isMat() const128 inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }
isUMat() const129 inline bool _InputArray::isUMat() const  { return kind() == _InputArray::UMAT; }
isMatVector() const130 inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
isUMatVector() const131 inline bool _InputArray::isUMatVector() const  { return kind() == _InputArray::STD_VECTOR_UMAT; }
isMatx() const132 inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; }
133 
134 ////////////////////////////////////////////////////////////////////////////////////////
135 
_OutputArray()136 inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
_OutputArray(int _flags,void * _obj)137 inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
_OutputArray(Mat & m)138 inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
_OutputArray(std::vector<Mat> & vec)139 inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
_OutputArray(UMat & m)140 inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
_OutputArray(std::vector<UMat> & vec)141 inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
142 
143 template<typename _Tp> inline
_OutputArray(std::vector<_Tp> & vec)144 _OutputArray::_OutputArray(std::vector<_Tp>& vec)
145 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
146 
147 inline
_OutputArray(std::vector<bool> &)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
_OutputArray(std::vector<std::vector<_Tp>> & vec)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
_OutputArray(std::vector<Mat_<_Tp>> & vec)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
_OutputArray(Mat_<_Tp> & m)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
_OutputArray(Matx<_Tp,m,n> & mtx)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
_OutputArray(_Tp * vec,int n)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
_OutputArray(const std::vector<_Tp> & vec)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
_OutputArray(const std::vector<std::vector<_Tp>> & vec)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
_OutputArray(const std::vector<Mat_<_Tp>> & vec)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
_OutputArray(const Mat_<_Tp> & m)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
_OutputArray(const Matx<_Tp,m,n> & mtx)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
_OutputArray(const _Tp * vec,int n)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 
_OutputArray(cuda::GpuMat & d_mat)195 inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat)
196 { init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
197 
_OutputArray(ogl::Buffer & buf)198 inline _OutputArray::_OutputArray(ogl::Buffer& buf)
199 { init(OPENGL_BUFFER + ACCESS_WRITE, &buf); }
200 
_OutputArray(cuda::HostMem & cuda_mem)201 inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem)
202 { init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
203 
_OutputArray(const Mat & m)204 inline _OutputArray::_OutputArray(const Mat& m)
205 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); }
206 
_OutputArray(const std::vector<Mat> & vec)207 inline _OutputArray::_OutputArray(const std::vector<Mat>& vec)
208 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
209 
_OutputArray(const UMat & m)210 inline _OutputArray::_OutputArray(const UMat& m)
211 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); }
212 
_OutputArray(const std::vector<UMat> & vec)213 inline _OutputArray::_OutputArray(const std::vector<UMat>& vec)
214 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
215 
_OutputArray(const cuda::GpuMat & d_mat)216 inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat)
217 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
218 
_OutputArray(const ogl::Buffer & buf)219 inline _OutputArray::_OutputArray(const ogl::Buffer& buf)
220 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); }
221 
_OutputArray(const cuda::HostMem & cuda_mem)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 
_InputOutputArray()227 inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
_InputOutputArray(int _flags,void * _obj)228 inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
_InputOutputArray(Mat & m)229 inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
_InputOutputArray(std::vector<Mat> & vec)230 inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
_InputOutputArray(UMat & m)231 inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
_InputOutputArray(std::vector<UMat> & vec)232 inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); }
233 
234 template<typename _Tp> inline
_InputOutputArray(std::vector<_Tp> & vec)235 _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
236 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
237 
_InputOutputArray(std::vector<bool> &)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
_InputOutputArray(std::vector<std::vector<_Tp>> & vec)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
_InputOutputArray(std::vector<Mat_<_Tp>> & vec)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
_InputOutputArray(Mat_<_Tp> & m)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
_InputOutputArray(Matx<_Tp,m,n> & mtx)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
_InputOutputArray(_Tp * vec,int n)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
_InputOutputArray(const std::vector<_Tp> & vec)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
_InputOutputArray(const std::vector<std::vector<_Tp>> & vec)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
_InputOutputArray(const std::vector<Mat_<_Tp>> & vec)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
_InputOutputArray(const Mat_<_Tp> & m)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
_InputOutputArray(const Matx<_Tp,m,n> & mtx)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
_InputOutputArray(const _Tp * vec,int n)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 
_InputOutputArray(cuda::GpuMat & d_mat)285 inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat)
286 { init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
287 
_InputOutputArray(ogl::Buffer & buf)288 inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf)
289 { init(OPENGL_BUFFER + ACCESS_RW, &buf); }
290 
_InputOutputArray(cuda::HostMem & cuda_mem)291 inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem)
292 { init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
293 
_InputOutputArray(const Mat & m)294 inline _InputOutputArray::_InputOutputArray(const Mat& m)
295 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); }
296 
_InputOutputArray(const std::vector<Mat> & vec)297 inline _InputOutputArray::_InputOutputArray(const std::vector<Mat>& vec)
298 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); }
299 
_InputOutputArray(const UMat & m)300 inline _InputOutputArray::_InputOutputArray(const UMat& m)
301 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); }
302 
_InputOutputArray(const std::vector<UMat> & vec)303 inline _InputOutputArray::_InputOutputArray(const std::vector<UMat>& vec)
304 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); }
305 
_InputOutputArray(const cuda::GpuMat & d_mat)306 inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat)
307 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
308 
_InputOutputArray(const ogl::Buffer & buf)309 inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf)
310 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); }
311 
_InputOutputArray(const cuda::HostMem & cuda_mem)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
Mat()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
Mat(int _rows,int _cols,int _type)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
Mat(int _rows,int _cols,int _type,const Scalar & _s)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
Mat(Size _sz,int _type)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
Mat(Size _sz,int _type,const Scalar & _s)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
Mat(int _dims,const int * _sz,int _type)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
Mat(int _dims,const int * _sz,int _type,const Scalar & _s)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
Mat(const Mat & m)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
Mat(int _rows,int _cols,int _type,void * _data,size_t _step)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
Mat(Size _sz,int _type,void * _data,size_t _step)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
Mat(const std::vector<_Tp> & vec,bool copyData)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
Mat(const Vec<_Tp,n> & vec,bool copyData)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
Mat(const Matx<_Tp,m,n> & M,bool copyData)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
Mat(const Point_<_Tp> & pt,bool copyData)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
Mat(const Point3_<_Tp> & pt,bool copyData)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
Mat(const MatCommaInitializer_<_Tp> & commaInitializer)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
~Mat()552 Mat::~Mat()
553 {
554     release();
555     if( step.p != step.buf )
556         fastFree(step.p);
557 }
558 
559 inline
operator =(const Mat & m)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
row(int y) const589 Mat Mat::row(int y) const
590 {
591     return Mat(*this, Range(y, y + 1), Range::all());
592 }
593 
594 inline
col(int x) const595 Mat Mat::col(int x) const
596 {
597     return Mat(*this, Range::all(), Range(x, x + 1));
598 }
599 
600 inline
rowRange(int startrow,int endrow) const601 Mat Mat::rowRange(int startrow, int endrow) const
602 {
603     return Mat(*this, Range(startrow, endrow), Range::all());
604 }
605 
606 inline
rowRange(const Range & r) const607 Mat Mat::rowRange(const Range& r) const
608 {
609     return Mat(*this, r, Range::all());
610 }
611 
612 inline
colRange(int startcol,int endcol) const613 Mat Mat::colRange(int startcol, int endcol) const
614 {
615     return Mat(*this, Range::all(), Range(startcol, endcol));
616 }
617 
618 inline
colRange(const Range & r) const619 Mat Mat::colRange(const Range& r) const
620 {
621     return Mat(*this, Range::all(), r);
622 }
623 
624 inline
clone() const625 Mat Mat::clone() const
626 {
627     Mat m;
628     copyTo(m);
629     return m;
630 }
631 
632 inline
assignTo(Mat & m,int _type) const633 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
create(int _rows,int _cols,int _type)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
create(Size _sz,int _type)652 void Mat::create(Size _sz, int _type)
653 {
654     create(_sz.height, _sz.width, _type);
655 }
656 
657 inline
addref()658 void Mat::addref()
659 {
660     if( u )
661         CV_XADD(&u->refcount, 1);
662 }
663 
release()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
operator ()(Range _rowRange,Range _colRange) const675 Mat Mat::operator()( Range _rowRange, Range _colRange ) const
676 {
677     return Mat(*this, _rowRange, _colRange);
678 }
679 
680 inline
operator ()(const Rect & roi) const681 Mat Mat::operator()( const Rect& roi ) const
682 {
683     return Mat(*this, roi);
684 }
685 
686 inline
operator ()(const Range * ranges) const687 Mat Mat::operator()(const Range* ranges) const
688 {
689     return Mat(*this, ranges);
690 }
691 
692 inline
isContinuous() const693 bool Mat::isContinuous() const
694 {
695     return (flags & CONTINUOUS_FLAG) != 0;
696 }
697 
698 inline
isSubmatrix() const699 bool Mat::isSubmatrix() const
700 {
701     return (flags & SUBMATRIX_FLAG) != 0;
702 }
703 
704 inline
elemSize() const705 size_t Mat::elemSize() const
706 {
707     return dims > 0 ? step.p[dims - 1] : 0;
708 }
709 
710 inline
elemSize1() const711 size_t Mat::elemSize1() const
712 {
713     return CV_ELEM_SIZE1(flags);
714 }
715 
716 inline
type() const717 int Mat::type() const
718 {
719     return CV_MAT_TYPE(flags);
720 }
721 
722 inline
depth() const723 int Mat::depth() const
724 {
725     return CV_MAT_DEPTH(flags);
726 }
727 
728 inline
channels() const729 int Mat::channels() const
730 {
731     return CV_MAT_CN(flags);
732 }
733 
734 inline
step1(int i) const735 size_t Mat::step1(int i) const
736 {
737     return step.p[i] / elemSize1();
738 }
739 
740 inline
empty() const741 bool Mat::empty() const
742 {
743     return data == 0 || total() == 0;
744 }
745 
746 inline
total() const747 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
ptr(int y)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
ptr(int y) const765 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
ptr(int y)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
ptr(int y) const779 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
ptr(int i0,int i1)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
ptr(int i0,int i1) const795 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
ptr(int i0,int i1)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
ptr(int i0,int i1) const813 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
ptr(int i0,int i1,int i2)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
ptr(int i0,int i1,int i2) const832 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
ptr(int i0,int i1,int i2)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
ptr(int i0,int i1,int i2) const852 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
ptr(const int * idx)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
ptr(const int * idx) const876 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
at(int i0,int i1)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
at(int i0,int i1) const899 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
at(Point pt)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
at(Point pt) const917 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
at(int i0)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
at(int i0) const940 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
at(int i0,int i1,int i2)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
at(int i0,int i1,int i2) const961 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
at(const int * idx)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
at(const int * idx) const975 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
at(const Vec<int,n> & idx)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
at(const Vec<int,n> & idx) const989 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
begin() const996 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
end() const1003 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
begin()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
end()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
forEach(const Functor & operation)1028 void Mat::forEach(const Functor& operation) {
1029     this->forEach_impl<_Tp>(operation);
1030 }
1031 
1032 template<typename _Tp, typename Functor> inline
forEach(const Functor & operation) const1033 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
operator std::vector<_Tp>() const1039 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
operator Vec<_Tp,n>() const1047 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
operator Matx<_Tp,m,n>() const1061 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
push_back(const _Tp & elem)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
push_back(const Mat_<_Tp> & m)1094 void Mat::push_back(const Mat_<_Tp>& m)
1095 {
1096     push_back((const Mat&)m);
1097 }
1098 
1099 ///////////////////////////// MatSize ////////////////////////////
1100 
1101 inline
MatSize(int * _p)1102 MatSize::MatSize(int* _p)
1103     : p(_p) {}
1104 
1105 inline
operator ()() const1106 Size MatSize::operator()() const
1107 {
1108     CV_DbgAssert(p[-1] <= 2);
1109     return Size(p[1], p[0]);
1110 }
1111 
1112 inline
operator [](int i) const1113 const int& MatSize::operator[](int i) const
1114 {
1115     return p[i];
1116 }
1117 
1118 inline
operator [](int i)1119 int& MatSize::operator[](int i)
1120 {
1121     return p[i];
1122 }
1123 
1124 inline
operator const int*() const1125 MatSize::operator const int*() const
1126 {
1127     return p;
1128 }
1129 
1130 inline
operator ==(const MatSize & sz) const1131 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
operator !=(const MatSize & sz) const1147 bool MatSize::operator != (const MatSize& sz) const
1148 {
1149     return !(*this == sz);
1150 }
1151 
1152 
1153 
1154 ///////////////////////////// MatStep ////////////////////////////
1155 
1156 inline
MatStep()1157 MatStep::MatStep()
1158 {
1159     p = buf; p[0] = p[1] = 0;
1160 }
1161 
1162 inline
MatStep(size_t s)1163 MatStep::MatStep(size_t s)
1164 {
1165     p = buf; p[0] = s; p[1] = 0;
1166 }
1167 
1168 inline
operator [](int i) const1169 const size_t& MatStep::operator[](int i) const
1170 {
1171     return p[i];
1172 }
1173 
1174 inline
operator [](int i)1175 size_t& MatStep::operator[](int i)
1176 {
1177     return p[i];
1178 }
1179 
operator size_t() const1180 inline MatStep::operator size_t() const
1181 {
1182     CV_DbgAssert( p == buf );
1183     return buf[0];
1184 }
1185 
operator =(size_t s)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
Mat_()1198 Mat_<_Tp>::Mat_()
1199     : Mat()
1200 {
1201     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
1202 }
1203 
1204 template<typename _Tp> inline
Mat_(int _rows,int _cols)1205 Mat_<_Tp>::Mat_(int _rows, int _cols)
1206     : Mat(_rows, _cols, DataType<_Tp>::type)
1207 {
1208 }
1209 
1210 template<typename _Tp> inline
Mat_(int _rows,int _cols,const _Tp & value)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
Mat_(Size _sz)1218 Mat_<_Tp>::Mat_(Size _sz)
1219     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
1220 {}
1221 
1222 template<typename _Tp> inline
Mat_(Size _sz,const _Tp & value)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
Mat_(int _dims,const int * _sz)1230 Mat_<_Tp>::Mat_(int _dims, const int* _sz)
1231     : Mat(_dims, _sz, DataType<_Tp>::type)
1232 {}
1233 
1234 template<typename _Tp> inline
Mat_(int _dims,const int * _sz,const _Tp & _s)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
Mat_(const Mat_<_Tp> & m,const Range * ranges)1240 Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
1241     : Mat(m, ranges)
1242 {}
1243 
1244 template<typename _Tp> inline
Mat_(const Mat & m)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
Mat_(const Mat_ & m)1253 Mat_<_Tp>::Mat_(const Mat_& m)
1254     : Mat(m)
1255 {}
1256 
1257 template<typename _Tp> inline
Mat_(int _rows,int _cols,_Tp * _data,size_t steps)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
Mat_(const Mat_ & m,const Range & _rowRange,const Range & _colRange)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
Mat_(const Mat_ & m,const Rect & roi)1268 Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
1269     : Mat(m, roi)
1270 {}
1271 
1272 template<typename _Tp> template<int n> inline
Mat_(const Vec<typename DataType<_Tp>::channel_type,n> & vec,bool copyData)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
Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n> & M,bool copyData)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
Mat_(const Point_<typename DataType<_Tp>::channel_type> & pt,bool copyData)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
Mat_(const Point3_<typename DataType<_Tp>::channel_type> & pt,bool copyData)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
Mat_(const MatCommaInitializer_<_Tp> & commaInitializer)1309 Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
1310     : Mat(commaInitializer)
1311 {}
1312 
1313 template<typename _Tp> inline
Mat_(const std::vector<_Tp> & vec,bool copyData)1314 Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
1315     : Mat(vec, copyData)
1316 {}
1317 
1318 template<typename _Tp> inline
operator =(const Mat & m)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
operator =(const Mat_ & m)1336 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
1337 {
1338     Mat::operator=(m);
1339     return *this;
1340 }
1341 
1342 template<typename _Tp> inline
operator =(const _Tp & s)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
create(int _rows,int _cols)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
create(Size _sz)1357 void Mat_<_Tp>::create(Size _sz)
1358 {
1359     Mat::create(_sz, DataType<_Tp>::type);
1360 }
1361 
1362 template<typename _Tp> inline
create(int _dims,const int * _sz)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
cross(const Mat_ & m) const1369 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
operator Mat_<T2>() const1375 Mat_<_Tp>::operator Mat_<T2>() const
1376 {
1377     return Mat_<T2>(*this);
1378 }
1379 
1380 template<typename _Tp> inline
row(int y) const1381 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
col(int x) const1387 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
diag(int d) const1393 Mat_<_Tp> Mat_<_Tp>::diag(int d) const
1394 {
1395     return Mat_(Mat::diag(d));
1396 }
1397 
1398 template<typename _Tp> inline
clone() const1399 Mat_<_Tp> Mat_<_Tp>::clone() const
1400 {
1401     return Mat_(Mat::clone());
1402 }
1403 
1404 template<typename _Tp> inline
elemSize() const1405 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
elemSize1() const1412 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
type() const1419 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
depth() const1426 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
channels() const1433 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
stepT(int i) const1440 size_t Mat_<_Tp>::stepT(int i) const
1441 {
1442     return step.p[i] / elemSize();
1443 }
1444 
1445 template<typename _Tp> inline
step1(int i) const1446 size_t Mat_<_Tp>::step1(int i) const
1447 {
1448     return step.p[i] / elemSize1();
1449 }
1450 
1451 template<typename _Tp> inline
adjustROI(int dtop,int dbottom,int dleft,int dright)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
operator ()(const Range & _rowRange,const Range & _colRange) const1458 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
operator ()(const Rect & roi) const1464 Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
1465 {
1466     return Mat_<_Tp>(*this, roi);
1467 }
1468 
1469 template<typename _Tp> inline
operator ()(const Range * ranges) const1470 Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
1471 {
1472     return Mat_<_Tp>(*this, ranges);
1473 }
1474 
1475 template<typename _Tp> inline
operator [](int y)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
operator [](int y) const1483 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
operator ()(int i0,int i1)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
operator ()(int i0,int i1) const1500 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
operator ()(Point pt)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
operator ()(Point pt) const1520 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
operator ()(const int * idx)1530 _Tp& Mat_<_Tp>::operator ()(const int* idx)
1531 {
1532     return Mat::at<_Tp>(idx);
1533 }
1534 
1535 template<typename _Tp> inline
operator ()(const int * idx) const1536 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
operator ()(const Vec<int,n> & idx)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
operator ()(const Vec<int,n> & idx) const1548 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
operator ()(int i0)1554 _Tp& Mat_<_Tp>::operator ()(int i0)
1555 {
1556     return this->at<_Tp>(i0);
1557 }
1558 
1559 template<typename _Tp> inline
operator ()(int i0) const1560 const _Tp& Mat_<_Tp>::operator ()(int i0) const
1561 {
1562     return this->at<_Tp>(i0);
1563 }
1564 
1565 template<typename _Tp> inline
operator ()(int i0,int i1,int i2)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
operator ()(int i0,int i1,int i2) const1572 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
operator std::vector<_Tp>() const1578 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
operator Vec<typename DataType<_Tp>::channel_type,n>() const1586 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
operator Matx<typename DataType<_Tp>::channel_type,m,n>() const1593 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
begin() const1602 MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
1603 {
1604     return Mat::begin<_Tp>();
1605 }
1606 
1607 template<typename _Tp> inline
end() const1608 MatConstIterator_<_Tp> Mat_<_Tp>::end() const
1609 {
1610     return Mat::end<_Tp>();
1611 }
1612 
1613 template<typename _Tp> inline
begin()1614 MatIterator_<_Tp> Mat_<_Tp>::begin()
1615 {
1616     return Mat::begin<_Tp>();
1617 }
1618 
1619 template<typename _Tp> inline
end()1620 MatIterator_<_Tp> Mat_<_Tp>::end()
1621 {
1622     return Mat::end<_Tp>();
1623 }
1624 
1625 template<typename _Tp> template<typename Functor> inline
forEach(const Functor & operation)1626 void Mat_<_Tp>::forEach(const Functor& operation) {
1627     Mat::forEach<_Tp, Functor>(operation);
1628 }
1629 
1630 template<typename _Tp> template<typename Functor> inline
forEach(const Functor & operation) const1631 void Mat_<_Tp>::forEach(const Functor& operation) const {
1632     Mat::forEach<_Tp, Functor>(operation);
1633 }
1634 
1635 ///////////////////////////// SparseMat /////////////////////////////
1636 
1637 inline
SparseMat()1638 SparseMat::SparseMat()
1639     : flags(MAGIC_VAL), hdr(0)
1640 {}
1641 
1642 inline
SparseMat(int _dims,const int * _sizes,int _type)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
SparseMat(const SparseMat & m)1650 SparseMat::SparseMat(const SparseMat& m)
1651     : flags(m.flags), hdr(m.hdr)
1652 {
1653     addref();
1654 }
1655 
1656 inline
~SparseMat()1657 SparseMat::~SparseMat()
1658 {
1659     release();
1660 }
1661 
1662 inline
operator =(const SparseMat & m)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
operator =(const Mat & m)1677 SparseMat& SparseMat::operator = (const Mat& m)
1678 {
1679     return (*this = SparseMat(m));
1680 }
1681 
1682 inline
clone() const1683 SparseMat SparseMat::clone() const
1684 {
1685     SparseMat temp;
1686     this->copyTo(temp);
1687     return temp;
1688 }
1689 
1690 inline
assignTo(SparseMat & m,int _type) const1691 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
addref()1700 void SparseMat::addref()
1701 {
1702     if( hdr )
1703         CV_XADD(&hdr->refcount, 1);
1704 }
1705 
1706 inline
release()1707 void SparseMat::release()
1708 {
1709     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
1710         delete hdr;
1711     hdr = 0;
1712 }
1713 
1714 inline
elemSize() const1715 size_t SparseMat::elemSize() const
1716 {
1717     return CV_ELEM_SIZE(flags);
1718 }
1719 
1720 inline
elemSize1() const1721 size_t SparseMat::elemSize1() const
1722 {
1723     return CV_ELEM_SIZE1(flags);
1724 }
1725 
1726 inline
type() const1727 int SparseMat::type() const
1728 {
1729     return CV_MAT_TYPE(flags);
1730 }
1731 
1732 inline
depth() const1733 int SparseMat::depth() const
1734 {
1735     return CV_MAT_DEPTH(flags);
1736 }
1737 
1738 inline
channels() const1739 int SparseMat::channels() const
1740 {
1741     return CV_MAT_CN(flags);
1742 }
1743 
1744 inline
size() const1745 const int* SparseMat::size() const
1746 {
1747     return hdr ? hdr->size : 0;
1748 }
1749 
1750 inline
size(int i) const1751 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
dims() const1762 int SparseMat::dims() const
1763 {
1764     return hdr ? hdr->dims : 0;
1765 }
1766 
1767 inline
nzcount() const1768 size_t SparseMat::nzcount() const
1769 {
1770     return hdr ? hdr->nodeCount : 0;
1771 }
1772 
1773 inline
hash(int i0) const1774 size_t SparseMat::hash(int i0) const
1775 {
1776     return (size_t)i0;
1777 }
1778 
1779 inline
hash(int i0,int i1) const1780 size_t SparseMat::hash(int i0, int i1) const
1781 {
1782     return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
1783 }
1784 
1785 inline
hash(int i0,int i1,int i2) const1786 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
hash(const int * idx) const1792 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
ref(int i0,size_t * hashval)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
ref(int i0,int i1,size_t * hashval)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
ref(int i0,int i1,int i2,size_t * hashval)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
ref(const int * idx,size_t * hashval)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
value(int i0,size_t * hashval) const1828 _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
value(int i0,int i1,size_t * hashval) const1835 _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
value(int i0,int i1,int i2,size_t * hashval) const1842 _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
value(const int * idx,size_t * hashval) const1849 _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
find(int i0,size_t * hashval) const1856 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
find(int i0,int i1,size_t * hashval) const1862 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
find(int i0,int i1,int i2,size_t * hashval) const1868 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
find(const int * idx,size_t * hashval) const1874 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
value(Node * n)1880 _Tp& SparseMat::value(Node* n)
1881 {
1882     return *(_Tp*)((uchar*)n + hdr->valueOffset);
1883 }
1884 
1885 template<typename _Tp> inline
value(const Node * n) const1886 const _Tp& SparseMat::value(const Node* n) const
1887 {
1888     return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
1889 }
1890 
1891 inline
node(size_t nidx)1892 SparseMat::Node* SparseMat::node(size_t nidx)
1893 {
1894     return (Node*)(void*)&hdr->pool[nidx];
1895 }
1896 
1897 inline
node(size_t nidx) const1898 const SparseMat::Node* SparseMat::node(size_t nidx) const
1899 {
1900     return (const Node*)(const void*)&hdr->pool[nidx];
1901 }
1902 
1903 inline
begin()1904 SparseMatIterator SparseMat::begin()
1905 {
1906     return SparseMatIterator(this);
1907 }
1908 
1909 inline
begin() const1910 SparseMatConstIterator SparseMat::begin() const
1911 {
1912     return SparseMatConstIterator(this);
1913 }
1914 
1915 inline
end()1916 SparseMatIterator SparseMat::end()
1917 {
1918     SparseMatIterator it(this);
1919     it.seekEnd();
1920     return it;
1921 }
1922 
1923 inline
end() const1924 SparseMatConstIterator SparseMat::end() const
1925 {
1926     SparseMatConstIterator it(this);
1927     it.seekEnd();
1928     return it;
1929 }
1930 
1931 template<typename _Tp> inline
begin()1932 SparseMatIterator_<_Tp> SparseMat::begin()
1933 {
1934     return SparseMatIterator_<_Tp>(this);
1935 }
1936 
1937 template<typename _Tp> inline
begin() const1938 SparseMatConstIterator_<_Tp> SparseMat::begin() const
1939 {
1940     return SparseMatConstIterator_<_Tp>(this);
1941 }
1942 
1943 template<typename _Tp> inline
end()1944 SparseMatIterator_<_Tp> SparseMat::end()
1945 {
1946     SparseMatIterator_<_Tp> it(this);
1947     it.seekEnd();
1948     return it;
1949 }
1950 
1951 template<typename _Tp> inline
end() const1952 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
SparseMat_()1964 SparseMat_<_Tp>::SparseMat_()
1965 {
1966     flags = MAGIC_VAL | DataType<_Tp>::type;
1967 }
1968 
1969 template<typename _Tp> inline
SparseMat_(int _dims,const int * _sizes)1970 SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
1971     : SparseMat(_dims, _sizes, DataType<_Tp>::type)
1972 {}
1973 
1974 template<typename _Tp> inline
SparseMat_(const SparseMat & m)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
SparseMat_(const SparseMat_<_Tp> & m)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
SparseMat_(const Mat & m)1993 SparseMat_<_Tp>::SparseMat_(const Mat& m)
1994 {
1995     SparseMat sm(m);
1996     *this = sm;
1997 }
1998 
1999 template<typename _Tp> inline
operator =(const SparseMat_<_Tp> & m)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
operator =(const SparseMat & m)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
operator =(const Mat & m)2022 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
2023 {
2024     return (*this = SparseMat(m));
2025 }
2026 
2027 template<typename _Tp> inline
clone() const2028 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
create(int _dims,const int * _sizes)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
type() const2042 int SparseMat_<_Tp>::type() const
2043 {
2044     return DataType<_Tp>::type;
2045 }
2046 
2047 template<typename _Tp> inline
depth() const2048 int SparseMat_<_Tp>::depth() const
2049 {
2050     return DataType<_Tp>::depth;
2051 }
2052 
2053 template<typename _Tp> inline
channels() const2054 int SparseMat_<_Tp>::channels() const
2055 {
2056     return DataType<_Tp>::channels;
2057 }
2058 
2059 template<typename _Tp> inline
ref(int i0,size_t * hashval)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
operator ()(int i0,size_t * hashval) const2066 _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
ref(int i0,int i1,size_t * hashval)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
operator ()(int i0,int i1,size_t * hashval) const2078 _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
ref(int i0,int i1,int i2,size_t * hashval)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
operator ()(int i0,int i1,int i2,size_t * hashval) const2090 _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
ref(const int * idx,size_t * hashval)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
operator ()(const int * idx,size_t * hashval) const2102 _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
begin()2108 SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
2109 {
2110     return SparseMatIterator_<_Tp>(this);
2111 }
2112 
2113 template<typename _Tp> inline
begin() const2114 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
2115 {
2116     return SparseMatConstIterator_<_Tp>(this);
2117 }
2118 
2119 template<typename _Tp> inline
end()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
end() const2128 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
MatConstIterator()2140 MatConstIterator::MatConstIterator()
2141     : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
2142 {}
2143 
2144 inline
MatConstIterator(const Mat * _m)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
MatConstIterator(const Mat * _m,int _row,int _col)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
MatConstIterator(const Mat * _m,Point _pt)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
MatConstIterator(const MatConstIterator & it)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
operator =(const MatConstIterator & it)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
operator *() const2198 const uchar* MatConstIterator::operator *() const
2199 {
2200     return ptr;
2201 }
2202 
operator +=(ptrdiff_t ofs)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
operator -=(ptrdiff_t ofs)2218 MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
2219 {
2220     return (*this += -ofs);
2221 }
2222 
2223 inline
operator --()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
operator --(int)2235 MatConstIterator MatConstIterator::operator --(int)
2236 {
2237     MatConstIterator b = *this;
2238     *this += -1;
2239     return b;
2240 }
2241 
2242 inline
operator ++()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 
operator ++(int)2253 inline MatConstIterator MatConstIterator::operator ++(int)
2254 {
2255     MatConstIterator b = *this;
2256     *this += 1;
2257     return b;
2258 }
2259 
2260 
2261 static inline
operator ==(const MatConstIterator & a,const MatConstIterator & b)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
operator !=(const MatConstIterator & a,const MatConstIterator & b)2268 bool operator != (const MatConstIterator& a, const MatConstIterator& b)
2269 {
2270     return !(a == b);
2271 }
2272 
2273 static inline
operator <(const MatConstIterator & a,const MatConstIterator & b)2274 bool operator < (const MatConstIterator& a, const MatConstIterator& b)
2275 {
2276     return a.ptr < b.ptr;
2277 }
2278 
2279 static inline
operator >(const MatConstIterator & a,const MatConstIterator & b)2280 bool operator > (const MatConstIterator& a, const MatConstIterator& b)
2281 {
2282     return a.ptr > b.ptr;
2283 }
2284 
2285 static inline
operator <=(const MatConstIterator & a,const MatConstIterator & b)2286 bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
2287 {
2288     return a.ptr <= b.ptr;
2289 }
2290 
2291 static inline
operator >=(const MatConstIterator & a,const MatConstIterator & b)2292 bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
2293 {
2294     return a.ptr >= b.ptr;
2295 }
2296 
2297 static inline
operator -(const MatConstIterator & b,const MatConstIterator & a)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
operator +(const MatConstIterator & a,ptrdiff_t ofs)2309 MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
2310 {
2311     MatConstIterator b = a;
2312     return b += ofs;
2313 }
2314 
2315 static inline
operator +(ptrdiff_t ofs,const MatConstIterator & a)2316 MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
2317 {
2318     MatConstIterator b = a;
2319     return b += ofs;
2320 }
2321 
2322 static inline
operator -(const MatConstIterator & a,ptrdiff_t ofs)2323 MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
2324 {
2325     MatConstIterator b = a;
2326     return b += -ofs;
2327 }
2328 
2329 
2330 inline
operator [](ptrdiff_t i) const2331 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
MatConstIterator_()2341 MatConstIterator_<_Tp>::MatConstIterator_()
2342 {}
2343 
2344 template<typename _Tp> inline
MatConstIterator_(const Mat_<_Tp> * _m)2345 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
2346     : MatConstIterator(_m)
2347 {}
2348 
2349 template<typename _Tp> inline
MatConstIterator_(const Mat_<_Tp> * _m,int _row,int _col)2350 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
2351     : MatConstIterator(_m, _row, _col)
2352 {}
2353 
2354 template<typename _Tp> inline
MatConstIterator_(const Mat_<_Tp> * _m,Point _pt)2355 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
2356     : MatConstIterator(_m, _pt)
2357 {}
2358 
2359 template<typename _Tp> inline
MatConstIterator_(const MatConstIterator_ & it)2360 MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
2361     : MatConstIterator(it)
2362 {}
2363 
2364 template<typename _Tp> inline
operator =(const MatConstIterator_ & it)2365 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
2366 {
2367     MatConstIterator::operator = (it);
2368     return *this;
2369 }
2370 
2371 template<typename _Tp> inline
operator *() const2372 _Tp MatConstIterator_<_Tp>::operator *() const
2373 {
2374     return *(_Tp*)(this->ptr);
2375 }
2376 
2377 template<typename _Tp> inline
operator +=(ptrdiff_t ofs)2378 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
2379 {
2380     MatConstIterator::operator += (ofs);
2381     return *this;
2382 }
2383 
2384 template<typename _Tp> inline
operator -=(ptrdiff_t ofs)2385 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
2386 {
2387     return (*this += -ofs);
2388 }
2389 
2390 template<typename _Tp> inline
operator --()2391 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
2392 {
2393     MatConstIterator::operator --();
2394     return *this;
2395 }
2396 
2397 template<typename _Tp> inline
operator --(int)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
operator ++()2406 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
2407 {
2408     MatConstIterator::operator ++();
2409     return *this;
2410 }
2411 
2412 template<typename _Tp> inline
operator ++(int)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
pos() const2422 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
operator ==(const MatConstIterator_<_Tp> & a,const MatConstIterator_<_Tp> & b)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
operator !=(const MatConstIterator_<_Tp> & a,const MatConstIterator_<_Tp> & b)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
operator +(const MatConstIterator_<_Tp> & a,ptrdiff_t ofs)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
operator +(ptrdiff_t ofs,const MatConstIterator_<_Tp> & a)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
operator -(const MatConstIterator_<_Tp> & a,ptrdiff_t ofs)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
operator [](ptrdiff_t i) const2478 _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
MatIterator_()2488 MatIterator_<_Tp>::MatIterator_()
2489     : MatConstIterator_<_Tp>()
2490 {}
2491 
2492 template<typename _Tp> inline
MatIterator_(Mat_<_Tp> * _m)2493 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
2494     : MatConstIterator_<_Tp>(_m)
2495 {}
2496 
2497 template<typename _Tp> inline
MatIterator_(Mat_<_Tp> * _m,int _row,int _col)2498 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
2499     : MatConstIterator_<_Tp>(_m, _row, _col)
2500 {}
2501 
2502 template<typename _Tp> inline
MatIterator_(Mat_<_Tp> * _m,Point _pt)2503 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt)
2504     : MatConstIterator_<_Tp>(_m, _pt)
2505 {}
2506 
2507 template<typename _Tp> inline
MatIterator_(Mat_<_Tp> * _m,const int * _idx)2508 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx)
2509     : MatConstIterator_<_Tp>(_m, _idx)
2510 {}
2511 
2512 template<typename _Tp> inline
MatIterator_(const MatIterator_ & it)2513 MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
2514     : MatConstIterator_<_Tp>(it)
2515 {}
2516 
2517 template<typename _Tp> inline
operator =(const MatIterator_<_Tp> & it)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
operator *() const2525 _Tp& MatIterator_<_Tp>::operator *() const
2526 {
2527     return *(_Tp*)(this->ptr);
2528 }
2529 
2530 template<typename _Tp> inline
operator +=(ptrdiff_t ofs)2531 MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
2532 {
2533     MatConstIterator::operator += (ofs);
2534     return *this;
2535 }
2536 
2537 template<typename _Tp> inline
operator -=(ptrdiff_t ofs)2538 MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
2539 {
2540     MatConstIterator::operator += (-ofs);
2541     return *this;
2542 }
2543 
2544 template<typename _Tp> inline
operator --()2545 MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
2546 {
2547     MatConstIterator::operator --();
2548     return *this;
2549 }
2550 
2551 template<typename _Tp> inline
operator --(int)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
operator ++()2560 MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
2561 {
2562     MatConstIterator::operator ++();
2563     return *this;
2564 }
2565 
2566 template<typename _Tp> inline
operator ++(int)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
operator [](ptrdiff_t i) const2575 _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
2576 {
2577     return *(*this + i);
2578 }
2579 
2580 
2581 template<typename _Tp> static inline
operator ==(const MatIterator_<_Tp> & a,const MatIterator_<_Tp> & b)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
operator !=(const MatIterator_<_Tp> & a,const MatIterator_<_Tp> & b)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
operator +(const MatIterator_<_Tp> & a,ptrdiff_t ofs)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
operator +(ptrdiff_t ofs,const MatIterator_<_Tp> & a)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
operator -(const MatIterator_<_Tp> & a,ptrdiff_t ofs)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
SparseMatConstIterator()2619 SparseMatConstIterator::SparseMatConstIterator()
2620     : m(0), hashidx(0), ptr(0)
2621 {}
2622 
2623 inline
SparseMatConstIterator(const SparseMatConstIterator & it)2624 SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
2625     : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
2626 {}
2627 
operator =(const SparseMatConstIterator & it)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
value() const2640 const _Tp& SparseMatConstIterator::value() const
2641 {
2642     return *(const _Tp*)ptr;
2643 }
2644 
2645 inline
node() const2646 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
operator ++(int)2652 SparseMatConstIterator SparseMatConstIterator::operator ++(int)
2653 {
2654     SparseMatConstIterator it = *this;
2655     ++*this;
2656     return it;
2657 }
2658 
2659 inline
seekEnd()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
operator ==(const SparseMatConstIterator & it1,const SparseMatConstIterator & it2)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
operator !=(const SparseMatConstIterator & it1,const SparseMatConstIterator & it2)2677 bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
2678 {
2679     return !(it1 == it2);
2680 }
2681 
2682 
2683 
2684 ///////////////////////// SparseMatIterator /////////////////////////
2685 
2686 inline
SparseMatIterator()2687 SparseMatIterator::SparseMatIterator()
2688 {}
2689 
2690 inline
SparseMatIterator(SparseMat * _m)2691 SparseMatIterator::SparseMatIterator(SparseMat* _m)
2692     : SparseMatConstIterator(_m)
2693 {}
2694 
2695 inline
SparseMatIterator(const SparseMatIterator & it)2696 SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
2697     : SparseMatConstIterator(it)
2698 {}
2699 
2700 inline
operator =(const SparseMatIterator & it)2701 SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
2702 {
2703     (SparseMatConstIterator&)*this = it;
2704     return *this;
2705 }
2706 
2707 template<typename _Tp> inline
value() const2708 _Tp& SparseMatIterator::value() const
2709 {
2710     return *(_Tp*)ptr;
2711 }
2712 
2713 inline
node() const2714 SparseMat::Node* SparseMatIterator::node() const
2715 {
2716     return (SparseMat::Node*)SparseMatConstIterator::node();
2717 }
2718 
2719 inline
operator ++()2720 SparseMatIterator& SparseMatIterator::operator ++()
2721 {
2722     SparseMatConstIterator::operator ++();
2723     return *this;
2724 }
2725 
2726 inline
operator ++(int)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
SparseMatConstIterator_()2739 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
2740 {}
2741 
2742 template<typename _Tp> inline
SparseMatConstIterator_(const SparseMat_<_Tp> * _m)2743 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
2744     : SparseMatConstIterator(_m)
2745 {}
2746 
2747 template<typename _Tp> inline
SparseMatConstIterator_(const SparseMat * _m)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
SparseMatConstIterator_(const SparseMatConstIterator_<_Tp> & it)2755 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
2756     : SparseMatConstIterator(it)
2757 {}
2758 
2759 template<typename _Tp> inline
operator =(const SparseMatConstIterator_<_Tp> & it)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
operator *() const2768 const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
2769 {
2770     return *(const _Tp*)this->ptr;
2771 }
2772 
2773 template<typename _Tp> inline
operator ++()2774 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
2775 {
2776     SparseMatConstIterator::operator ++();
2777     return *this;
2778 }
2779 
2780 template<typename _Tp> inline
operator ++(int)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
SparseMatIterator_()2793 SparseMatIterator_<_Tp>::SparseMatIterator_()
2794 {}
2795 
2796 template<typename _Tp> inline
SparseMatIterator_(SparseMat_<_Tp> * _m)2797 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
2798     : SparseMatConstIterator_<_Tp>(_m)
2799 {}
2800 
2801 template<typename _Tp> inline
SparseMatIterator_(SparseMat * _m)2802 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
2803     : SparseMatConstIterator_<_Tp>(_m)
2804 {}
2805 
2806 template<typename _Tp> inline
SparseMatIterator_(const SparseMatIterator_<_Tp> & it)2807 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
2808     : SparseMatConstIterator_<_Tp>(it)
2809 {}
2810 
2811 template<typename _Tp> inline
operator =(const SparseMatIterator_<_Tp> & it)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
operator *() const2820 _Tp& SparseMatIterator_<_Tp>::operator *() const
2821 {
2822     return *(_Tp*)this->ptr;
2823 }
2824 
2825 template<typename _Tp> inline
operator ++()2826 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
2827 {
2828     SparseMatConstIterator::operator ++();
2829     return *this;
2830 }
2831 
2832 template<typename _Tp> inline
operator ++(int)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
MatCommaInitializer_(Mat_<_Tp> * _m)2845 MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
2846     : it(_m)
2847 {}
2848 
2849 template<typename _Tp> template<typename T2> inline
operator ,(T2 v)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
operator Mat_<_Tp>() const2859 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
operator <<(const Mat_<_Tp> & m,T2 val)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
operator =(const MatExpr & e)2878 Mat& Mat::operator = (const MatExpr& e)
2879 {
2880     e.op->assign(e, *this);
2881     return *this;
2882 }
2883 
2884 template<typename _Tp> inline
Mat_(const MatExpr & e)2885 Mat_<_Tp>::Mat_(const MatExpr& e)
2886 {
2887     e.op->assign(e, *this, DataType<_Tp>::type);
2888 }
2889 
2890 template<typename _Tp> inline
operator =(const MatExpr & e)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
zeros(int rows,int cols)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
zeros(Size sz)2904 MatExpr Mat_<_Tp>::zeros(Size sz)
2905 {
2906     return Mat::zeros(sz, DataType<_Tp>::type);
2907 }
2908 
2909 template<typename _Tp> inline
ones(int rows,int cols)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
ones(Size sz)2916 MatExpr Mat_<_Tp>::ones(Size sz)
2917 {
2918     return Mat::ones(sz, DataType<_Tp>::type);
2919 }
2920 
2921 template<typename _Tp> inline
eye(int rows,int cols)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
eye(Size sz)2928 MatExpr Mat_<_Tp>::eye(Size sz)
2929 {
2930     return Mat::eye(sz, DataType<_Tp>::type);
2931 }
2932 
2933 inline
MatExpr()2934 MatExpr::MatExpr()
2935     : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
2936 {}
2937 
2938 inline
MatExpr(const MatOp * _op,int _flags,const Mat & _a,const Mat & _b,const Mat & _c,double _alpha,double _beta,const Scalar & _s)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
operator Mat() const2945 MatExpr::operator Mat() const
2946 {
2947     Mat m;
2948     op->assign(*this, m);
2949     return m;
2950 }
2951 
2952 template<typename _Tp> inline
operator Mat_<_Tp>() const2953 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
min(const Mat_<_Tp> & a,const Mat_<_Tp> & b)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
min(const Mat_<_Tp> & a,double s)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
min(double s,const Mat_<_Tp> & a)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
max(const Mat_<_Tp> & a,const Mat_<_Tp> & b)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
max(const Mat_<_Tp> & a,double s)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
max(double s,const Mat_<_Tp> & a)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
abs(const Mat_<_Tp> & m)2998 MatExpr abs(const Mat_<_Tp>& m)
2999 {
3000     return cv::abs((const Mat&)m);
3001 }
3002 
3003 
3004 static inline
operator +=(Mat & a,const MatExpr & b)3005 Mat& operator += (Mat& a, const MatExpr& b)
3006 {
3007     b.op->augAssignAdd(b, a);
3008     return a;
3009 }
3010 
3011 static inline
operator +=(const Mat & a,const MatExpr & b)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
operator +=(Mat_<_Tp> & a,const MatExpr & b)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
operator +=(const Mat_<_Tp> & a,const MatExpr & b)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
operator -=(Mat & a,const MatExpr & b)3033 Mat& operator -= (Mat& a, const MatExpr& b)
3034 {
3035     b.op->augAssignSubtract(b, a);
3036     return a;
3037 }
3038 
3039 static inline
operator -=(const Mat & a,const MatExpr & b)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
operator -=(Mat_<_Tp> & a,const MatExpr & b)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
operator -=(const Mat_<_Tp> & a,const MatExpr & b)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
operator *=(Mat & a,const MatExpr & b)3061 Mat& operator *= (Mat& a, const MatExpr& b)
3062 {
3063     b.op->augAssignMultiply(b, a);
3064     return a;
3065 }
3066 
3067 static inline
operator *=(const Mat & a,const MatExpr & b)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
operator *=(Mat_<_Tp> & a,const MatExpr & b)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
operator *=(const Mat_<_Tp> & a,const MatExpr & b)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
operator /=(Mat & a,const MatExpr & b)3089 Mat& operator /= (Mat& a, const MatExpr& b)
3090 {
3091     b.op->augAssignDivide(b, a);
3092     return a;
3093 }
3094 
3095 static inline
operator /=(const Mat & a,const MatExpr & b)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
operator /=(Mat_<_Tp> & a,const MatExpr & b)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
operator /=(const Mat_<_Tp> & a,const MatExpr & b)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
UMat(UMatUsageFlags _usageFlags)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
UMat(int _rows,int _cols,int _type,UMatUsageFlags _usageFlags)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
UMat(int _rows,int _cols,int _type,const Scalar & _s,UMatUsageFlags _usageFlags)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
UMat(Size _sz,int _type,UMatUsageFlags _usageFlags)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
UMat(Size _sz,int _type,const Scalar & _s,UMatUsageFlags _usageFlags)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
UMat(int _dims,const int * _sz,int _type,UMatUsageFlags _usageFlags)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
UMat(int _dims,const int * _sz,int _type,const Scalar & _s,UMatUsageFlags _usageFlags)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
UMat(const UMat & m)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
UMat(const std::vector<_Tp> & vec,bool copyData)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
operator =(const UMat & m)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
row(int y) const3232 UMat UMat::row(int y) const
3233 {
3234     return UMat(*this, Range(y, y + 1), Range::all());
3235 }
3236 
3237 inline
col(int x) const3238 UMat UMat::col(int x) const
3239 {
3240     return UMat(*this, Range::all(), Range(x, x + 1));
3241 }
3242 
3243 inline
rowRange(int startrow,int endrow) const3244 UMat UMat::rowRange(int startrow, int endrow) const
3245 {
3246     return UMat(*this, Range(startrow, endrow), Range::all());
3247 }
3248 
3249 inline
rowRange(const Range & r) const3250 UMat UMat::rowRange(const Range& r) const
3251 {
3252     return UMat(*this, r, Range::all());
3253 }
3254 
3255 inline
colRange(int startcol,int endcol) const3256 UMat UMat::colRange(int startcol, int endcol) const
3257 {
3258     return UMat(*this, Range::all(), Range(startcol, endcol));
3259 }
3260 
3261 inline
colRange(const Range & r) const3262 UMat UMat::colRange(const Range& r) const
3263 {
3264     return UMat(*this, Range::all(), r);
3265 }
3266 
3267 inline
clone() const3268 UMat UMat::clone() const
3269 {
3270     UMat m;
3271     copyTo(m);
3272     return m;
3273 }
3274 
3275 inline
assignTo(UMat & m,int _type) const3276 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
create(int _rows,int _cols,int _type,UMatUsageFlags _usageFlags)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
create(Size _sz,int _type,UMatUsageFlags _usageFlags)3295 void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
3296 {
3297     create(_sz.height, _sz.width, _type, _usageFlags);
3298 }
3299 
3300 inline
addref()3301 void UMat::addref()
3302 {
3303     if( u )
3304         CV_XADD(&(u->urefcount), 1);
3305 }
3306 
release()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
operator ()(Range _rowRange,Range _colRange) const3317 UMat UMat::operator()( Range _rowRange, Range _colRange ) const
3318 {
3319     return UMat(*this, _rowRange, _colRange);
3320 }
3321 
3322 inline
operator ()(const Rect & roi) const3323 UMat UMat::operator()( const Rect& roi ) const
3324 {
3325     return UMat(*this, roi);
3326 }
3327 
3328 inline
operator ()(const Range * ranges) const3329 UMat UMat::operator()(const Range* ranges) const
3330 {
3331     return UMat(*this, ranges);
3332 }
3333 
3334 inline
isContinuous() const3335 bool UMat::isContinuous() const
3336 {
3337     return (flags & CONTINUOUS_FLAG) != 0;
3338 }
3339 
3340 inline
isSubmatrix() const3341 bool UMat::isSubmatrix() const
3342 {
3343     return (flags & SUBMATRIX_FLAG) != 0;
3344 }
3345 
3346 inline
elemSize() const3347 size_t UMat::elemSize() const
3348 {
3349     return dims > 0 ? step.p[dims - 1] : 0;
3350 }
3351 
3352 inline
elemSize1() const3353 size_t UMat::elemSize1() const
3354 {
3355     return CV_ELEM_SIZE1(flags);
3356 }
3357 
3358 inline
type() const3359 int UMat::type() const
3360 {
3361     return CV_MAT_TYPE(flags);
3362 }
3363 
3364 inline
depth() const3365 int UMat::depth() const
3366 {
3367     return CV_MAT_DEPTH(flags);
3368 }
3369 
3370 inline
channels() const3371 int UMat::channels() const
3372 {
3373     return CV_MAT_CN(flags);
3374 }
3375 
3376 inline
step1(int i) const3377 size_t UMat::step1(int i) const
3378 {
3379     return step.p[i] / elemSize1();
3380 }
3381 
3382 inline
empty() const3383 bool UMat::empty() const
3384 {
3385     return u == 0 || total() == 0;
3386 }
3387 
3388 inline
total() const3389 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 
hostCopyObsolete() const3399 inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
deviceCopyObsolete() const3400 inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
deviceMemMapped() const3401 inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }
copyOnMap() const3402 inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; }
tempUMat() const3403 inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; }
tempCopiedUMat() const3404 inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; }
3405 
markDeviceMemMapped(bool flag)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 
markHostCopyObsolete(bool flag)3414 inline void UMatData::markHostCopyObsolete(bool flag)
3415 {
3416     if(flag)
3417         flags |= HOST_COPY_OBSOLETE;
3418     else
3419         flags &= ~HOST_COPY_OBSOLETE;
3420 }
markDeviceCopyObsolete(bool flag)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 
UMatDataAutoLock(UMatData * _u)3429 inline UMatDataAutoLock::UMatDataAutoLock(UMatData* _u) : u(_u) { u->lock(); }
~UMatDataAutoLock()3430 inline UMatDataAutoLock::~UMatDataAutoLock() { u->unlock(); }
3431 
3432 //! @endcond
3433 
3434 } //cv
3435 
3436 #endif
3437