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