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