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