OpenCV 2.4.8 components for OpenCVgrabber.
[mmanager-3rdparty.git] / OpenCV2.4.8 / build / include / opencv2 / core / mat.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 SKIP_INCLUDES
47 #include <limits.h>
48 #include <string.h>
49 #endif // SKIP_INCLUDES
50
51 #ifdef __cplusplus
52
53 namespace cv
54 {
55
56 //////////////////////////////// Mat ////////////////////////////////
57
58 inline void Mat::initEmpty()
59 {
60     flags = MAGIC_VAL;
61     dims = rows = cols = 0;
62     data = datastart = dataend = datalimit = 0;
63     refcount = 0;
64     allocator = 0;
65 }
66
67 inline Mat::Mat() : size(&rows)
68 {
69     initEmpty();
70 }
71
72 inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
73 {
74     initEmpty();
75     create(_rows, _cols, _type);
76 }
77
78 inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows)
79 {
80     initEmpty();
81     create(_rows, _cols, _type);
82     *this = _s;
83 }
84
85 inline Mat::Mat(Size _sz, int _type) : size(&rows)
86 {
87     initEmpty();
88     create( _sz.height, _sz.width, _type );
89 }
90
91 inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows)
92 {
93     initEmpty();
94     create(_sz.height, _sz.width, _type);
95     *this = _s;
96 }
97
98 inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows)
99 {
100     initEmpty();
101     create(_dims, _sz, _type);
102 }
103
104 inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) : size(&rows)
105 {
106     initEmpty();
107     create(_dims, _sz, _type);
108     *this = _s;
109 }
110
111 inline Mat::Mat(const Mat& m)
112     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
113     refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
114     datalimit(m.datalimit), allocator(m.allocator), size(&rows)
115 {
116     if( refcount )
117         CV_XADD(refcount, 1);
118     if( m.dims <= 2 )
119     {
120         step[0] = m.step[0]; step[1] = m.step[1];
121     }
122     else
123     {
124         dims = 0;
125         copySize(m);
126     }
127 }
128
129 inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
130     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
131     data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
132     datalimit(0), allocator(0), size(&rows)
133 {
134     size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
135     if( _step == AUTO_STEP )
136     {
137         _step = minstep;
138         flags |= CONTINUOUS_FLAG;
139     }
140     else
141     {
142         if( rows == 1 ) _step = minstep;
143         CV_DbgAssert( _step >= minstep );
144         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
145     }
146     step[0] = _step; step[1] = esz;
147     datalimit = datastart + _step*rows;
148     dataend = datalimit - _step + minstep;
149 }
150
151 inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
152     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
153     data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
154     datalimit(0), allocator(0), size(&rows)
155 {
156     size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
157     if( _step == AUTO_STEP )
158     {
159         _step = minstep;
160         flags |= CONTINUOUS_FLAG;
161     }
162     else
163     {
164         if( rows == 1 ) _step = minstep;
165         CV_DbgAssert( _step >= minstep );
166         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
167     }
168     step[0] = _step; step[1] = esz;
169     datalimit = datastart + _step*rows;
170     dataend = datalimit - _step + minstep;
171 }
172
173
174 template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
175     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
176     dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0),
177     datastart(0), dataend(0), allocator(0), size(&rows)
178 {
179     if(vec.empty())
180         return;
181     if( !copyData )
182     {
183         step[0] = step[1] = sizeof(_Tp);
184         data = datastart = (uchar*)&vec[0];
185         datalimit = dataend = datastart + rows*step[0];
186     }
187     else
188         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
189 }
190
191
192 template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
193     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
194     dims(2), rows(n), cols(1), data(0), refcount(0),
195     datastart(0), dataend(0), allocator(0), size(&rows)
196 {
197     if( !copyData )
198     {
199         step[0] = step[1] = sizeof(_Tp);
200         data = datastart = (uchar*)vec.val;
201         datalimit = dataend = datastart + rows*step[0];
202     }
203     else
204         Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
205 }
206
207
208 template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
209     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
210     dims(2), rows(m), cols(n), data(0), refcount(0),
211     datastart(0), dataend(0), allocator(0), size(&rows)
212 {
213     if( !copyData )
214     {
215         step[0] = cols*sizeof(_Tp);
216         step[1] = sizeof(_Tp);
217         data = datastart = (uchar*)M.val;
218         datalimit = dataend = datastart + rows*step[0];
219     }
220     else
221         Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
222 }
223
224
225 template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
226     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
227     dims(2), rows(2), cols(1), data(0), refcount(0),
228     datastart(0), dataend(0), allocator(0), size(&rows)
229 {
230     if( !copyData )
231     {
232         step[0] = step[1] = sizeof(_Tp);
233         data = datastart = (uchar*)&pt.x;
234         datalimit = dataend = datastart + rows*step[0];
235     }
236     else
237     {
238         create(2, 1, DataType<_Tp>::type);
239         ((_Tp*)data)[0] = pt.x;
240         ((_Tp*)data)[1] = pt.y;
241     }
242 }
243
244
245 template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
246     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
247     dims(2), rows(3), cols(1), data(0), refcount(0),
248     datastart(0), dataend(0), allocator(0), size(&rows)
249 {
250     if( !copyData )
251     {
252         step[0] = step[1] = sizeof(_Tp);
253         data = datastart = (uchar*)&pt.x;
254         datalimit = dataend = datastart + rows*step[0];
255     }
256     else
257     {
258         create(3, 1, DataType<_Tp>::type);
259         ((_Tp*)data)[0] = pt.x;
260         ((_Tp*)data)[1] = pt.y;
261         ((_Tp*)data)[2] = pt.z;
262     }
263 }
264
265
266 template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
267     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
268     dims(0), rows(0), cols(0), data(0), refcount(0),
269     datastart(0), dataend(0), allocator(0), size(&rows)
270 {
271     *this = *commaInitializer;
272 }
273
274 inline Mat::~Mat()
275 {
276     release();
277     if( step.p != step.buf )
278         fastFree(step.p);
279 }
280
281 inline Mat& Mat::operator = (const Mat& m)
282 {
283     if( this != &m )
284     {
285         if( m.refcount )
286             CV_XADD(m.refcount, 1);
287         release();
288         flags = m.flags;
289         if( dims <= 2 && m.dims <= 2 )
290         {
291             dims = m.dims;
292             rows = m.rows;
293             cols = m.cols;
294             step[0] = m.step[0];
295             step[1] = m.step[1];
296         }
297         else
298             copySize(m);
299         data = m.data;
300         datastart = m.datastart;
301         dataend = m.dataend;
302         datalimit = m.datalimit;
303         refcount = m.refcount;
304         allocator = m.allocator;
305     }
306     return *this;
307 }
308
309 inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
310 inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
311 inline Mat Mat::rowRange(int startrow, int endrow) const
312     { return Mat(*this, Range(startrow, endrow), Range::all()); }
313 inline Mat Mat::rowRange(const Range& r) const
314     { return Mat(*this, r, Range::all()); }
315 inline Mat Mat::colRange(int startcol, int endcol) const
316     { return Mat(*this, Range::all(), Range(startcol, endcol)); }
317 inline Mat Mat::colRange(const Range& r) const
318     { return Mat(*this, Range::all(), r); }
319
320 inline Mat Mat::diag(const Mat& d)
321 {
322     CV_Assert( d.cols == 1 || d.rows == 1 );
323     int len = d.rows + d.cols - 1;
324     Mat m(len, len, d.type(), Scalar(0)), md = m.diag();
325     if( d.cols == 1 )
326         d.copyTo(md);
327     else
328         transpose(d, md);
329     return m;
330 }
331
332 inline Mat Mat::clone() const
333 {
334     Mat m;
335     copyTo(m);
336     return m;
337 }
338
339 inline void Mat::assignTo( Mat& m, int _type ) const
340 {
341     if( _type < 0 )
342         m = *this;
343     else
344         convertTo(m, _type);
345 }
346
347 inline void Mat::create(int _rows, int _cols, int _type)
348 {
349     _type &= TYPE_MASK;
350     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
351         return;
352     int sz[] = {_rows, _cols};
353     create(2, sz, _type);
354 }
355
356 inline void Mat::create(Size _sz, int _type)
357 {
358     create(_sz.height, _sz.width, _type);
359 }
360
361 inline void Mat::addref()
362 { if( refcount ) CV_XADD(refcount, 1); }
363
364 inline void Mat::release()
365 {
366     if( refcount && CV_XADD(refcount, -1) == 1 )
367         deallocate();
368     data = datastart = dataend = datalimit = 0;
369     size.p[0] = 0;
370     refcount = 0;
371 }
372
373 inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
374 {
375     return Mat(*this, _rowRange, _colRange);
376 }
377
378 inline Mat Mat::operator()( const Rect& roi ) const
379 { return Mat(*this, roi); }
380
381 inline Mat Mat::operator()(const Range* ranges) const
382 {
383     return Mat(*this, ranges);
384 }
385
386 inline Mat::operator CvMat() const
387 {
388     CV_DbgAssert(dims <= 2);
389     CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data);
390     m.step = (int)step[0];
391     m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
392     return m;
393 }
394
395 inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
396 inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
397 inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; }
398 inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
399 inline int Mat::type() const { return CV_MAT_TYPE(flags); }
400 inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
401 inline int Mat::channels() const { return CV_MAT_CN(flags); }
402 inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
403 inline bool Mat::empty() const { return data == 0 || total() == 0; }
404 inline size_t Mat::total() const
405 {
406     if( dims <= 2 )
407         return (size_t)rows*cols;
408     size_t p = 1;
409     for( int i = 0; i < dims; i++ )
410         p *= size[i];
411     return p;
412 }
413
414 inline uchar* Mat::ptr(int y)
415 {
416     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
417     return data + step.p[0]*y;
418 }
419
420 inline const uchar* Mat::ptr(int y) const
421 {
422     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
423     return data + step.p[0]*y;
424 }
425
426 template<typename _Tp> inline _Tp* Mat::ptr(int y)
427 {
428     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
429     return (_Tp*)(data + step.p[0]*y);
430 }
431
432 template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
433 {
434     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
435     return (const _Tp*)(data + step.p[0]*y);
436 }
437
438
439 inline uchar* Mat::ptr(int i0, int i1)
440 {
441     CV_DbgAssert( dims >= 2 && data &&
442                   (unsigned)i0 < (unsigned)size.p[0] &&
443                   (unsigned)i1 < (unsigned)size.p[1] );
444     return data + i0*step.p[0] + i1*step.p[1];
445 }
446
447 inline const uchar* Mat::ptr(int i0, int i1) const
448 {
449     CV_DbgAssert( dims >= 2 && data &&
450                  (unsigned)i0 < (unsigned)size.p[0] &&
451                  (unsigned)i1 < (unsigned)size.p[1] );
452     return data + i0*step.p[0] + i1*step.p[1];
453 }
454
455 template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1)
456 {
457     CV_DbgAssert( dims >= 2 && data &&
458                   (unsigned)i0 < (unsigned)size.p[0] &&
459                   (unsigned)i1 < (unsigned)size.p[1] );
460     return (_Tp*)(data + i0*step.p[0] + i1*step.p[1]);
461 }
462
463 template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1) const
464 {
465     CV_DbgAssert( dims >= 2 && data &&
466                   (unsigned)i0 < (unsigned)size.p[0] &&
467                   (unsigned)i1 < (unsigned)size.p[1] );
468     return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]);
469 }
470
471 inline uchar* Mat::ptr(int i0, int i1, int i2)
472 {
473     CV_DbgAssert( dims >= 3 && data &&
474                   (unsigned)i0 < (unsigned)size.p[0] &&
475                   (unsigned)i1 < (unsigned)size.p[1] &&
476                   (unsigned)i2 < (unsigned)size.p[2] );
477     return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
478 }
479
480 inline const uchar* Mat::ptr(int i0, int i1, int i2) const
481 {
482     CV_DbgAssert( dims >= 3 && data &&
483                   (unsigned)i0 < (unsigned)size.p[0] &&
484                   (unsigned)i1 < (unsigned)size.p[1] &&
485                   (unsigned)i2 < (unsigned)size.p[2] );
486     return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
487 }
488
489 template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1, int i2)
490 {
491     CV_DbgAssert( dims >= 3 && data &&
492                   (unsigned)i0 < (unsigned)size.p[0] &&
493                   (unsigned)i1 < (unsigned)size.p[1] &&
494                   (unsigned)i2 < (unsigned)size.p[2] );
495     return (_Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
496 }
497
498 template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1, int i2) const
499 {
500     CV_DbgAssert( dims >= 3 && data &&
501                   (unsigned)i0 < (unsigned)size.p[0] &&
502                   (unsigned)i1 < (unsigned)size.p[1] &&
503                   (unsigned)i2 < (unsigned)size.p[2] );
504     return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
505 }
506
507 inline uchar* Mat::ptr(const int* idx)
508 {
509     int i, d = dims;
510     uchar* p = data;
511     CV_DbgAssert( d >= 1 && p );
512     for( i = 0; i < d; i++ )
513     {
514         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
515         p += idx[i]*step.p[i];
516     }
517     return p;
518 }
519
520 inline const uchar* Mat::ptr(const int* idx) const
521 {
522     int i, d = dims;
523     uchar* p = data;
524     CV_DbgAssert( d >= 1 && p );
525     for( i = 0; i < d; i++ )
526     {
527         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
528         p += idx[i]*step.p[i];
529     }
530     return p;
531 }
532
533 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
534 {
535     CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
536         (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
537         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
538     return ((_Tp*)(data + step.p[0]*i0))[i1];
539 }
540
541 template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
542 {
543     CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
544         (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
545         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
546     return ((const _Tp*)(data + step.p[0]*i0))[i1];
547 }
548
549 template<typename _Tp> inline _Tp& Mat::at(Point pt)
550 {
551     CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
552         (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
553         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
554     return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
555 }
556
557 template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
558 {
559     CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
560         (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
561         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
562     return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
563 }
564
565 template<typename _Tp> inline _Tp& Mat::at(int i0)
566 {
567     CV_DbgAssert( dims <= 2 && data &&
568                  (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
569                  elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
570     if( isContinuous() || size.p[0] == 1 )
571         return ((_Tp*)data)[i0];
572     if( size.p[1] == 1 )
573         return *(_Tp*)(data + step.p[0]*i0);
574     int i = i0/cols, j = i0 - i*cols;
575     return ((_Tp*)(data + step.p[0]*i))[j];
576 }
577
578 template<typename _Tp> inline const _Tp& Mat::at(int i0) const
579 {
580     CV_DbgAssert( dims <= 2 && data &&
581                  (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
582                  elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
583     if( isContinuous() || size.p[0] == 1 )
584         return ((const _Tp*)data)[i0];
585     if( size.p[1] == 1 )
586         return *(const _Tp*)(data + step.p[0]*i0);
587     int i = i0/cols, j = i0 - i*cols;
588     return ((const _Tp*)(data + step.p[0]*i))[j];
589 }
590
591 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
592 {
593     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
594     return *(_Tp*)ptr(i0, i1, i2);
595 }
596 template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
597 {
598     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
599     return *(const _Tp*)ptr(i0, i1, i2);
600 }
601 template<typename _Tp> inline _Tp& Mat::at(const int* idx)
602 {
603     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
604     return *(_Tp*)ptr(idx);
605 }
606 template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
607 {
608     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
609     return *(const _Tp*)ptr(idx);
610 }
611 template<typename _Tp, int n> _Tp& Mat::at(const Vec<int, n>& idx)
612 {
613     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
614     return *(_Tp*)ptr(idx.val);
615 }
616 template<typename _Tp, int n> inline const _Tp& Mat::at(const Vec<int, n>& idx) const
617 {
618     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
619     return *(const _Tp*)ptr(idx.val);
620 }
621
622
623 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
624 {
625     CV_DbgAssert( elemSize() == sizeof(_Tp) );
626     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
627 }
628
629 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
630 {
631     CV_DbgAssert( elemSize() == sizeof(_Tp) );
632     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
633     it += total();
634     return it;
635 }
636
637 template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
638 {
639     CV_DbgAssert( elemSize() == sizeof(_Tp) );
640     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
641 }
642
643 template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
644 {
645     CV_DbgAssert( elemSize() == sizeof(_Tp) );
646     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
647     it += total();
648     return it;
649 }
650
651 template<typename _Tp> inline Mat::operator vector<_Tp>() const
652 {
653     vector<_Tp> v;
654     copyTo(v);
655     return v;
656 }
657
658 template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
659 {
660     CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
661                rows + cols - 1 == n && channels() == 1 );
662
663     if( isContinuous() && type() == DataType<_Tp>::type )
664         return Vec<_Tp, n>((_Tp*)data);
665     Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
666     convertTo(tmp, tmp.type());
667     return v;
668 }
669
670 template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
671 {
672     CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
673
674     if( isContinuous() && type() == DataType<_Tp>::type )
675         return Matx<_Tp, m, n>((_Tp*)data);
676     Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
677     convertTo(tmp, tmp.type());
678     return mtx;
679 }
680
681
682 template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
683 {
684     if( !data )
685     {
686         *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
687         return;
688     }
689     CV_Assert(DataType<_Tp>::type == type() && cols == 1
690               /* && dims == 2 (cols == 1 implies dims == 2) */);
691     uchar* tmp = dataend + step[0];
692     if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
693     {
694         *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem;
695         dataend = tmp;
696     }
697     else
698         push_back_(&elem);
699 }
700
701 template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
702 {
703     push_back((const Mat&)m);
704 }
705
706 inline Mat::MSize::MSize(int* _p) : p(_p) {}
707 inline Size Mat::MSize::operator()() const
708 {
709     CV_DbgAssert(p[-1] <= 2);
710     return Size(p[1], p[0]);
711 }
712 inline const int& Mat::MSize::operator[](int i) const { return p[i]; }
713 inline int& Mat::MSize::operator[](int i) { return p[i]; }
714 inline Mat::MSize::operator const int*() const { return p; }
715
716 inline bool Mat::MSize::operator == (const MSize& sz) const
717 {
718     int d = p[-1], dsz = sz.p[-1];
719     if( d != dsz )
720         return false;
721     if( d == 2 )
722         return p[0] == sz.p[0] && p[1] == sz.p[1];
723
724     for( int i = 0; i < d; i++ )
725         if( p[i] != sz.p[i] )
726             return false;
727     return true;
728 }
729
730 inline bool Mat::MSize::operator != (const MSize& sz) const
731 {
732     return !(*this == sz);
733 }
734
735 inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
736 inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
737 inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; }
738 inline size_t& Mat::MStep::operator[](int i) { return p[i]; }
739 inline Mat::MStep::operator size_t() const
740 {
741     CV_DbgAssert( p == buf );
742     return buf[0];
743 }
744 inline Mat::MStep& Mat::MStep::operator = (size_t s)
745 {
746     CV_DbgAssert( p == buf );
747     buf[0] = s;
748     return *this;
749 }
750
751 static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
752 {
753     return cvarrToMat(arr, copyData, true, coiMode);
754 }
755
756 ///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
757
758 inline SVD::SVD() {}
759 inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
760 inline void SVD::solveZ( InputArray m, OutputArray _dst )
761 {
762     Mat mtx = m.getMat();
763     SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
764     _dst.create(svd.vt.cols, 1, svd.vt.type());
765     Mat dst = _dst.getMat();
766     svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
767 }
768
769 template<typename _Tp, int m, int n, int nm> inline void
770     SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
771 {
772     assert( nm == MIN(m, n));
773     Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
774     SVD::compute(_a, _w, _u, _vt);
775     CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
776 }
777
778 template<typename _Tp, int m, int n, int nm> inline void
779 SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
780 {
781     assert( nm == MIN(m, n));
782     Mat _a(a, false), _w(w, false);
783     SVD::compute(_a, _w);
784     CV_Assert(_w.data == (uchar*)&w.val[0]);
785 }
786
787 template<typename _Tp, int m, int n, int nm, int nb> inline void
788 SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
789                 const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
790                 Matx<_Tp, n, nb>& dst )
791 {
792     assert( nm == MIN(m, n));
793     Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
794     SVD::backSubst(_w, _u, _vt, _rhs, _dst);
795     CV_Assert(_dst.data == (uchar*)&dst.val[0]);
796 }
797
798 ///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
799
800 template<typename _Tp> inline Mat_<_Tp>::Mat_()
801     : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
802
803 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
804     : Mat(_rows, _cols, DataType<_Tp>::type) {}
805
806 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
807     : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
808
809 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
810     : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
811
812 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
813     : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
814
815 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
816     : Mat(_dims, _sz, DataType<_Tp>::type) {}
817
818 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
819     : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
820
821 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
822     : Mat(m, ranges) {}
823
824 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
825     : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
826
827 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
828     : Mat(m) {}
829
830 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
831     : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
832
833 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
834     : Mat(m, _rowRange, _colRange) {}
835
836 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
837     : Mat(m, roi) {}
838
839 template<typename _Tp> template<int n> inline
840     Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
841     : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
842 {
843     CV_Assert(n%DataType<_Tp>::channels == 0);
844     if( copyData )
845         *this = clone();
846 }
847
848 template<typename _Tp> template<int m, int n> inline
849     Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n>& M, bool copyData)
850     : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
851 {
852     CV_Assert(n % DataType<_Tp>::channels == 0);
853     if( copyData )
854         *this = clone();
855 }
856
857 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
858     : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
859 {
860     CV_Assert(2 % DataType<_Tp>::channels == 0);
861     if( copyData )
862         *this = clone();
863 }
864
865 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
866     : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
867 {
868     CV_Assert(3 % DataType<_Tp>::channels == 0);
869     if( copyData )
870         *this = clone();
871 }
872
873 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
874     : Mat(commaInitializer) {}
875
876 template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
877     : Mat(vec, copyData) {}
878
879 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
880 {
881     if( DataType<_Tp>::type == m.type() )
882     {
883         Mat::operator = (m);
884         return *this;
885     }
886     if( DataType<_Tp>::depth == m.depth() )
887     {
888         return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
889     }
890     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
891     m.convertTo(*this, type());
892     return *this;
893 }
894
895 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
896 {
897     Mat::operator=(m);
898     return *this;
899 }
900
901 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
902 {
903     typedef typename DataType<_Tp>::vec_type VT;
904     Mat::operator=(Scalar((const VT&)s));
905     return *this;
906 }
907
908 template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
909 {
910     Mat::create(_rows, _cols, DataType<_Tp>::type);
911 }
912
913 template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
914 {
915     Mat::create(_sz, DataType<_Tp>::type);
916 }
917
918 template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
919 {
920     Mat::create(_dims, _sz, DataType<_Tp>::type);
921 }
922
923
924 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
925 { return Mat_<_Tp>(Mat::cross(m)); }
926
927 template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
928 { return Mat_<T2>(*this); }
929
930 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
931 { return Mat_(*this, Range(y, y+1), Range::all()); }
932 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
933 { return Mat_(*this, Range::all(), Range(x, x+1)); }
934 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
935 { return Mat_(Mat::diag(d)); }
936 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
937 { return Mat_(Mat::clone()); }
938
939 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
940 {
941     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
942     return sizeof(_Tp);
943 }
944
945 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
946 {
947     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
948     return sizeof(_Tp)/DataType<_Tp>::channels;
949 }
950 template<typename _Tp> inline int Mat_<_Tp>::type() const
951 {
952     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
953     return DataType<_Tp>::type;
954 }
955 template<typename _Tp> inline int Mat_<_Tp>::depth() const
956 {
957     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
958     return DataType<_Tp>::depth;
959 }
960 template<typename _Tp> inline int Mat_<_Tp>::channels() const
961 {
962     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
963     return DataType<_Tp>::channels;
964 }
965 template<typename _Tp> inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); }
966 template<typename _Tp> inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); }
967
968 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
969 { return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));  }
970
971 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
972 { return Mat_<_Tp>(*this, _rowRange, _colRange); }
973
974 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
975 { return Mat_<_Tp>(*this, roi); }
976
977 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
978 { return Mat_<_Tp>(*this, ranges); }
979
980 template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
981 { return (_Tp*)ptr(y); }
982 template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
983 { return (const _Tp*)ptr(y); }
984
985 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
986 {
987     CV_DbgAssert( dims <= 2 && data &&
988                   (unsigned)i0 < (unsigned)size.p[0] &&
989                   (unsigned)i1 < (unsigned)size.p[1] &&
990                   type() == DataType<_Tp>::type );
991     return ((_Tp*)(data + step.p[0]*i0))[i1];
992 }
993
994 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
995 {
996     CV_DbgAssert( dims <= 2 && data &&
997                   (unsigned)i0 < (unsigned)size.p[0] &&
998                   (unsigned)i1 < (unsigned)size.p[1] &&
999                   type() == DataType<_Tp>::type );
1000     return ((const _Tp*)(data + step.p[0]*i0))[i1];
1001 }
1002
1003 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
1004 {
1005     CV_DbgAssert( dims <= 2 && data &&
1006                   (unsigned)pt.y < (unsigned)size.p[0] &&
1007                   (unsigned)pt.x < (unsigned)size.p[1] &&
1008                   type() == DataType<_Tp>::type );
1009     return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
1010 }
1011
1012 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
1013 {
1014     CV_DbgAssert( dims <= 2 && data &&
1015                   (unsigned)pt.y < (unsigned)size.p[0] &&
1016                   (unsigned)pt.x < (unsigned)size.p[1] &&
1017                  type() == DataType<_Tp>::type );
1018     return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
1019 }
1020
1021 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
1022 {
1023     return Mat::at<_Tp>(idx);
1024 }
1025
1026 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
1027 {
1028     return Mat::at<_Tp>(idx);
1029 }
1030
1031 template<typename _Tp> template<int n> inline _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
1032 {
1033     return Mat::at<_Tp>(idx);
1034 }
1035
1036 template<typename _Tp> template<int n> inline const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
1037 {
1038     return Mat::at<_Tp>(idx);
1039 }
1040
1041 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
1042 {
1043     return this->at<_Tp>(i0);
1044 }
1045
1046 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
1047 {
1048     return this->at<_Tp>(i0);
1049 }
1050
1051 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
1052 {
1053     return this->at<_Tp>(i0, i1, i2);
1054 }
1055
1056 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
1057 {
1058     return this->at<_Tp>(i0, i1, i2);
1059 }
1060
1061
1062 template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
1063 {
1064     vector<_Tp> v;
1065     copyTo(v);
1066     return v;
1067 }
1068
1069 template<typename _Tp> template<int n> inline Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
1070 {
1071     CV_Assert(n % DataType<_Tp>::channels == 0);
1072     return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
1073 }
1074
1075 template<typename _Tp> template<int m, int n> inline Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
1076 {
1077     CV_Assert(n % DataType<_Tp>::channels == 0);
1078
1079     Matx<typename DataType<_Tp>::channel_type, m, n> res = this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
1080     return res;
1081 }
1082
1083 template<typename T1, typename T2, typename Op> inline void
1084 process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
1085 {
1086     int y, x, rows = m1.rows, cols = m1.cols;
1087
1088     CV_DbgAssert( m1.size() == m2.size() );
1089
1090     for( y = 0; y < rows; y++ )
1091     {
1092         const T1* src = m1[y];
1093         T2* dst = m2[y];
1094
1095         for( x = 0; x < cols; x++ )
1096             dst[x] = op(src[x]);
1097     }
1098 }
1099
1100 template<typename T1, typename T2, typename T3, typename Op> inline void
1101 process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
1102 {
1103     int y, x, rows = m1.rows, cols = m1.cols;
1104
1105     CV_DbgAssert( m1.size() == m2.size() );
1106
1107     for( y = 0; y < rows; y++ )
1108     {
1109         const T1* src1 = m1[y];
1110         const T2* src2 = m2[y];
1111         T3* dst = m3[y];
1112
1113         for( x = 0; x < cols; x++ )
1114             dst[x] = op( src1[x], src2[x] );
1115     }
1116 }
1117
1118
1119 /////////////////////////////// Input/Output Arrays /////////////////////////////////
1120
1121 template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec)
1122     : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
1123
1124 template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp> >& vec)
1125     : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
1126
1127 template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec)
1128     : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
1129
1130 template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
1131     : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
1132
1133 template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
1134     : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
1135
1136 inline _InputArray::_InputArray(const Scalar& s)
1137     : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&s), sz(1, 4) {}
1138
1139 template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m)
1140     : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {}
1141
1142 template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec)
1143     : _InputArray(vec) {}
1144 template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec)
1145     : _InputArray(vec) {}
1146 template<typename _Tp> inline _OutputArray::_OutputArray(vector<Mat_<_Tp> >& vec)
1147     : _InputArray(vec) {}
1148 template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m)
1149     : _InputArray(m) {}
1150 template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
1151     : _InputArray(mtx) {}
1152 template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n)
1153     : _InputArray(vec, n) {}
1154
1155 template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec)
1156     : _InputArray(vec) {flags |= FIXED_SIZE;}
1157 template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec)
1158     : _InputArray(vec) {flags |= FIXED_SIZE;}
1159 template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec)
1160     : _InputArray(vec) {flags |= FIXED_SIZE;}
1161
1162 template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m)
1163     : _InputArray(m) {flags |= FIXED_SIZE;}
1164 template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
1165     : _InputArray(mtx) {}
1166 template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n)
1167     : _InputArray(vec, n) {}
1168
1169 //////////////////////////////////// Matrix Expressions /////////////////////////////////////////
1170
1171 class CV_EXPORTS MatOp
1172 {
1173 public:
1174     MatOp() {};
1175     virtual ~MatOp() {};
1176
1177     virtual bool elementWise(const MatExpr& expr) const;
1178     virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
1179     virtual void roi(const MatExpr& expr, const Range& rowRange,
1180                      const Range& colRange, MatExpr& res) const;
1181     virtual void diag(const MatExpr& expr, int d, MatExpr& res) const;
1182     virtual void augAssignAdd(const MatExpr& expr, Mat& m) const;
1183     virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const;
1184     virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const;
1185     virtual void augAssignDivide(const MatExpr& expr, Mat& m) const;
1186     virtual void augAssignAnd(const MatExpr& expr, Mat& m) const;
1187     virtual void augAssignOr(const MatExpr& expr, Mat& m) const;
1188     virtual void augAssignXor(const MatExpr& expr, Mat& m) const;
1189
1190     virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
1191     virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const;
1192
1193     virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
1194     virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
1195
1196     virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
1197     virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const;
1198
1199     virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
1200     virtual void divide(double s, const MatExpr& expr, MatExpr& res) const;
1201
1202     virtual void abs(const MatExpr& expr, MatExpr& res) const;
1203
1204     virtual void transpose(const MatExpr& expr, MatExpr& res) const;
1205     virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
1206     virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
1207
1208     virtual Size size(const MatExpr& expr) const;
1209     virtual int type(const MatExpr& expr) const;
1210 };
1211
1212
1213 class CV_EXPORTS MatExpr
1214 {
1215 public:
1216     MatExpr() : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s(Scalar()) {}
1217     MatExpr(const MatOp* _op, int _flags, const Mat& _a=Mat(), const Mat& _b=Mat(),
1218             const Mat& _c=Mat(), double _alpha=1, double _beta=1, const Scalar& _s=Scalar())
1219         : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) {}
1220     explicit MatExpr(const Mat& m);
1221     operator Mat() const
1222     {
1223         Mat m;
1224         op->assign(*this, m);
1225         return m;
1226     }
1227
1228     template<typename _Tp> operator Mat_<_Tp>() const
1229     {
1230         Mat_<_Tp> m;
1231         op->assign(*this, m, DataType<_Tp>::type);
1232         return m;
1233     }
1234
1235     MatExpr row(int y) const;
1236     MatExpr col(int x) const;
1237     MatExpr diag(int d=0) const;
1238     MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
1239     MatExpr operator()( const Rect& roi ) const;
1240
1241     Mat cross(const Mat& m) const;
1242     double dot(const Mat& m) const;
1243
1244     MatExpr t() const;
1245     MatExpr inv(int method = DECOMP_LU) const;
1246     MatExpr mul(const MatExpr& e, double scale=1) const;
1247     MatExpr mul(const Mat& m, double scale=1) const;
1248
1249     Size size() const;
1250     int type() const;
1251
1252     const MatOp* op;
1253     int flags;
1254
1255     Mat a, b, c;
1256     double alpha, beta;
1257     Scalar s;
1258 };
1259
1260
1261 CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b);
1262 CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s);
1263 CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a);
1264 CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m);
1265 CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e);
1266 CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s);
1267 CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e);
1268 CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2);
1269
1270 CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b);
1271 CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s);
1272 CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a);
1273 CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m);
1274 CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e);
1275 CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s);
1276 CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e);
1277 CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2);
1278
1279 CV_EXPORTS MatExpr operator - (const Mat& m);
1280 CV_EXPORTS MatExpr operator - (const MatExpr& e);
1281
1282 CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);
1283 CV_EXPORTS MatExpr operator * (const Mat& a, double s);
1284 CV_EXPORTS MatExpr operator * (double s, const Mat& a);
1285 CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m);
1286 CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e);
1287 CV_EXPORTS MatExpr operator * (const MatExpr& e, double s);
1288 CV_EXPORTS MatExpr operator * (double s, const MatExpr& e);
1289 CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2);
1290
1291 CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b);
1292 CV_EXPORTS MatExpr operator / (const Mat& a, double s);
1293 CV_EXPORTS MatExpr operator / (double s, const Mat& a);
1294 CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m);
1295 CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e);
1296 CV_EXPORTS MatExpr operator / (const MatExpr& e, double s);
1297 CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
1298 CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
1299
1300 CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b);
1301 CV_EXPORTS MatExpr operator < (const Mat& a, double s);
1302 CV_EXPORTS MatExpr operator < (double s, const Mat& a);
1303
1304 CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b);
1305 CV_EXPORTS MatExpr operator <= (const Mat& a, double s);
1306 CV_EXPORTS MatExpr operator <= (double s, const Mat& a);
1307
1308 CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b);
1309 CV_EXPORTS MatExpr operator == (const Mat& a, double s);
1310 CV_EXPORTS MatExpr operator == (double s, const Mat& a);
1311
1312 CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b);
1313 CV_EXPORTS MatExpr operator != (const Mat& a, double s);
1314 CV_EXPORTS MatExpr operator != (double s, const Mat& a);
1315
1316 CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b);
1317 CV_EXPORTS MatExpr operator >= (const Mat& a, double s);
1318 CV_EXPORTS MatExpr operator >= (double s, const Mat& a);
1319
1320 CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b);
1321 CV_EXPORTS MatExpr operator > (const Mat& a, double s);
1322 CV_EXPORTS MatExpr operator > (double s, const Mat& a);
1323
1324 CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
1325 CV_EXPORTS MatExpr min(const Mat& a, double s);
1326 CV_EXPORTS MatExpr min(double s, const Mat& a);
1327
1328 CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
1329 CV_EXPORTS MatExpr max(const Mat& a, double s);
1330 CV_EXPORTS MatExpr max(double s, const Mat& a);
1331
1332 template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1333 {
1334     return cv::min((const Mat&)a, (const Mat&)b);
1335 }
1336
1337 template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, double s)
1338 {
1339     return cv::min((const Mat&)a, s);
1340 }
1341
1342 template<typename _Tp> static inline MatExpr min(double s, const Mat_<_Tp>& a)
1343 {
1344     return cv::min((const Mat&)a, s);
1345 }
1346
1347 template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1348 {
1349     return cv::max((const Mat&)a, (const Mat&)b);
1350 }
1351
1352 template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, double s)
1353 {
1354     return cv::max((const Mat&)a, s);
1355 }
1356
1357 template<typename _Tp> static inline MatExpr max(double s, const Mat_<_Tp>& a)
1358 {
1359     return cv::max((const Mat&)a, s);
1360 }
1361
1362 template<typename _Tp> static inline void min(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
1363 {
1364     cv::min((const Mat&)a, (const Mat&)b, (Mat&)c);
1365 }
1366
1367 template<typename _Tp> static inline void min(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c)
1368 {
1369     cv::min((const Mat&)a, s, (Mat&)c);
1370 }
1371
1372 template<typename _Tp> static inline void min(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c)
1373 {
1374     cv::min((const Mat&)a, s, (Mat&)c);
1375 }
1376
1377 template<typename _Tp> static inline void max(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
1378 {
1379     cv::max((const Mat&)a, (const Mat&)b, (Mat&)c);
1380 }
1381
1382 template<typename _Tp> static inline void max(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c)
1383 {
1384     cv::max((const Mat&)a, s, (Mat&)c);
1385 }
1386
1387 template<typename _Tp> static inline void max(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c)
1388 {
1389     cv::max((const Mat&)a, s, (Mat&)c);
1390 }
1391
1392
1393 CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
1394 CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
1395 CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
1396
1397 CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b);
1398 CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s);
1399 CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a);
1400
1401 CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b);
1402 CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s);
1403 CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a);
1404
1405 CV_EXPORTS MatExpr operator ~(const Mat& m);
1406
1407 CV_EXPORTS MatExpr abs(const Mat& m);
1408 CV_EXPORTS MatExpr abs(const MatExpr& e);
1409
1410 template<typename _Tp> static inline MatExpr abs(const Mat_<_Tp>& m)
1411 {
1412     return cv::abs((const Mat&)m);
1413 }
1414
1415 ////////////////////////////// Augmenting algebraic operations //////////////////////////////////
1416
1417 inline Mat& Mat::operator = (const MatExpr& e)
1418 {
1419     e.op->assign(e, *this);
1420     return *this;
1421 }
1422
1423 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr& e)
1424 {
1425     e.op->assign(e, *this, DataType<_Tp>::type);
1426 }
1427
1428 template<typename _Tp> Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
1429 {
1430     e.op->assign(e, *this, DataType<_Tp>::type);
1431     return *this;
1432 }
1433
1434 static inline Mat& operator += (const Mat& a, const Mat& b)
1435 {
1436     add(a, b, (Mat&)a);
1437     return (Mat&)a;
1438 }
1439
1440 static inline Mat& operator += (const Mat& a, const Scalar& s)
1441 {
1442     add(a, s, (Mat&)a);
1443     return (Mat&)a;
1444 }
1445
1446 template<typename _Tp> static inline
1447 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1448 {
1449     add(a, b, (Mat&)a);
1450     return (Mat_<_Tp>&)a;
1451 }
1452
1453 template<typename _Tp> static inline
1454 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s)
1455 {
1456     add(a, s, (Mat&)a);
1457     return (Mat_<_Tp>&)a;
1458 }
1459
1460 static inline Mat& operator += (const Mat& a, const MatExpr& b)
1461 {
1462     b.op->augAssignAdd(b, (Mat&)a);
1463     return (Mat&)a;
1464 }
1465
1466 template<typename _Tp> static inline
1467 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
1468 {
1469     b.op->augAssignAdd(b, (Mat&)a);
1470     return (Mat_<_Tp>&)a;
1471 }
1472
1473 static inline Mat& operator -= (const Mat& a, const Mat& b)
1474 {
1475     subtract(a, b, (Mat&)a);
1476     return (Mat&)a;
1477 }
1478
1479 static inline Mat& operator -= (const Mat& a, const Scalar& s)
1480 {
1481     subtract(a, s, (Mat&)a);
1482     return (Mat&)a;
1483 }
1484
1485 template<typename _Tp> static inline
1486 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1487 {
1488     subtract(a, b, (Mat&)a);
1489     return (Mat_<_Tp>&)a;
1490 }
1491
1492 template<typename _Tp> static inline
1493 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s)
1494 {
1495     subtract(a, s, (Mat&)a);
1496     return (Mat_<_Tp>&)a;
1497 }
1498
1499 static inline Mat& operator -= (const Mat& a, const MatExpr& b)
1500 {
1501     b.op->augAssignSubtract(b, (Mat&)a);
1502     return (Mat&)a;
1503 }
1504
1505 template<typename _Tp> static inline
1506 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
1507 {
1508     b.op->augAssignSubtract(b, (Mat&)a);
1509     return (Mat_<_Tp>&)a;
1510 }
1511
1512 static inline Mat& operator *= (const Mat& a, const Mat& b)
1513 {
1514     gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
1515     return (Mat&)a;
1516 }
1517
1518 static inline Mat& operator *= (const Mat& a, double s)
1519 {
1520     a.convertTo((Mat&)a, -1, s);
1521     return (Mat&)a;
1522 }
1523
1524 template<typename _Tp> static inline
1525 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1526 {
1527     gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
1528     return (Mat_<_Tp>&)a;
1529 }
1530
1531 template<typename _Tp> static inline
1532 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, double s)
1533 {
1534     a.convertTo((Mat&)a, -1, s);
1535     return (Mat_<_Tp>&)a;
1536 }
1537
1538 static inline Mat& operator *= (const Mat& a, const MatExpr& b)
1539 {
1540     b.op->augAssignMultiply(b, (Mat&)a);
1541     return (Mat&)a;
1542 }
1543
1544 template<typename _Tp> static inline
1545 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
1546 {
1547     b.op->augAssignMultiply(b, (Mat&)a);
1548     return (Mat_<_Tp>&)a;
1549 }
1550
1551 static inline Mat& operator /= (const Mat& a, const Mat& b)
1552 {
1553     divide(a, b, (Mat&)a);
1554     return (Mat&)a;
1555 }
1556
1557 static inline Mat& operator /= (const Mat& a, double s)
1558 {
1559     a.convertTo((Mat&)a, -1, 1./s);
1560     return (Mat&)a;
1561 }
1562
1563 template<typename _Tp> static inline
1564 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1565 {
1566     divide(a, b, (Mat&)a);
1567     return (Mat_<_Tp>&)a;
1568 }
1569
1570 template<typename _Tp> static inline
1571 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double s)
1572 {
1573     a.convertTo((Mat&)a, -1, 1./s);
1574     return (Mat_<_Tp>&)a;
1575 }
1576
1577 static inline Mat& operator /= (const Mat& a, const MatExpr& b)
1578 {
1579     b.op->augAssignDivide(b, (Mat&)a);
1580     return (Mat&)a;
1581 }
1582
1583 template<typename _Tp> static inline
1584 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
1585 {
1586     b.op->augAssignDivide(b, (Mat&)a);
1587     return (Mat_<_Tp>&)a;
1588 }
1589
1590 ////////////////////////////// Logical operations ///////////////////////////////
1591
1592 static inline Mat& operator &= (const Mat& a, const Mat& b)
1593 {
1594     bitwise_and(a, b, (Mat&)a);
1595     return (Mat&)a;
1596 }
1597
1598 static inline Mat& operator &= (const Mat& a, const Scalar& s)
1599 {
1600     bitwise_and(a, s, (Mat&)a);
1601     return (Mat&)a;
1602 }
1603
1604 template<typename _Tp> static inline Mat_<_Tp>&
1605 operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1606 {
1607     bitwise_and(a, b, (Mat&)a);
1608     return (Mat_<_Tp>&)a;
1609 }
1610
1611 template<typename _Tp> static inline Mat_<_Tp>&
1612 operator &= (const Mat_<_Tp>& a, const Scalar& s)
1613 {
1614     bitwise_and(a, s, (Mat&)a);
1615     return (Mat_<_Tp>&)a;
1616 }
1617
1618 static inline Mat& operator |= (const Mat& a, const Mat& b)
1619 {
1620     bitwise_or(a, b, (Mat&)a);
1621     return (Mat&)a;
1622 }
1623
1624 static inline Mat& operator |= (const Mat& a, const Scalar& s)
1625 {
1626     bitwise_or(a, s, (Mat&)a);
1627     return (Mat&)a;
1628 }
1629
1630 template<typename _Tp> static inline Mat_<_Tp>&
1631 operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1632 {
1633     bitwise_or(a, b, (Mat&)a);
1634     return (Mat_<_Tp>&)a;
1635 }
1636
1637 template<typename _Tp> static inline Mat_<_Tp>&
1638 operator |= (const Mat_<_Tp>& a, const Scalar& s)
1639 {
1640     bitwise_or(a, s, (Mat&)a);
1641     return (Mat_<_Tp>&)a;
1642 }
1643
1644 static inline Mat& operator ^= (const Mat& a, const Mat& b)
1645 {
1646     bitwise_xor(a, b, (Mat&)a);
1647     return (Mat&)a;
1648 }
1649
1650 static inline Mat& operator ^= (const Mat& a, const Scalar& s)
1651 {
1652     bitwise_xor(a, s, (Mat&)a);
1653     return (Mat&)a;
1654 }
1655
1656 template<typename _Tp> static inline Mat_<_Tp>&
1657 operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1658 {
1659     bitwise_xor(a, b, (Mat&)a);
1660     return (Mat_<_Tp>&)a;
1661 }
1662
1663 template<typename _Tp> static inline Mat_<_Tp>&
1664 operator ^= (const Mat_<_Tp>& a, const Scalar& s)
1665 {
1666     bitwise_xor(a, s, (Mat&)a);
1667     return (Mat_<_Tp>&)a;
1668 }
1669
1670 /////////////////////////////// Miscellaneous operations //////////////////////////////
1671
1672 template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
1673 { split(src, (vector<Mat>&)mv ); }
1674
1675 //////////////////////////////////////////////////////////////
1676
1677 template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(int rows, int cols)
1678 {
1679     return Mat::zeros(rows, cols, DataType<_Tp>::type);
1680 }
1681
1682 template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(Size sz)
1683 {
1684     return Mat::zeros(sz, DataType<_Tp>::type);
1685 }
1686
1687 template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(int rows, int cols)
1688 {
1689     return Mat::ones(rows, cols, DataType<_Tp>::type);
1690 }
1691
1692 template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(Size sz)
1693 {
1694     return Mat::ones(sz, DataType<_Tp>::type);
1695 }
1696
1697 template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(int rows, int cols)
1698 {
1699     return Mat::eye(rows, cols, DataType<_Tp>::type);
1700 }
1701
1702 template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(Size sz)
1703 {
1704     return Mat::eye(sz, DataType<_Tp>::type);
1705 }
1706
1707 //////////////////////////////// Iterators & Comma initializers //////////////////////////////////
1708
1709 inline MatConstIterator::MatConstIterator()
1710     : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {}
1711
1712 inline MatConstIterator::MatConstIterator(const Mat* _m)
1713     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
1714 {
1715     if( m && m->isContinuous() )
1716     {
1717         sliceStart = m->data;
1718         sliceEnd = sliceStart + m->total()*elemSize;
1719     }
1720     seek((const int*)0);
1721 }
1722
1723 inline MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
1724     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
1725 {
1726     CV_Assert(m && m->dims <= 2);
1727     if( m->isContinuous() )
1728     {
1729         sliceStart = m->data;
1730         sliceEnd = sliceStart + m->total()*elemSize;
1731     }
1732     int idx[]={_row, _col};
1733     seek(idx);
1734 }
1735
1736 inline MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
1737     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
1738 {
1739     CV_Assert(m && m->dims <= 2);
1740     if( m->isContinuous() )
1741     {
1742         sliceStart = m->data;
1743         sliceEnd = sliceStart + m->total()*elemSize;
1744     }
1745     int idx[]={_pt.y, _pt.x};
1746     seek(idx);
1747 }
1748
1749 inline MatConstIterator::MatConstIterator(const MatConstIterator& it)
1750     : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
1751 {}
1752
1753 inline MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
1754 {
1755     m = it.m; elemSize = it.elemSize; ptr = it.ptr;
1756     sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
1757     return *this;
1758 }
1759
1760 inline uchar* MatConstIterator::operator *() const { return ptr; }
1761
1762 inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
1763 {
1764     if( !m || ofs == 0 )
1765         return *this;
1766     ptrdiff_t ofsb = ofs*elemSize;
1767     ptr += ofsb;
1768     if( ptr < sliceStart || sliceEnd <= ptr )
1769     {
1770         ptr -= ofsb;
1771         seek(ofs, true);
1772     }
1773     return *this;
1774 }
1775
1776 inline MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
1777 { return (*this += -ofs); }
1778
1779 inline MatConstIterator& MatConstIterator::operator --()
1780 {
1781     if( m && (ptr -= elemSize) < sliceStart )
1782     {
1783         ptr += elemSize;
1784         seek(-1, true);
1785     }
1786     return *this;
1787 }
1788
1789 inline MatConstIterator MatConstIterator::operator --(int)
1790 {
1791     MatConstIterator b = *this;
1792     *this += -1;
1793     return b;
1794 }
1795
1796 inline MatConstIterator& MatConstIterator::operator ++()
1797 {
1798     if( m && (ptr += elemSize) >= sliceEnd )
1799     {
1800         ptr -= elemSize;
1801         seek(1, true);
1802     }
1803     return *this;
1804 }
1805
1806 inline MatConstIterator MatConstIterator::operator ++(int)
1807 {
1808     MatConstIterator b = *this;
1809     *this += 1;
1810     return b;
1811 }
1812
1813 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_() {}
1814
1815 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
1816     : MatConstIterator(_m) {}
1817
1818 template<typename _Tp> inline MatConstIterator_<_Tp>::
1819     MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
1820     : MatConstIterator(_m, _row, _col) {}
1821
1822 template<typename _Tp> inline MatConstIterator_<_Tp>::
1823     MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
1824     : MatConstIterator(_m, _pt) {}
1825
1826 template<typename _Tp> inline MatConstIterator_<_Tp>::
1827     MatConstIterator_(const MatConstIterator_& it)
1828     : MatConstIterator(it) {}
1829
1830 template<typename _Tp> inline MatConstIterator_<_Tp>&
1831     MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
1832 {
1833     MatConstIterator::operator = (it);
1834     return *this;
1835 }
1836
1837 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
1838
1839 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
1840 {
1841     MatConstIterator::operator += (ofs);
1842     return *this;
1843 }
1844
1845 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
1846 { return (*this += -ofs); }
1847
1848 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
1849 {
1850     MatConstIterator::operator --();
1851     return *this;
1852 }
1853
1854 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
1855 {
1856     MatConstIterator_ b = *this;
1857     MatConstIterator::operator --();
1858     return b;
1859 }
1860
1861 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
1862 {
1863     MatConstIterator::operator ++();
1864     return *this;
1865 }
1866
1867 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
1868 {
1869     MatConstIterator_ b = *this;
1870     MatConstIterator::operator ++();
1871     return b;
1872 }
1873
1874 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
1875
1876 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
1877     : MatConstIterator_<_Tp>(_m) {}
1878
1879 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
1880     : MatConstIterator_<_Tp>(_m, _row, _col) {}
1881
1882 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
1883     : MatConstIterator_<_Tp>(_m, _pt) {}
1884
1885 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
1886     : MatConstIterator_<_Tp>(_m, _idx) {}
1887
1888 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
1889     : MatConstIterator_<_Tp>(it) {}
1890
1891 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
1892 {
1893     MatConstIterator::operator = (it);
1894     return *this;
1895 }
1896
1897 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
1898
1899 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
1900 {
1901     MatConstIterator::operator += (ofs);
1902     return *this;
1903 }
1904
1905 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
1906 {
1907     MatConstIterator::operator += (-ofs);
1908     return *this;
1909 }
1910
1911 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
1912 {
1913     MatConstIterator::operator --();
1914     return *this;
1915 }
1916
1917 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
1918 {
1919     MatIterator_ b = *this;
1920     MatConstIterator::operator --();
1921     return b;
1922 }
1923
1924 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
1925 {
1926     MatConstIterator::operator ++();
1927     return *this;
1928 }
1929
1930 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
1931 {
1932     MatIterator_ b = *this;
1933     MatConstIterator::operator ++();
1934     return b;
1935 }
1936
1937 template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
1938 {
1939     if( !m )
1940         return Point();
1941     CV_DbgAssert( m->dims <= 2 );
1942     if( m->isContinuous() )
1943     {
1944         ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
1945         int y = (int)(ofs / m->cols), x = (int)(ofs - (ptrdiff_t)y*m->cols);
1946         return Point(x, y);
1947     }
1948     else
1949     {
1950         ptrdiff_t ofs = (uchar*)ptr - m->data;
1951         int y = (int)(ofs / m->step), x = (int)((ofs - y*m->step)/sizeof(_Tp));
1952         return Point(x, y);
1953     }
1954 }
1955
1956 static inline bool
1957 operator == (const MatConstIterator& a, const MatConstIterator& b)
1958 { return a.m == b.m && a.ptr == b.ptr; }
1959
1960 template<typename _Tp> static inline bool
1961 operator != (const MatConstIterator& a, const MatConstIterator& b)
1962 { return !(a == b); }
1963
1964 template<typename _Tp> static inline bool
1965 operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
1966 { return a.m == b.m && a.ptr == b.ptr; }
1967
1968 template<typename _Tp> static inline bool
1969 operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
1970 { return a.m != b.m || a.ptr != b.ptr; }
1971
1972 template<typename _Tp> static inline bool
1973 operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
1974 { return a.m == b.m && a.ptr == b.ptr; }
1975
1976 template<typename _Tp> static inline bool
1977 operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
1978 { return a.m != b.m || a.ptr != b.ptr; }
1979
1980 static inline bool
1981 operator < (const MatConstIterator& a, const MatConstIterator& b)
1982 { return a.ptr < b.ptr; }
1983
1984 static inline bool
1985 operator > (const MatConstIterator& a, const MatConstIterator& b)
1986 { return a.ptr > b.ptr; }
1987
1988 static inline bool
1989 operator <= (const MatConstIterator& a, const MatConstIterator& b)
1990 { return a.ptr <= b.ptr; }
1991
1992 static inline bool
1993 operator >= (const MatConstIterator& a, const MatConstIterator& b)
1994 { return a.ptr >= b.ptr; }
1995
1996 CV_EXPORTS ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a);
1997
1998 static inline MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
1999 { MatConstIterator b = a; return b += ofs; }
2000
2001 static inline MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
2002 { MatConstIterator b = a; return b += ofs; }
2003
2004 static inline MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
2005 { MatConstIterator b = a; return b += -ofs; }
2006
2007 template<typename _Tp> static inline MatConstIterator_<_Tp>
2008 operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
2009 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
2010
2011 template<typename _Tp> static inline MatConstIterator_<_Tp>
2012 operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
2013 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
2014
2015 template<typename _Tp> static inline MatConstIterator_<_Tp>
2016 operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
2017 { MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatConstIterator_<_Tp>&)t; }
2018
2019 inline uchar* MatConstIterator::operator [](ptrdiff_t i) const
2020 { return *(*this + i); }
2021
2022 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
2023 { return *(_Tp*)MatConstIterator::operator [](i); }
2024
2025 template<typename _Tp> static inline MatIterator_<_Tp>
2026 operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
2027 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
2028
2029 template<typename _Tp> static inline MatIterator_<_Tp>
2030 operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
2031 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
2032
2033 template<typename _Tp> static inline MatIterator_<_Tp>
2034 operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
2035 { MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatIterator_<_Tp>&)t; }
2036
2037 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
2038 { return *(*this + i); }
2039
2040 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
2041 { return Mat::begin<_Tp>(); }
2042
2043 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const
2044 { return Mat::end<_Tp>(); }
2045
2046 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::begin()
2047 { return Mat::begin<_Tp>(); }
2048
2049 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::end()
2050 { return Mat::end<_Tp>(); }
2051
2052 template<typename _Tp> inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : it(_m) {}
2053
2054 template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
2055 MatCommaInitializer_<_Tp>::operator , (T2 v)
2056 {
2057     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
2058     *this->it = _Tp(v); ++this->it;
2059     return *this;
2060 }
2061
2062 template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
2063 {
2064     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
2065     return Mat_<_Tp>(*this->it.m);
2066 }
2067
2068 template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
2069 {
2070     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
2071     return Mat_<_Tp>(*this->it.m);
2072 }
2073
2074 template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
2075 operator << (const Mat_<_Tp>& m, T2 val)
2076 {
2077     MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
2078     return (commaInitializer, val);
2079 }
2080
2081 //////////////////////////////// SparseMat ////////////////////////////////
2082
2083 inline SparseMat::SparseMat()
2084 : flags(MAGIC_VAL), hdr(0)
2085 {
2086 }
2087
2088 inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
2089 : flags(MAGIC_VAL), hdr(0)
2090 {
2091     create(_dims, _sizes, _type);
2092 }
2093
2094 inline SparseMat::SparseMat(const SparseMat& m)
2095 : flags(m.flags), hdr(m.hdr)
2096 {
2097     addref();
2098 }
2099
2100 inline SparseMat::~SparseMat()
2101 {
2102     release();
2103 }
2104
2105 inline SparseMat& SparseMat::operator = (const SparseMat& m)
2106 {
2107     if( this != &m )
2108     {
2109         if( m.hdr )
2110             CV_XADD(&m.hdr->refcount, 1);
2111         release();
2112         flags = m.flags;
2113         hdr = m.hdr;
2114     }
2115     return *this;
2116 }
2117
2118 inline SparseMat& SparseMat::operator = (const Mat& m)
2119 { return (*this = SparseMat(m)); }
2120
2121 inline SparseMat SparseMat::clone() const
2122 {
2123     SparseMat temp;
2124     this->copyTo(temp);
2125     return temp;
2126 }
2127
2128
2129 inline void SparseMat::assignTo( SparseMat& m, int _type ) const
2130 {
2131     if( _type < 0 )
2132         m = *this;
2133     else
2134         convertTo(m, _type);
2135 }
2136
2137 inline void SparseMat::addref()
2138 { if( hdr ) CV_XADD(&hdr->refcount, 1); }
2139
2140 inline void SparseMat::release()
2141 {
2142     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
2143         delete hdr;
2144     hdr = 0;
2145 }
2146
2147 inline size_t SparseMat::elemSize() const
2148 { return CV_ELEM_SIZE(flags); }
2149
2150 inline size_t SparseMat::elemSize1() const
2151 { return CV_ELEM_SIZE1(flags); }
2152
2153 inline int SparseMat::type() const
2154 { return CV_MAT_TYPE(flags); }
2155
2156 inline int SparseMat::depth() const
2157 { return CV_MAT_DEPTH(flags); }
2158
2159 inline int SparseMat::channels() const
2160 { return CV_MAT_CN(flags); }
2161
2162 inline const int* SparseMat::size() const
2163 {
2164     return hdr ? hdr->size : 0;
2165 }
2166
2167 inline int SparseMat::size(int i) const
2168 {
2169     if( hdr )
2170     {
2171         CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
2172         return hdr->size[i];
2173     }
2174     return 0;
2175 }
2176
2177 inline int SparseMat::dims() const
2178 {
2179     return hdr ? hdr->dims : 0;
2180 }
2181
2182 inline size_t SparseMat::nzcount() const
2183 {
2184     return hdr ? hdr->nodeCount : 0;
2185 }
2186
2187 inline size_t SparseMat::hash(int i0) const
2188 {
2189     return (size_t)i0;
2190 }
2191
2192 inline size_t SparseMat::hash(int i0, int i1) const
2193 {
2194     return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1;
2195 }
2196
2197 inline size_t SparseMat::hash(int i0, int i1, int i2) const
2198 {
2199     return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2;
2200 }
2201
2202 inline size_t SparseMat::hash(const int* idx) const
2203 {
2204     size_t h = (unsigned)idx[0];
2205     if( !hdr )
2206         return 0;
2207     int i, d = hdr->dims;
2208     for( i = 1; i < d; i++ )
2209         h = h*HASH_SCALE + (unsigned)idx[i];
2210     return h;
2211 }
2212
2213 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
2214 { return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
2215
2216 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
2217 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
2218
2219 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
2220 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
2221
2222 template<typename _Tp> inline _Tp& SparseMat::ref(const int* idx, size_t* hashval)
2223 { return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
2224
2225 template<typename _Tp> inline _Tp SparseMat::value(int i0, size_t* hashval) const
2226 {
2227     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
2228     return p ? *p : _Tp();
2229 }
2230
2231 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
2232 {
2233     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
2234     return p ? *p : _Tp();
2235 }
2236
2237 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
2238 {
2239     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
2240     return p ? *p : _Tp();
2241 }
2242
2243 template<typename _Tp> inline _Tp SparseMat::value(const int* idx, size_t* hashval) const
2244 {
2245     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
2246     return p ? *p : _Tp();
2247 }
2248
2249 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
2250 { return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); }
2251
2252 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
2253 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); }
2254
2255 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
2256 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); }
2257
2258 template<typename _Tp> inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
2259 { return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); }
2260
2261 template<typename _Tp> inline _Tp& SparseMat::value(Node* n)
2262 { return *(_Tp*)((uchar*)n + hdr->valueOffset); }
2263
2264 template<typename _Tp> inline const _Tp& SparseMat::value(const Node* n) const
2265 { return *(const _Tp*)((const uchar*)n + hdr->valueOffset); }
2266
2267 inline SparseMat::Node* SparseMat::node(size_t nidx)
2268 { return (Node*)(void*)&hdr->pool[nidx]; }
2269
2270 inline const SparseMat::Node* SparseMat::node(size_t nidx) const
2271 { return (const Node*)(void*)&hdr->pool[nidx]; }
2272
2273 inline SparseMatIterator SparseMat::begin()
2274 { return SparseMatIterator(this); }
2275
2276 inline SparseMatConstIterator SparseMat::begin() const
2277 { return SparseMatConstIterator(this); }
2278
2279 inline SparseMatIterator SparseMat::end()
2280 { SparseMatIterator it(this); it.seekEnd(); return it; }
2281
2282 inline SparseMatConstIterator SparseMat::end() const
2283 { SparseMatConstIterator it(this); it.seekEnd(); return it; }
2284
2285 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
2286 { return SparseMatIterator_<_Tp>(this); }
2287
2288 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
2289 { return SparseMatConstIterator_<_Tp>(this); }
2290
2291 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
2292 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
2293
2294 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
2295 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
2296
2297
2298 inline SparseMatConstIterator::SparseMatConstIterator()
2299 : m(0), hashidx(0), ptr(0)
2300 {
2301 }
2302
2303 inline SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
2304 : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
2305 {
2306 }
2307
2308 static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
2309 { return it1.m == it2.m && it1.ptr == it2.ptr; }
2310
2311 static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
2312 { return !(it1 == it2); }
2313
2314
2315 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
2316 {
2317     if( this != &it )
2318     {
2319         m = it.m;
2320         hashidx = it.hashidx;
2321         ptr = it.ptr;
2322     }
2323     return *this;
2324 }
2325
2326 template<typename _Tp> inline const _Tp& SparseMatConstIterator::value() const
2327 { return *(_Tp*)ptr; }
2328
2329 inline const SparseMat::Node* SparseMatConstIterator::node() const
2330 {
2331     return ptr && m && m->hdr ?
2332         (const SparseMat::Node*)(void*)(ptr - m->hdr->valueOffset) : 0;
2333 }
2334
2335 inline SparseMatConstIterator SparseMatConstIterator::operator ++(int)
2336 {
2337     SparseMatConstIterator it = *this;
2338     ++*this;
2339     return it;
2340 }
2341
2342
2343 inline void SparseMatConstIterator::seekEnd()
2344 {
2345     if( m && m->hdr )
2346     {
2347         hashidx = m->hdr->hashtab.size();
2348         ptr = 0;
2349     }
2350 }
2351
2352 inline SparseMatIterator::SparseMatIterator()
2353 {}
2354
2355 inline SparseMatIterator::SparseMatIterator(SparseMat* _m)
2356 : SparseMatConstIterator(_m)
2357 {}
2358
2359 inline SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
2360 : SparseMatConstIterator(it)
2361 {
2362 }
2363
2364 inline SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
2365 {
2366     (SparseMatConstIterator&)*this = it;
2367     return *this;
2368 }
2369
2370 template<typename _Tp> inline _Tp& SparseMatIterator::value() const
2371 { return *(_Tp*)ptr; }
2372
2373 inline SparseMat::Node* SparseMatIterator::node() const
2374 {
2375     return (SparseMat::Node*)SparseMatConstIterator::node();
2376 }
2377
2378 inline SparseMatIterator& SparseMatIterator::operator ++()
2379 {
2380     SparseMatConstIterator::operator ++();
2381     return *this;
2382 }
2383
2384 inline SparseMatIterator SparseMatIterator::operator ++(int)
2385 {
2386     SparseMatIterator it = *this;
2387     ++*this;
2388     return it;
2389 }
2390
2391
2392 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_()
2393 { flags = MAGIC_VAL | DataType<_Tp>::type; }
2394
2395 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
2396 : SparseMat(_dims, _sizes, DataType<_Tp>::type)
2397 {}
2398
2399 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
2400 {
2401     if( m.type() == DataType<_Tp>::type )
2402         *this = (const SparseMat_<_Tp>&)m;
2403     else
2404         m.convertTo(this, DataType<_Tp>::type);
2405 }
2406
2407 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
2408 {
2409     this->flags = m.flags;
2410     this->hdr = m.hdr;
2411     if( this->hdr )
2412         CV_XADD(&this->hdr->refcount, 1);
2413 }
2414
2415 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const Mat& m)
2416 {
2417     SparseMat sm(m);
2418     *this = sm;
2419 }
2420
2421 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
2422 {
2423     SparseMat sm(m);
2424     *this = sm;
2425 }
2426
2427 template<typename _Tp> inline SparseMat_<_Tp>&
2428 SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
2429 {
2430     if( this != &m )
2431     {
2432         if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
2433         release();
2434         flags = m.flags;
2435         hdr = m.hdr;
2436     }
2437     return *this;
2438 }
2439
2440 template<typename _Tp> inline SparseMat_<_Tp>&
2441 SparseMat_<_Tp>::operator = (const SparseMat& m)
2442 {
2443     if( m.type() == DataType<_Tp>::type )
2444         return (*this = (const SparseMat_<_Tp>&)m);
2445     m.convertTo(*this, DataType<_Tp>::type);
2446     return *this;
2447 }
2448
2449 template<typename _Tp> inline SparseMat_<_Tp>&
2450 SparseMat_<_Tp>::operator = (const Mat& m)
2451 { return (*this = SparseMat(m)); }
2452
2453 template<typename _Tp> inline SparseMat_<_Tp>
2454 SparseMat_<_Tp>::clone() const
2455 {
2456     SparseMat_<_Tp> m;
2457     this->copyTo(m);
2458     return m;
2459 }
2460
2461 template<typename _Tp> inline void
2462 SparseMat_<_Tp>::create(int _dims, const int* _sizes)
2463 {
2464     SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
2465 }
2466
2467 template<typename _Tp> inline
2468 SparseMat_<_Tp>::operator CvSparseMat*() const
2469 {
2470     return SparseMat::operator CvSparseMat*();
2471 }
2472
2473 template<typename _Tp> inline int SparseMat_<_Tp>::type() const
2474 { return DataType<_Tp>::type; }
2475
2476 template<typename _Tp> inline int SparseMat_<_Tp>::depth() const
2477 { return DataType<_Tp>::depth; }
2478
2479 template<typename _Tp> inline int SparseMat_<_Tp>::channels() const
2480 { return DataType<_Tp>::channels; }
2481
2482 template<typename _Tp> inline _Tp&
2483 SparseMat_<_Tp>::ref(int i0, size_t* hashval)
2484 { return SparseMat::ref<_Tp>(i0, hashval); }
2485
2486 template<typename _Tp> inline _Tp
2487 SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
2488 { return SparseMat::value<_Tp>(i0, hashval); }
2489
2490 template<typename _Tp> inline _Tp&
2491 SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
2492 { return SparseMat::ref<_Tp>(i0, i1, hashval); }
2493
2494 template<typename _Tp> inline _Tp
2495 SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
2496 { return SparseMat::value<_Tp>(i0, i1, hashval); }
2497
2498 template<typename _Tp> inline _Tp&
2499 SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
2500 { return SparseMat::ref<_Tp>(i0, i1, i2, hashval); }
2501
2502 template<typename _Tp> inline _Tp
2503 SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
2504 { return SparseMat::value<_Tp>(i0, i1, i2, hashval); }
2505
2506 template<typename _Tp> inline _Tp&
2507 SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
2508 { return SparseMat::ref<_Tp>(idx, hashval); }
2509
2510 template<typename _Tp> inline _Tp
2511 SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
2512 { return SparseMat::value<_Tp>(idx, hashval); }
2513
2514 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
2515 { return SparseMatIterator_<_Tp>(this); }
2516
2517 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
2518 { return SparseMatConstIterator_<_Tp>(this); }
2519
2520 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
2521 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
2522
2523 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
2524 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
2525
2526 template<typename _Tp> inline
2527 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
2528 {}
2529
2530 template<typename _Tp> inline
2531 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
2532 : SparseMatConstIterator(_m)
2533 {}
2534
2535 template<typename _Tp> inline
2536 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
2537 : SparseMatConstIterator(_m)
2538 {
2539     CV_Assert( _m->type() == DataType<_Tp>::type );
2540 }
2541
2542 template<typename _Tp> inline
2543 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
2544 : SparseMatConstIterator(it)
2545 {}
2546
2547 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
2548 SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
2549 { return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
2550     (*reinterpret_cast<SparseMatConstIterator*>(this) =
2551      reinterpret_cast<const SparseMatConstIterator&>(it)); }
2552
2553 template<typename _Tp> inline const _Tp&
2554 SparseMatConstIterator_<_Tp>::operator *() const
2555 { return *(const _Tp*)this->ptr; }
2556
2557 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
2558 SparseMatConstIterator_<_Tp>::operator ++()
2559 {
2560     SparseMatConstIterator::operator ++();
2561     return *this;
2562 }
2563
2564 template<typename _Tp> inline SparseMatConstIterator_<_Tp>
2565 SparseMatConstIterator_<_Tp>::operator ++(int)
2566 {
2567     SparseMatConstIterator it = *this;
2568     SparseMatConstIterator::operator ++();
2569     return it;
2570 }
2571
2572 template<typename _Tp> inline
2573 SparseMatIterator_<_Tp>::SparseMatIterator_()
2574 {}
2575
2576 template<typename _Tp> inline
2577 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
2578 : SparseMatConstIterator_<_Tp>(_m)
2579 {}
2580
2581 template<typename _Tp> inline
2582 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
2583 : SparseMatConstIterator_<_Tp>(_m)
2584 {}
2585
2586 template<typename _Tp> inline
2587 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
2588 : SparseMatConstIterator_<_Tp>(it)
2589 {}
2590
2591 template<typename _Tp> inline SparseMatIterator_<_Tp>&
2592 SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
2593 { return reinterpret_cast<SparseMatIterator_<_Tp>&>
2594     (*reinterpret_cast<SparseMatConstIterator*>(this) =
2595      reinterpret_cast<const SparseMatConstIterator&>(it)); }
2596
2597 template<typename _Tp> inline _Tp&
2598 SparseMatIterator_<_Tp>::operator *() const
2599 { return *(_Tp*)this->ptr; }
2600
2601 template<typename _Tp> inline SparseMatIterator_<_Tp>&
2602 SparseMatIterator_<_Tp>::operator ++()
2603 {
2604     SparseMatConstIterator::operator ++();
2605     return *this;
2606 }
2607
2608 template<typename _Tp> inline SparseMatIterator_<_Tp>
2609 SparseMatIterator_<_Tp>::operator ++(int)
2610 {
2611     SparseMatIterator it = *this;
2612     SparseMatConstIterator::operator ++();
2613     return it;
2614 }
2615
2616 }
2617
2618 #endif
2619 #endif