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