include/opencv2/core/mat.hpp
Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
00044 #define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
00045 
00046 #ifndef SKIP_INCLUDES
00047 #include <limits.h>
00048 #include <string.h>
00049 #endif // SKIP_INCLUDES
00050 
00051 #ifdef __cplusplus
00052 
00053 namespace cv
00054 {
00055 
00057 
00058 inline void Mat::initEmpty()
00059 {
00060     flags = MAGIC_VAL;
00061     dims = rows = cols = 0;
00062     data = datastart = dataend = datalimit = 0;
00063     refcount = 0;
00064     allocator = 0;
00065 }
00066 
00067 inline Mat::Mat() : size(&rows)
00068 {
00069     initEmpty();
00070 }
00071 
00072 inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
00073 {
00074     initEmpty();
00075     create(_rows, _cols, _type);
00076 }
00077 
00078 inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows)
00079 {
00080     initEmpty();
00081     create(_rows, _cols, _type);
00082     *this = _s;
00083 }
00084 
00085 inline Mat::Mat(Size _sz, int _type) : size(&rows)
00086 {
00087     initEmpty();
00088     create( _sz.height, _sz.width, _type );
00089 }
00090 
00091 inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows)
00092 {
00093     initEmpty();
00094     create(_sz.height, _sz.width, _type);
00095     *this = _s;
00096 }
00097 
00098 inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows)
00099 {
00100     initEmpty();
00101     create(_dims, _sz, _type);
00102 }
00103 
00104 inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) : size(&rows)
00105 {
00106     initEmpty();
00107     create(_dims, _sz, _type);
00108     *this = _s;
00109 }
00110 
00111 inline Mat::Mat(const Mat& m)
00112     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
00113     refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
00114     datalimit(m.datalimit), allocator(m.allocator), size(&rows)
00115 {
00116     if( refcount )
00117         CV_XADD(refcount, 1);
00118     if( m.dims <= 2 )
00119     {
00120         step[0] = m.step[0]; step[1] = m.step[1];
00121     }
00122     else
00123     {
00124         dims = 0;
00125         copySize(m);
00126     }
00127 }
00128 
00129 inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
00130     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
00131     data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
00132     datalimit(0), allocator(0), size(&rows)
00133 {
00134     size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
00135     if( _step == AUTO_STEP )
00136     {
00137         _step = minstep;
00138         flags |= CONTINUOUS_FLAG;
00139     }
00140     else
00141     {
00142         if( rows == 1 ) _step = minstep;
00143         CV_DbgAssert( _step >= minstep );
00144         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
00145     }
00146     step[0] = _step; step[1] = esz;
00147     datalimit = datastart + _step*rows;
00148     dataend = datalimit - _step + minstep;
00149 }
00150 
00151 inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
00152     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
00153     data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
00154     datalimit(0), allocator(0), size(&rows)
00155 {
00156     size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
00157     if( _step == AUTO_STEP )
00158     {
00159         _step = minstep;
00160         flags |= CONTINUOUS_FLAG;
00161     }
00162     else
00163     {
00164         if( rows == 1 ) _step = minstep;
00165         CV_DbgAssert( _step >= minstep );
00166         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
00167     }
00168     step[0] = _step; step[1] = esz;
00169     datalimit = datastart + _step*rows;
00170     dataend = datalimit - _step + minstep;
00171 }
00172 
00173 
00174 template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
00175     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00176     dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0),
00177     datastart(0), dataend(0), allocator(0), size(&rows)
00178 {
00179     if(vec.empty())
00180         return;
00181     if( !copyData )
00182     {
00183         step[0] = step[1] = sizeof(_Tp);
00184         data = datastart = (uchar*)&vec[0];
00185         datalimit = dataend = datastart + rows*step[0];
00186     }
00187     else
00188         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
00189 }
00190 
00191 
00192 template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
00193     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00194     dims(2), rows(n), cols(1), data(0), refcount(0),
00195     datastart(0), dataend(0), allocator(0), size(&rows)
00196 {
00197     if( !copyData )
00198     {
00199         step[0] = step[1] = sizeof(_Tp);
00200         data = datastart = (uchar*)vec.val;
00201         datalimit = dataend = datastart + rows*step[0];
00202     }
00203     else
00204         Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
00205 }
00206 
00207 
00208 template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
00209     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00210     dims(2), rows(m), cols(n), data(0), refcount(0),
00211     datastart(0), dataend(0), allocator(0), size(&rows)
00212 {
00213     if( !copyData )
00214     {
00215         step[0] = cols*sizeof(_Tp);
00216         step[1] = sizeof(_Tp);
00217         data = datastart = (uchar*)M.val;
00218         datalimit = dataend = datastart + rows*step[0];
00219     }
00220     else
00221         Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
00222 }
00223 
00224 
00225 template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
00226     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00227     dims(2), rows(2), cols(1), data(0), refcount(0),
00228     datastart(0), dataend(0), allocator(0), size(&rows)
00229 {
00230     if( !copyData )
00231     {
00232         step[0] = step[1] = sizeof(_Tp);
00233         data = datastart = (uchar*)&pt.x;
00234         datalimit = dataend = datastart + rows*step[0];
00235     }
00236     else
00237     {
00238         create(2, 1, DataType<_Tp>::type);
00239         ((_Tp*)data)[0] = pt.x;
00240         ((_Tp*)data)[1] = pt.y;
00241     }
00242 }
00243 
00244 
00245 template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
00246     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00247     dims(2), rows(3), cols(1), data(0), refcount(0),
00248     datastart(0), dataend(0), allocator(0), size(&rows)
00249 {
00250     if( !copyData )
00251     {
00252         step[0] = step[1] = sizeof(_Tp);
00253         data = datastart = (uchar*)&pt.x;
00254         datalimit = dataend = datastart + rows*step[0];
00255     }
00256     else
00257     {
00258         create(3, 1, DataType<_Tp>::type);
00259         ((_Tp*)data)[0] = pt.x;
00260         ((_Tp*)data)[1] = pt.y;
00261         ((_Tp*)data)[2] = pt.z;
00262     }
00263 }
00264 
00265 
00266 template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
00267     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00268     dims(0), rows(0), cols(0), data(0), refcount(0),
00269     datastart(0), dataend(0), allocator(0), size(&rows)
00270 {
00271     *this = *commaInitializer;
00272 }
00273 
00274 inline Mat::~Mat()
00275 {
00276     release();
00277     if( step.p != step.buf )
00278         fastFree(step.p);
00279 }
00280 
00281 inline Mat& Mat::operator = (const Mat& m)
00282 {
00283     if( this != &m )
00284     {
00285         if( m.refcount )
00286             CV_XADD(m.refcount, 1);
00287         release();
00288         flags = m.flags;
00289         if( dims <= 2 && m.dims <= 2 )
00290         {
00291             dims = m.dims;
00292             rows = m.rows;
00293             cols = m.cols;
00294             step[0] = m.step[0];
00295             step[1] = m.step[1];
00296         }
00297         else
00298             copySize(m);
00299         data = m.data;
00300         datastart = m.datastart;
00301         dataend = m.dataend;
00302         datalimit = m.datalimit;
00303         refcount = m.refcount;
00304         allocator = m.allocator;
00305     }
00306     return *this;
00307 }
00308 
00309 inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
00310 inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
00311 inline Mat Mat::rowRange(int startrow, int endrow) const
00312     { return Mat(*this, Range(startrow, endrow), Range::all()); }
00313 inline Mat Mat::rowRange(const Range& r) const
00314     { return Mat(*this, r, Range::all()); }
00315 inline Mat Mat::colRange(int startcol, int endcol) const
00316     { return Mat(*this, Range::all(), Range(startcol, endcol)); }
00317 inline Mat Mat::colRange(const Range& r) const
00318     { return Mat(*this, Range::all(), r); }
00319 
00320 inline Mat Mat::diag(const Mat& d)
00321 {
00322     CV_Assert( d.cols == 1 || d.rows == 1 );
00323     int len = d.rows + d.cols - 1;
00324     Mat m(len, len, d.type(), Scalar(0)), md = m.diag();
00325     if( d.cols == 1 )
00326         d.copyTo(md);
00327     else
00328         transpose(d, md);
00329     return m;
00330 }
00331 
00332 inline Mat Mat::clone() const
00333 {
00334     Mat m;
00335     copyTo(m);
00336     return m;
00337 }
00338 
00339 inline void Mat::assignTo( Mat& m, int _type ) const
00340 {
00341     if( _type < 0 )
00342         m = *this;
00343     else
00344         convertTo(m, _type);
00345 }
00346 
00347 inline void Mat::create(int _rows, int _cols, int _type)
00348 {
00349     _type &= TYPE_MASK;
00350     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
00351         return;
00352     int sz[] = {_rows, _cols};
00353     create(2, sz, _type);
00354 }
00355 
00356 inline void Mat::create(Size _sz, int _type)
00357 {
00358     create(_sz.height, _sz.width, _type);
00359 }
00360 
00361 inline void Mat::addref()
00362 { if( refcount ) CV_XADD(refcount, 1); }
00363 
00364 inline void Mat::release()
00365 {
00366     if( refcount && CV_XADD(refcount, -1) == 1 )
00367         deallocate();
00368     data = datastart = dataend = datalimit = 0;
00369     size.p[0] = 0;
00370     refcount = 0;
00371 }
00372 
00373 inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
00374 {
00375     return Mat(*this, _rowRange, _colRange);
00376 }
00377 
00378 inline Mat Mat::operator()( const Rect& roi ) const
00379 { return Mat(*this, roi); }
00380 
00381 inline Mat Mat::operator()(const Range* ranges) const
00382 {
00383     return Mat(*this, ranges);
00384 }
00385 
00386 inline Mat::operator CvMat() const
00387 {
00388     CV_DbgAssert(dims <= 2);
00389     CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data);
00390     m.step = (int)step[0];
00391     m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
00392     return m;
00393 }
00394 
00395 inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
00396 inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
00397 inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; }
00398 inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
00399 inline int Mat::type() const { return CV_MAT_TYPE(flags); }
00400 inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
00401 inline int Mat::channels() const { return CV_MAT_CN(flags); }
00402 inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
00403 inline bool Mat::empty() const { return data == 0 || total() == 0; }
00404 inline size_t Mat::total() const
00405 {
00406     if( dims <= 2 )
00407         return (size_t)rows*cols;
00408     size_t p = 1;
00409     for( int i = 0; i < dims; i++ )
00410         p *= size[i];
00411     return p;
00412 }
00413 
00414 inline uchar* Mat::ptr(int y)
00415 {
00416     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00417     return data + step.p[0]*y;
00418 }
00419 
00420 inline const uchar* Mat::ptr(int y) const
00421 {
00422     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00423     return data + step.p[0]*y;
00424 }
00425 
00426 template<typename _Tp> inline _Tp* Mat::ptr(int y)
00427 {
00428     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00429     return (_Tp*)(data + step.p[0]*y);
00430 }
00431 
00432 template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
00433 {
00434     CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
00435     return (const _Tp*)(data + step.p[0]*y);
00436 }
00437 
00438 
00439 inline uchar* Mat::ptr(int i0, int i1)
00440 {
00441     CV_DbgAssert( dims >= 2 && data &&
00442                   (unsigned)i0 < (unsigned)size.p[0] &&
00443                   (unsigned)i1 < (unsigned)size.p[1] );
00444     return data + i0*step.p[0] + i1*step.p[1];
00445 }
00446 
00447 inline const uchar* Mat::ptr(int i0, int i1) const
00448 {
00449     CV_DbgAssert( dims >= 2 && data &&
00450                  (unsigned)i0 < (unsigned)size.p[0] &&
00451                  (unsigned)i1 < (unsigned)size.p[1] );
00452     return data + i0*step.p[0] + i1*step.p[1];
00453 }
00454 
00455 template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1)
00456 {
00457     CV_DbgAssert( dims >= 2 && data &&
00458                   (unsigned)i0 < (unsigned)size.p[0] &&
00459                   (unsigned)i1 < (unsigned)size.p[1] );
00460     return (_Tp*)(data + i0*step.p[0] + i1*step.p[1]);
00461 }
00462 
00463 template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1) const
00464 {
00465     CV_DbgAssert( dims >= 2 && data &&
00466                   (unsigned)i0 < (unsigned)size.p[0] &&
00467                   (unsigned)i1 < (unsigned)size.p[1] );
00468     return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]);
00469 }
00470 
00471 inline uchar* Mat::ptr(int i0, int i1, int i2)
00472 {
00473     CV_DbgAssert( dims >= 3 && data &&
00474                   (unsigned)i0 < (unsigned)size.p[0] &&
00475                   (unsigned)i1 < (unsigned)size.p[1] &&
00476                   (unsigned)i2 < (unsigned)size.p[2] );
00477     return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
00478 }
00479 
00480 inline const uchar* Mat::ptr(int i0, int i1, int i2) const
00481 {
00482     CV_DbgAssert( dims >= 3 && data &&
00483                   (unsigned)i0 < (unsigned)size.p[0] &&
00484                   (unsigned)i1 < (unsigned)size.p[1] &&
00485                   (unsigned)i2 < (unsigned)size.p[2] );
00486     return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
00487 }
00488 
00489 template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1, int i2)
00490 {
00491     CV_DbgAssert( dims >= 3 && data &&
00492                   (unsigned)i0 < (unsigned)size.p[0] &&
00493                   (unsigned)i1 < (unsigned)size.p[1] &&
00494                   (unsigned)i2 < (unsigned)size.p[2] );
00495     return (_Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
00496 }
00497 
00498 template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1, int i2) const
00499 {
00500     CV_DbgAssert( dims >= 3 && data &&
00501                   (unsigned)i0 < (unsigned)size.p[0] &&
00502                   (unsigned)i1 < (unsigned)size.p[1] &&
00503                   (unsigned)i2 < (unsigned)size.p[2] );
00504     return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
00505 }
00506 
00507 inline uchar* Mat::ptr(const int* idx)
00508 {
00509     int i, d = dims;
00510     uchar* p = data;
00511     CV_DbgAssert( d >= 1 && p );
00512     for( i = 0; i < d; i++ )
00513     {
00514         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
00515         p += idx[i]*step.p[i];
00516     }
00517     return p;
00518 }
00519 
00520 inline const uchar* Mat::ptr(const int* idx) const
00521 {
00522     int i, d = dims;
00523     uchar* p = data;
00524     CV_DbgAssert( d >= 1 && p );
00525     for( i = 0; i < d; i++ )
00526     {
00527         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
00528         p += idx[i]*step.p[i];
00529     }
00530     return p;
00531 }
00532 
00533 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
00534 {
00535     CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
00536         (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
00537         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00538     return ((_Tp*)(data + step.p[0]*i0))[i1];
00539 }
00540 
00541 template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
00542 {
00543     CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
00544         (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
00545         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00546     return ((const _Tp*)(data + step.p[0]*i0))[i1];
00547 }
00548 
00549 template<typename _Tp> inline _Tp& Mat::at(Point pt)
00550 {
00551     CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
00552         (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
00553         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00554     return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
00555 }
00556 
00557 template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
00558 {
00559     CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
00560         (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
00561         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00562     return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
00563 }
00564 
00565 template<typename _Tp> inline _Tp& Mat::at(int i0)
00566 {
00567     CV_DbgAssert( dims <= 2 && data &&
00568                  (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
00569                  elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00570     if( isContinuous() || size.p[0] == 1 )
00571         return ((_Tp*)data)[i0];
00572     if( size.p[1] == 1 )
00573         return *(_Tp*)(data + step.p[0]*i0);
00574     int i = i0/cols, j = i0 - i*cols;
00575     return ((_Tp*)(data + step.p[0]*i))[j];
00576 }
00577 
00578 template<typename _Tp> inline const _Tp& Mat::at(int i0) const
00579 {
00580     CV_DbgAssert( dims <= 2 && data &&
00581                  (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
00582                  elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00583     if( isContinuous() || size.p[0] == 1 )
00584         return ((const _Tp*)data)[i0];
00585     if( size.p[1] == 1 )
00586         return *(const _Tp*)(data + step.p[0]*i0);
00587     int i = i0/cols, j = i0 - i*cols;
00588     return ((const _Tp*)(data + step.p[0]*i))[j];
00589 }
00590 
00591 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
00592 {
00593     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00594     return *(_Tp*)ptr(i0, i1, i2);
00595 }
00596 template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
00597 {
00598     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00599     return *(const _Tp*)ptr(i0, i1, i2);
00600 }
00601 template<typename _Tp> inline _Tp& Mat::at(const int* idx)
00602 {
00603     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00604     return *(_Tp*)ptr(idx);
00605 }
00606 template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
00607 {
00608     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00609     return *(const _Tp*)ptr(idx);
00610 }
00611 template<typename _Tp, int n> _Tp& Mat::at(const Vec<int, n>& idx)
00612 {
00613     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00614     return *(_Tp*)ptr(idx.val);
00615 }
00616 template<typename _Tp, int n> inline const _Tp& Mat::at(const Vec<int, n>& idx) const
00617 {
00618     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
00619     return *(const _Tp*)ptr(idx.val);
00620 }
00621 
00622 
00623 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
00624 {
00625     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00626     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
00627 }
00628 
00629 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
00630 {
00631     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00632     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
00633     it += total();
00634     return it;
00635 }
00636 
00637 template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
00638 {
00639     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00640     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
00641 }
00642 
00643 template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
00644 {
00645     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00646     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
00647     it += total();
00648     return it;
00649 }
00650 
00651 template<typename _Tp> inline Mat::operator vector<_Tp>() const
00652 {
00653     vector<_Tp> v;
00654     copyTo(v);
00655     return v;
00656 }
00657 
00658 template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
00659 {
00660     CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
00661                rows + cols - 1 == n && channels() == 1 );
00662 
00663     if( isContinuous() && type() == DataType<_Tp>::type )
00664         return Vec<_Tp, n>((_Tp*)data);
00665     Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
00666     convertTo(tmp, tmp.type());
00667     return v;
00668 }
00669 
00670 template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
00671 {
00672     CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
00673 
00674     if( isContinuous() && type() == DataType<_Tp>::type )
00675         return Matx<_Tp, m, n>((_Tp*)data);
00676     Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
00677     convertTo(tmp, tmp.type());
00678     return mtx;
00679 }
00680 
00681 
00682 template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
00683 {
00684     if( !data )
00685     {
00686         *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
00687         return;
00688     }
00689     CV_Assert(DataType<_Tp>::type == type() && cols == 1
00690               /* && dims == 2 (cols == 1 implies dims == 2) */);
00691     uchar* tmp = dataend + step[0];
00692     if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
00693     {
00694         *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem;
00695         dataend = tmp;
00696     }
00697     else
00698         push_back_(&elem);
00699 }
00700 
00701 template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
00702 {
00703     push_back((const Mat&)m);
00704 }
00705 
00706 inline Mat::MSize::MSize(int* _p) : p(_p) {}
00707 inline Size Mat::MSize::operator()() const
00708 {
00709     CV_DbgAssert(p[-1] <= 2);
00710     return Size(p[1], p[0]);
00711 }
00712 inline const int& Mat::MSize::operator[](int i) const { return p[i]; }
00713 inline int& Mat::MSize::operator[](int i) { return p[i]; }
00714 inline Mat::MSize::operator const int*() const { return p; }
00715 
00716 inline bool Mat::MSize::operator == (const MSize& sz) const
00717 {
00718     int d = p[-1], dsz = sz.p[-1];
00719     if( d != dsz )
00720         return false;
00721     if( d == 2 )
00722         return p[0] == sz.p[0] && p[1] == sz.p[1];
00723 
00724     for( int i = 0; i < d; i++ )
00725         if( p[i] != sz.p[i] )
00726             return false;
00727     return true;
00728 }
00729 
00730 inline bool Mat::MSize::operator != (const MSize& sz) const
00731 {
00732     return !(*this == sz);
00733 }
00734 
00735 inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
00736 inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
00737 inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; }
00738 inline size_t& Mat::MStep::operator[](int i) { return p[i]; }
00739 inline Mat::MStep::operator size_t() const
00740 {
00741     CV_DbgAssert( p == buf );
00742     return buf[0];
00743 }
00744 inline Mat::MStep& Mat::MStep::operator = (size_t s)
00745 {
00746     CV_DbgAssert( p == buf );
00747     buf[0] = s;
00748     return *this;
00749 }
00750 
00751 static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
00752 {
00753     return cvarrToMat(arr, copyData, true, coiMode);
00754 }
00755 
00757 
00758 inline SVD::SVD() {}
00759 inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
00760 inline void SVD::solveZ( InputArray m, OutputArray _dst )
00761 {
00762     Mat mtx = m.getMat();
00763     SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
00764     _dst.create(svd.vt.cols, 1, svd.vt.type());
00765     Mat dst = _dst.getMat();
00766     svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
00767 }
00768 
00769 template<typename _Tp, int m, int n, int nm> inline void
00770     SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
00771 {
00772     assert( nm == MIN(m, n));
00773     Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
00774     SVD::compute(_a, _w, _u, _vt);
00775     CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
00776 }
00777 
00778 template<typename _Tp, int m, int n, int nm> inline void
00779 SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
00780 {
00781     assert( nm == MIN(m, n));
00782     Mat _a(a, false), _w(w, false);
00783     SVD::compute(_a, _w);
00784     CV_Assert(_w.data == (uchar*)&w.val[0]);
00785 }
00786 
00787 template<typename _Tp, int m, int n, int nm, int nb> inline void
00788 SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
00789                 const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
00790                 Matx<_Tp, n, nb>& dst )
00791 {
00792     assert( nm == MIN(m, n));
00793     Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
00794     SVD::backSubst(_w, _u, _vt, _rhs, _dst);
00795     CV_Assert(_dst.data == (uchar*)&dst.val[0]);
00796 }
00797 
00799 
00800 template<typename _Tp> inline Mat_<_Tp>::Mat_()
00801     : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
00802 
00803 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
00804     : Mat(_rows, _cols, DataType<_Tp>::type) {}
00805 
00806 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
00807     : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
00808 
00809 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
00810     : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
00811 
00812 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
00813     : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
00814 
00815 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
00816     : Mat(_dims, _sz, DataType<_Tp>::type) {}
00817 
00818 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
00819     : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
00820 
00821 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
00822     : Mat(m, ranges) {}
00823 
00824 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
00825     : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
00826 
00827 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
00828     : Mat(m) {}
00829 
00830 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
00831     : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
00832 
00833 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
00834     : Mat(m, _rowRange, _colRange) {}
00835 
00836 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
00837     : Mat(m, roi) {}
00838 
00839 template<typename _Tp> template<int n> inline
00840     Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
00841     : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
00842 {
00843     CV_Assert(n%DataType<_Tp>::channels == 0);
00844     if( copyData )
00845         *this = clone();
00846 }
00847 
00848 template<typename _Tp> template<int m, int n> inline
00849     Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n>& M, bool copyData)
00850     : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
00851 {
00852     CV_Assert(n % DataType<_Tp>::channels == 0);
00853     if( copyData )
00854         *this = clone();
00855 }
00856 
00857 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
00858     : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
00859 {
00860     CV_Assert(2 % DataType<_Tp>::channels == 0);
00861     if( copyData )
00862         *this = clone();
00863 }
00864 
00865 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
00866     : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
00867 {
00868     CV_Assert(3 % DataType<_Tp>::channels == 0);
00869     if( copyData )
00870         *this = clone();
00871 }
00872 
00873 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
00874     : Mat(commaInitializer) {}
00875 
00876 template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
00877     : Mat(vec, copyData) {}
00878 
00879 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
00880 {
00881     if( DataType<_Tp>::type == m.type() )
00882     {
00883         Mat::operator = (m);
00884         return *this;
00885     }
00886     if( DataType<_Tp>::depth == m.depth() )
00887     {
00888         return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
00889     }
00890     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
00891     m.convertTo(*this, type());
00892     return *this;
00893 }
00894 
00895 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
00896 {
00897     Mat::operator=(m);
00898     return *this;
00899 }
00900 
00901 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
00902 {
00903     typedef typename DataType<_Tp>::vec_type VT;
00904     Mat::operator=(Scalar((const VT&)s));
00905     return *this;
00906 }
00907 
00908 template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
00909 {
00910     Mat::create(_rows, _cols, DataType<_Tp>::type);
00911 }
00912 
00913 template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
00914 {
00915     Mat::create(_sz, DataType<_Tp>::type);
00916 }
00917 
00918 template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
00919 {
00920     Mat::create(_dims, _sz, DataType<_Tp>::type);
00921 }
00922 
00923 
00924 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
00925 { return Mat_<_Tp>(Mat::cross(m)); }
00926 
00927 template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
00928 { return Mat_<T2>(*this); }
00929 
00930 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
00931 { return Mat_(*this, Range(y, y+1), Range::all()); }
00932 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
00933 { return Mat_(*this, Range::all(), Range(x, x+1)); }
00934 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
00935 { return Mat_(Mat::diag(d)); }
00936 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
00937 { return Mat_(Mat::clone()); }
00938 
00939 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
00940 {
00941     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
00942     return sizeof(_Tp);
00943 }
00944 
00945 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
00946 {
00947     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
00948     return sizeof(_Tp)/DataType<_Tp>::channels;
00949 }
00950 template<typename _Tp> inline int Mat_<_Tp>::type() const
00951 {
00952     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
00953     return DataType<_Tp>::type;
00954 }
00955 template<typename _Tp> inline int Mat_<_Tp>::depth() const
00956 {
00957     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
00958     return DataType<_Tp>::depth;
00959 }
00960 template<typename _Tp> inline int Mat_<_Tp>::channels() const
00961 {
00962     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
00963     return DataType<_Tp>::channels;
00964 }
00965 template<typename _Tp> inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); }
00966 template<typename _Tp> inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); }
00967 
00968 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
00969 { return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));  }
00970 
00971 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
00972 { return Mat_<_Tp>(*this, _rowRange, _colRange); }
00973 
00974 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
00975 { return Mat_<_Tp>(*this, roi); }
00976 
00977 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
00978 { return Mat_<_Tp>(*this, ranges); }
00979 
00980 template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
00981 { return (_Tp*)ptr(y); }
00982 template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
00983 { return (const _Tp*)ptr(y); }
00984 
00985 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
00986 {
00987     CV_DbgAssert( dims <= 2 && data &&
00988                   (unsigned)i0 < (unsigned)size.p[0] &&
00989                   (unsigned)i1 < (unsigned)size.p[1] &&
00990                   type() == DataType<_Tp>::type );
00991     return ((_Tp*)(data + step.p[0]*i0))[i1];
00992 }
00993 
00994 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
00995 {
00996     CV_DbgAssert( dims <= 2 && data &&
00997                   (unsigned)i0 < (unsigned)size.p[0] &&
00998                   (unsigned)i1 < (unsigned)size.p[1] &&
00999                   type() == DataType<_Tp>::type );
01000     return ((const _Tp*)(data + step.p[0]*i0))[i1];
01001 }
01002 
01003 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
01004 {
01005     CV_DbgAssert( dims <= 2 && data &&
01006                   (unsigned)pt.y < (unsigned)size.p[0] &&
01007                   (unsigned)pt.x < (unsigned)size.p[1] &&
01008                   type() == DataType<_Tp>::type );
01009     return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
01010 }
01011 
01012 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
01013 {
01014     CV_DbgAssert( dims <= 2 && data &&
01015                   (unsigned)pt.y < (unsigned)size.p[0] &&
01016                   (unsigned)pt.x < (unsigned)size.p[1] &&
01017                  type() == DataType<_Tp>::type );
01018     return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
01019 }
01020 
01021 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
01022 {
01023     return Mat::at<_Tp>(idx);
01024 }
01025 
01026 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
01027 {
01028     return Mat::at<_Tp>(idx);
01029 }
01030 
01031 template<typename _Tp> template<int n> inline _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
01032 {
01033     return Mat::at<_Tp>(idx);
01034 }
01035 
01036 template<typename _Tp> template<int n> inline const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
01037 {
01038     return Mat::at<_Tp>(idx);
01039 }
01040 
01041 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
01042 {
01043     return this->at<_Tp>(i0);
01044 }
01045 
01046 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
01047 {
01048     return this->at<_Tp>(i0);
01049 }
01050 
01051 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
01052 {
01053     return this->at<_Tp>(i0, i1, i2);
01054 }
01055 
01056 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
01057 {
01058     return this->at<_Tp>(i0, i1, i2);
01059 }
01060 
01061 
01062 template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
01063 {
01064     vector<_Tp> v;
01065     copyTo(v);
01066     return v;
01067 }
01068 
01069 template<typename _Tp> template<int n> inline Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
01070 {
01071     CV_Assert(n % DataType<_Tp>::channels == 0);
01072     return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
01073 }
01074 
01075 template<typename _Tp> template<int m, int n> inline Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
01076 {
01077     CV_Assert(n % DataType<_Tp>::channels == 0);
01078     return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
01079 }
01080 
01081 template<typename T1, typename T2, typename Op> inline void
01082 process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
01083 {
01084     int y, x, rows = m1.rows, cols = m1.cols;
01085 
01086     CV_DbgAssert( m1.size() == m2.size() );
01087 
01088     for( y = 0; y < rows; y++ )
01089     {
01090         const T1* src = m1[y];
01091         T2* dst = m2[y];
01092 
01093         for( x = 0; x < cols; x++ )
01094             dst[x] = op(src[x]);
01095     }
01096 }
01097 
01098 template<typename T1, typename T2, typename T3, typename Op> inline void
01099 process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
01100 {
01101     int y, x, rows = m1.rows, cols = m1.cols;
01102 
01103     CV_DbgAssert( m1.size() == m2.size() );
01104 
01105     for( y = 0; y < rows; y++ )
01106     {
01107         const T1* src1 = m1[y];
01108         const T2* src2 = m2[y];
01109         T3* dst = m3[y];
01110 
01111         for( x = 0; x < cols; x++ )
01112             dst[x] = op( src1[x], src2[x] );
01113     }
01114 }
01115 
01116 
01118 
01119 template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec)
01120     : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
01121 
01122 template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp> >& vec)
01123     : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
01124 
01125 template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec)
01126     : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
01127 
01128 template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
01129     : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
01130 
01131 template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
01132     : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
01133 
01134 inline _InputArray::_InputArray(const Scalar& s)
01135     : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&s), sz(1, 4) {}
01136 
01137 template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m)
01138     : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {}
01139 
01140 template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec)
01141     : _InputArray(vec) {}
01142 template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec)
01143     : _InputArray(vec) {}
01144 template<typename _Tp> inline _OutputArray::_OutputArray(vector<Mat_<_Tp> >& vec)
01145     : _InputArray(vec) {}
01146 template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m)
01147     : _InputArray(m) {}
01148 template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
01149     : _InputArray(mtx) {}
01150 template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n)
01151     : _InputArray(vec, n) {}
01152 
01153 template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec)
01154     : _InputArray(vec) {flags |= FIXED_SIZE;}
01155 template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec)
01156     : _InputArray(vec) {flags |= FIXED_SIZE;}
01157 template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec)
01158     : _InputArray(vec) {flags |= FIXED_SIZE;}
01159 
01160 template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m)
01161     : _InputArray(m) {flags |= FIXED_SIZE;}
01162 template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
01163     : _InputArray(mtx) {}
01164 template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n)
01165     : _InputArray(vec, n) {}
01166 
01168 
01169 class CV_EXPORTS MatOp
01170 {
01171 public:
01172     MatOp() {};
01173     virtual ~MatOp() {};
01174 
01175     virtual bool elementWise(const MatExpr& expr) const;
01176     virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
01177     virtual void roi(const MatExpr& expr, const Range& rowRange,
01178                      const Range& colRange, MatExpr& res) const;
01179     virtual void diag(const MatExpr& expr, int d, MatExpr& res) const;
01180     virtual void augAssignAdd(const MatExpr& expr, Mat& m) const;
01181     virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const;
01182     virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const;
01183     virtual void augAssignDivide(const MatExpr& expr, Mat& m) const;
01184     virtual void augAssignAnd(const MatExpr& expr, Mat& m) const;
01185     virtual void augAssignOr(const MatExpr& expr, Mat& m) const;
01186     virtual void augAssignXor(const MatExpr& expr, Mat& m) const;
01187 
01188     virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
01189     virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const;
01190 
01191     virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
01192     virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
01193 
01194     virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
01195     virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const;
01196 
01197     virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
01198     virtual void divide(double s, const MatExpr& expr, MatExpr& res) const;
01199 
01200     virtual void abs(const MatExpr& expr, MatExpr& res) const;
01201 
01202     virtual void transpose(const MatExpr& expr, MatExpr& res) const;
01203     virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
01204     virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
01205 
01206     virtual Size size(const MatExpr& expr) const;
01207     virtual int type(const MatExpr& expr) const;
01208 };
01209 
01210 
01211 class CV_EXPORTS MatExpr
01212 {
01213 public:
01214     MatExpr() : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s(Scalar()) {}
01215     MatExpr(const MatOp* _op, int _flags, const Mat& _a=Mat(), const Mat& _b=Mat(),
01216             const Mat& _c=Mat(), double _alpha=1, double _beta=1, const Scalar& _s=Scalar())
01217         : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) {}
01218     explicit MatExpr(const Mat& m);
01219     operator Mat() const
01220     {
01221         Mat m;
01222         op->assign(*this, m);
01223         return m;
01224     }
01225 
01226     template<typename _Tp> operator Mat_<_Tp>() const
01227     {
01228         Mat_<_Tp> m;
01229         op->assign(*this, m, DataType<_Tp>::type);
01230         return m;
01231     }
01232 
01233     MatExpr row(int y) const;
01234     MatExpr col(int x) const;
01235     MatExpr diag(int d=0) const;
01236     MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
01237     MatExpr operator()( const Rect& roi ) const;
01238 
01239     Mat cross(const Mat& m) const;
01240     double dot(const Mat& m) const;
01241 
01242     MatExpr t() const;
01243     MatExpr inv(int method = DECOMP_LU) const;
01244     MatExpr mul(const MatExpr& e, double scale=1) const;
01245     MatExpr mul(const Mat& m, double scale=1) const;
01246 
01247     Size size() const;
01248     int type() const;
01249 
01250     const MatOp* op;
01251     int flags;
01252 
01253     Mat a, b, c;
01254     double alpha, beta;
01255     Scalar s;
01256 };
01257 
01258 
01259 CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b);
01260 CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s);
01261 CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a);
01262 CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m);
01263 CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e);
01264 CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s);
01265 CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e);
01266 CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2);
01267 
01268 CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b);
01269 CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s);
01270 CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a);
01271 CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m);
01272 CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e);
01273 CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s);
01274 CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e);
01275 CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2);
01276 
01277 CV_EXPORTS MatExpr operator - (const Mat& m);
01278 CV_EXPORTS MatExpr operator - (const MatExpr& e);
01279 
01280 CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);
01281 CV_EXPORTS MatExpr operator * (const Mat& a, double s);
01282 CV_EXPORTS MatExpr operator * (double s, const Mat& a);
01283 CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m);
01284 CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e);
01285 CV_EXPORTS MatExpr operator * (const MatExpr& e, double s);
01286 CV_EXPORTS MatExpr operator * (double s, const MatExpr& e);
01287 CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2);
01288 
01289 CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b);
01290 CV_EXPORTS MatExpr operator / (const Mat& a, double s);
01291 CV_EXPORTS MatExpr operator / (double s, const Mat& a);
01292 CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m);
01293 CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e);
01294 CV_EXPORTS MatExpr operator / (const MatExpr& e, double s);
01295 CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
01296 CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
01297 
01298 CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b);
01299 CV_EXPORTS MatExpr operator < (const Mat& a, double s);
01300 CV_EXPORTS MatExpr operator < (double s, const Mat& a);
01301 
01302 CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b);
01303 CV_EXPORTS MatExpr operator <= (const Mat& a, double s);
01304 CV_EXPORTS MatExpr operator <= (double s, const Mat& a);
01305 
01306 CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b);
01307 CV_EXPORTS MatExpr operator == (const Mat& a, double s);
01308 CV_EXPORTS MatExpr operator == (double s, const Mat& a);
01309 
01310 CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b);
01311 CV_EXPORTS MatExpr operator != (const Mat& a, double s);
01312 CV_EXPORTS MatExpr operator != (double s, const Mat& a);
01313 
01314 CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b);
01315 CV_EXPORTS MatExpr operator >= (const Mat& a, double s);
01316 CV_EXPORTS MatExpr operator >= (double s, const Mat& a);
01317 
01318 CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b);
01319 CV_EXPORTS MatExpr operator > (const Mat& a, double s);
01320 CV_EXPORTS MatExpr operator > (double s, const Mat& a);
01321 
01322 CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
01323 CV_EXPORTS MatExpr min(const Mat& a, double s);
01324 CV_EXPORTS MatExpr min(double s, const Mat& a);
01325 
01326 CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
01327 CV_EXPORTS MatExpr max(const Mat& a, double s);
01328 CV_EXPORTS MatExpr max(double s, const Mat& a);
01329 
01330 template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01331 {
01332     return cv::min((const Mat&)a, (const Mat&)b);
01333 }
01334 
01335 template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, double s)
01336 {
01337     return cv::min((const Mat&)a, s);
01338 }
01339 
01340 template<typename _Tp> static inline MatExpr min(double s, const Mat_<_Tp>& a)
01341 {
01342     return cv::min((const Mat&)a, s);
01343 }
01344 
01345 template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01346 {
01347     return cv::max((const Mat&)a, (const Mat&)b);
01348 }
01349 
01350 template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, double s)
01351 {
01352     return cv::max((const Mat&)a, s);
01353 }
01354 
01355 template<typename _Tp> static inline MatExpr max(double s, const Mat_<_Tp>& a)
01356 {
01357     return cv::max((const Mat&)a, s);
01358 }
01359 
01360 template<typename _Tp> static inline void min(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
01361 {
01362     cv::min((const Mat&)a, (const Mat&)b, (Mat&)c);
01363 }
01364 
01365 template<typename _Tp> static inline void min(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c)
01366 {
01367     cv::min((const Mat&)a, s, (Mat&)c);
01368 }
01369 
01370 template<typename _Tp> static inline void min(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c)
01371 {
01372     cv::min((const Mat&)a, s, (Mat&)c);
01373 }
01374 
01375 template<typename _Tp> static inline void max(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
01376 {
01377     cv::max((const Mat&)a, (const Mat&)b, (Mat&)c);
01378 }
01379 
01380 template<typename _Tp> static inline void max(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c)
01381 {
01382     cv::max((const Mat&)a, s, (Mat&)c);
01383 }
01384 
01385 template<typename _Tp> static inline void max(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c)
01386 {
01387     cv::max((const Mat&)a, s, (Mat&)c);
01388 }
01389 
01390 
01391 CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
01392 CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
01393 CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
01394 
01395 CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b);
01396 CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s);
01397 CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a);
01398 
01399 CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b);
01400 CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s);
01401 CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a);
01402 
01403 CV_EXPORTS MatExpr operator ~(const Mat& m);
01404 
01405 CV_EXPORTS MatExpr abs(const Mat& m);
01406 CV_EXPORTS MatExpr abs(const MatExpr& e);
01407 
01408 template<typename _Tp> static inline MatExpr abs(const Mat_<_Tp>& m)
01409 {
01410     return cv::abs((const Mat&)m);
01411 }
01412 
01414 
01415 inline Mat& Mat::operator = (const MatExpr& e)
01416 {
01417     e.op->assign(e, *this);
01418     return *this;
01419 }
01420 
01421 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr& e)
01422 {
01423     e.op->assign(e, *this, DataType<_Tp>::type);
01424 }
01425 
01426 template<typename _Tp> Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
01427 {
01428     e.op->assign(e, *this, DataType<_Tp>::type);
01429     return *this;
01430 }
01431 
01432 static inline Mat& operator += (const Mat& a, const Mat& b)
01433 {
01434     add(a, b, (Mat&)a);
01435     return (Mat&)a;
01436 }
01437 
01438 static inline Mat& operator += (const Mat& a, const Scalar& s)
01439 {
01440     add(a, s, (Mat&)a);
01441     return (Mat&)a;
01442 }
01443 
01444 template<typename _Tp> static inline
01445 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01446 {
01447     add(a, b, (Mat&)a);
01448     return (Mat_<_Tp>&)a;
01449 }
01450 
01451 template<typename _Tp> static inline
01452 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s)
01453 {
01454     add(a, s, (Mat&)a);
01455     return (Mat_<_Tp>&)a;
01456 }
01457 
01458 static inline Mat& operator += (const Mat& a, const MatExpr& b)
01459 {
01460     b.op->augAssignAdd(b, (Mat&)a);
01461     return (Mat&)a;
01462 }
01463 
01464 template<typename _Tp> static inline
01465 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
01466 {
01467     b.op->augAssignAdd(b, (Mat&)a);
01468     return (Mat_<_Tp>&)a;
01469 }
01470 
01471 static inline Mat& operator -= (const Mat& a, const Mat& b)
01472 {
01473     subtract(a, b, (Mat&)a);
01474     return (Mat&)a;
01475 }
01476 
01477 static inline Mat& operator -= (const Mat& a, const Scalar& s)
01478 {
01479     subtract(a, s, (Mat&)a);
01480     return (Mat&)a;
01481 }
01482 
01483 template<typename _Tp> static inline
01484 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01485 {
01486     subtract(a, b, (Mat&)a);
01487     return (Mat_<_Tp>&)a;
01488 }
01489 
01490 template<typename _Tp> static inline
01491 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s)
01492 {
01493     subtract(a, s, (Mat&)a);
01494     return (Mat_<_Tp>&)a;
01495 }
01496 
01497 static inline Mat& operator -= (const Mat& a, const MatExpr& b)
01498 {
01499     b.op->augAssignSubtract(b, (Mat&)a);
01500     return (Mat&)a;
01501 }
01502 
01503 template<typename _Tp> static inline
01504 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
01505 {
01506     b.op->augAssignSubtract(b, (Mat&)a);
01507     return (Mat_<_Tp>&)a;
01508 }
01509 
01510 static inline Mat& operator *= (const Mat& a, const Mat& b)
01511 {
01512     gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
01513     return (Mat&)a;
01514 }
01515 
01516 static inline Mat& operator *= (const Mat& a, double s)
01517 {
01518     a.convertTo((Mat&)a, -1, s);
01519     return (Mat&)a;
01520 }
01521 
01522 template<typename _Tp> static inline
01523 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01524 {
01525     gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
01526     return (Mat_<_Tp>&)a;
01527 }
01528 
01529 template<typename _Tp> static inline
01530 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, double s)
01531 {
01532     a.convertTo((Mat&)a, -1, s);
01533     return (Mat_<_Tp>&)a;
01534 }
01535 
01536 static inline Mat& operator *= (const Mat& a, const MatExpr& b)
01537 {
01538     b.op->augAssignMultiply(b, (Mat&)a);
01539     return (Mat&)a;
01540 }
01541 
01542 template<typename _Tp> static inline
01543 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
01544 {
01545     b.op->augAssignMultiply(b, (Mat&)a);
01546     return (Mat_<_Tp>&)a;
01547 }
01548 
01549 static inline Mat& operator /= (const Mat& a, const Mat& b)
01550 {
01551     divide(a, b, (Mat&)a);
01552     return (Mat&)a;
01553 }
01554 
01555 static inline Mat& operator /= (const Mat& a, double s)
01556 {
01557     a.convertTo((Mat&)a, -1, 1./s);
01558     return (Mat&)a;
01559 }
01560 
01561 template<typename _Tp> static inline
01562 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01563 {
01564     divide(a, b, (Mat&)a);
01565     return (Mat_<_Tp>&)a;
01566 }
01567 
01568 template<typename _Tp> static inline
01569 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double s)
01570 {
01571     a.convertTo((Mat&)a, -1, 1./s);
01572     return (Mat_<_Tp>&)a;
01573 }
01574 
01575 static inline Mat& operator /= (const Mat& a, const MatExpr& b)
01576 {
01577     b.op->augAssignDivide(b, (Mat&)a);
01578     return (Mat&)a;
01579 }
01580 
01581 template<typename _Tp> static inline
01582 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
01583 {
01584     b.op->augAssignDivide(b, (Mat&)a);
01585     return (Mat_<_Tp>&)a;
01586 }
01587 
01589 
01590 static inline Mat& operator &= (const Mat& a, const Mat& b)
01591 {
01592     bitwise_and(a, b, (Mat&)a);
01593     return (Mat&)a;
01594 }
01595 
01596 static inline Mat& operator &= (const Mat& a, const Scalar& s)
01597 {
01598     bitwise_and(a, s, (Mat&)a);
01599     return (Mat&)a;
01600 }
01601 
01602 template<typename _Tp> static inline Mat_<_Tp>&
01603 operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01604 {
01605     bitwise_and(a, b, (Mat&)a);
01606     return (Mat_<_Tp>&)a;
01607 }
01608 
01609 template<typename _Tp> static inline Mat_<_Tp>&
01610 operator &= (const Mat_<_Tp>& a, const Scalar& s)
01611 {
01612     bitwise_and(a, s, (Mat&)a);
01613     return (Mat_<_Tp>&)a;
01614 }
01615 
01616 static inline Mat& operator |= (const Mat& a, const Mat& b)
01617 {
01618     bitwise_or(a, b, (Mat&)a);
01619     return (Mat&)a;
01620 }
01621 
01622 static inline Mat& operator |= (const Mat& a, const Scalar& s)
01623 {
01624     bitwise_or(a, s, (Mat&)a);
01625     return (Mat&)a;
01626 }
01627 
01628 template<typename _Tp> static inline Mat_<_Tp>&
01629 operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01630 {
01631     bitwise_or(a, b, (Mat&)a);
01632     return (Mat_<_Tp>&)a;
01633 }
01634 
01635 template<typename _Tp> static inline Mat_<_Tp>&
01636 operator |= (const Mat_<_Tp>& a, const Scalar& s)
01637 {
01638     bitwise_or(a, s, (Mat&)a);
01639     return (Mat_<_Tp>&)a;
01640 }
01641 
01642 static inline Mat& operator ^= (const Mat& a, const Mat& b)
01643 {
01644     bitwise_xor(a, b, (Mat&)a);
01645     return (Mat&)a;
01646 }
01647 
01648 static inline Mat& operator ^= (const Mat& a, const Scalar& s)
01649 {
01650     bitwise_xor(a, s, (Mat&)a);
01651     return (Mat&)a;
01652 }
01653 
01654 template<typename _Tp> static inline Mat_<_Tp>&
01655 operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01656 {
01657     bitwise_xor(a, b, (Mat&)a);
01658     return (Mat_<_Tp>&)a;
01659 }
01660 
01661 template<typename _Tp> static inline Mat_<_Tp>&
01662 operator ^= (const Mat_<_Tp>& a, const Scalar& s)
01663 {
01664     bitwise_xor(a, s, (Mat&)a);
01665     return (Mat_<_Tp>&)a;
01666 }
01667 
01669 
01670 template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
01671 { split(src, (vector<Mat>&)mv ); }
01672 
01674 
01675 template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(int rows, int cols)
01676 {
01677     return Mat::zeros(rows, cols, DataType<_Tp>::type);
01678 }
01679 
01680 template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(Size sz)
01681 {
01682     return Mat::zeros(sz, DataType<_Tp>::type);
01683 }
01684 
01685 template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(int rows, int cols)
01686 {
01687     return Mat::ones(rows, cols, DataType<_Tp>::type);
01688 }
01689 
01690 template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(Size sz)
01691 {
01692     return Mat::ones(sz, DataType<_Tp>::type);
01693 }
01694 
01695 template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(int rows, int cols)
01696 {
01697     return Mat::eye(rows, cols, DataType<_Tp>::type);
01698 }
01699 
01700 template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(Size sz)
01701 {
01702     return Mat::eye(sz, DataType<_Tp>::type);
01703 }
01704 
01706 
01707 inline MatConstIterator::MatConstIterator()
01708     : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {}
01709 
01710 inline MatConstIterator::MatConstIterator(const Mat* _m)
01711     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
01712 {
01713     if( m && m->isContinuous() )
01714     {
01715         sliceStart = m->data;
01716         sliceEnd = sliceStart + m->total()*elemSize;
01717     }
01718     seek((const int*)0);
01719 }
01720 
01721 inline MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
01722     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
01723 {
01724     CV_Assert(m && m->dims <= 2);
01725     if( m->isContinuous() )
01726     {
01727         sliceStart = m->data;
01728         sliceEnd = sliceStart + m->total()*elemSize;
01729     }
01730     int idx[]={_row, _col};
01731     seek(idx);
01732 }
01733 
01734 inline MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
01735     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
01736 {
01737     CV_Assert(m && m->dims <= 2);
01738     if( m->isContinuous() )
01739     {
01740         sliceStart = m->data;
01741         sliceEnd = sliceStart + m->total()*elemSize;
01742     }
01743     int idx[]={_pt.y, _pt.x};
01744     seek(idx);
01745 }
01746 
01747 inline MatConstIterator::MatConstIterator(const MatConstIterator& it)
01748     : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
01749 {}
01750 
01751 inline MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
01752 {
01753     m = it.m; elemSize = it.elemSize; ptr = it.ptr;
01754     sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
01755     return *this;
01756 }
01757 
01758 inline uchar* MatConstIterator::operator *() const { return ptr; }
01759 
01760 inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
01761 {
01762     if( !m || ofs == 0 )
01763         return *this;
01764     ptrdiff_t ofsb = ofs*elemSize;
01765     ptr += ofsb;
01766     if( ptr < sliceStart || sliceEnd <= ptr )
01767     {
01768         ptr -= ofsb;
01769         seek(ofs, true);
01770     }
01771     return *this;
01772 }
01773 
01774 inline MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
01775 { return (*this += -ofs); }
01776 
01777 inline MatConstIterator& MatConstIterator::operator --()
01778 {
01779     if( m && (ptr -= elemSize) < sliceStart )
01780     {
01781         ptr += elemSize;
01782         seek(-1, true);
01783     }
01784     return *this;
01785 }
01786 
01787 inline MatConstIterator MatConstIterator::operator --(int)
01788 {
01789     MatConstIterator b = *this;
01790     *this += -1;
01791     return b;
01792 }
01793 
01794 inline MatConstIterator& MatConstIterator::operator ++()
01795 {
01796     if( m && (ptr += elemSize) >= sliceEnd )
01797     {
01798         ptr -= elemSize;
01799         seek(1, true);
01800     }
01801     return *this;
01802 }
01803 
01804 inline MatConstIterator MatConstIterator::operator ++(int)
01805 {
01806     MatConstIterator b = *this;
01807     *this += 1;
01808     return b;
01809 }
01810 
01811 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_() {}
01812 
01813 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
01814     : MatConstIterator(_m) {}
01815 
01816 template<typename _Tp> inline MatConstIterator_<_Tp>::
01817     MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
01818     : MatConstIterator(_m, _row, _col) {}
01819 
01820 template<typename _Tp> inline MatConstIterator_<_Tp>::
01821     MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
01822     : MatConstIterator(_m, _pt) {}
01823 
01824 template<typename _Tp> inline MatConstIterator_<_Tp>::
01825     MatConstIterator_(const MatConstIterator_& it)
01826     : MatConstIterator(it) {}
01827 
01828 template<typename _Tp> inline MatConstIterator_<_Tp>&
01829     MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
01830 {
01831     MatConstIterator::operator = (it);
01832     return *this;
01833 }
01834 
01835 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
01836 
01837 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
01838 {
01839     MatConstIterator::operator += (ofs);
01840     return *this;
01841 }
01842 
01843 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
01844 { return (*this += -ofs); }
01845 
01846 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
01847 {
01848     MatConstIterator::operator --();
01849     return *this;
01850 }
01851 
01852 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
01853 {
01854     MatConstIterator_ b = *this;
01855     MatConstIterator::operator --();
01856     return b;
01857 }
01858 
01859 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
01860 {
01861     MatConstIterator::operator ++();
01862     return *this;
01863 }
01864 
01865 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
01866 {
01867     MatConstIterator_ b = *this;
01868     MatConstIterator::operator ++();
01869     return b;
01870 }
01871 
01872 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
01873 
01874 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
01875     : MatConstIterator_<_Tp>(_m) {}
01876 
01877 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
01878     : MatConstIterator_<_Tp>(_m, _row, _col) {}
01879 
01880 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
01881     : MatConstIterator_<_Tp>(_m, _pt) {}
01882 
01883 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
01884     : MatConstIterator_<_Tp>(_m, _idx) {}
01885 
01886 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
01887     : MatConstIterator_<_Tp>(it) {}
01888 
01889 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
01890 {
01891     MatConstIterator::operator = (it);
01892     return *this;
01893 }
01894 
01895 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
01896 
01897 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
01898 {
01899     MatConstIterator::operator += (ofs);
01900     return *this;
01901 }
01902 
01903 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
01904 {
01905     MatConstIterator::operator += (-ofs);
01906     return *this;
01907 }
01908 
01909 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
01910 {
01911     MatConstIterator::operator --();
01912     return *this;
01913 }
01914 
01915 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
01916 {
01917     MatIterator_ b = *this;
01918     MatConstIterator::operator --();
01919     return b;
01920 }
01921 
01922 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
01923 {
01924     MatConstIterator::operator ++();
01925     return *this;
01926 }
01927 
01928 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
01929 {
01930     MatIterator_ b = *this;
01931     MatConstIterator::operator ++();
01932     return b;
01933 }
01934 
01935 template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
01936 {
01937     if( !m )
01938         return Point();
01939     CV_DbgAssert( m->dims <= 2 );
01940     if( m->isContinuous() )
01941     {
01942         ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
01943         int y = (int)(ofs / m->cols), x = (int)(ofs - (ptrdiff_t)y*m->cols);
01944         return Point(x, y);
01945     }
01946     else
01947     {
01948         ptrdiff_t ofs = (uchar*)ptr - m->data;
01949         int y = (int)(ofs / m->step), x = (int)((ofs - y*m->step)/sizeof(_Tp));
01950         return Point(x, y);
01951     }
01952 }
01953 
01954 static inline bool
01955 operator == (const MatConstIterator& a, const MatConstIterator& b)
01956 { return a.m == b.m && a.ptr == b.ptr; }
01957 
01958 template<typename _Tp> static inline bool
01959 operator != (const MatConstIterator& a, const MatConstIterator& b)
01960 { return !(a == b); }
01961 
01962 template<typename _Tp> static inline bool
01963 operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
01964 { return a.m == b.m && a.ptr == b.ptr; }
01965 
01966 template<typename _Tp> static inline bool
01967 operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
01968 { return a.m != b.m || a.ptr != b.ptr; }
01969 
01970 template<typename _Tp> static inline bool
01971 operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
01972 { return a.m == b.m && a.ptr == b.ptr; }
01973 
01974 template<typename _Tp> static inline bool
01975 operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
01976 { return a.m != b.m || a.ptr != b.ptr; }
01977 
01978 static inline bool
01979 operator < (const MatConstIterator& a, const MatConstIterator& b)
01980 { return a.ptr < b.ptr; }
01981 
01982 static inline bool
01983 operator > (const MatConstIterator& a, const MatConstIterator& b)
01984 { return a.ptr > b.ptr; }
01985 
01986 static inline bool
01987 operator <= (const MatConstIterator& a, const MatConstIterator& b)
01988 { return a.ptr <= b.ptr; }
01989 
01990 static inline bool
01991 operator >= (const MatConstIterator& a, const MatConstIterator& b)
01992 { return a.ptr >= b.ptr; }
01993 
01994 CV_EXPORTS ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a);
01995 
01996 static inline MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
01997 { MatConstIterator b = a; return b += ofs; }
01998 
01999 static inline MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
02000 { MatConstIterator b = a; return b += ofs; }
02001 
02002 static inline MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
02003 { MatConstIterator b = a; return b += -ofs; }
02004 
02005 template<typename _Tp> static inline MatConstIterator_<_Tp>
02006 operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
02007 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
02008 
02009 template<typename _Tp> static inline MatConstIterator_<_Tp>
02010 operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
02011 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
02012 
02013 template<typename _Tp> static inline MatConstIterator_<_Tp>
02014 operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
02015 { MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatConstIterator_<_Tp>&)t; }
02016 
02017 inline uchar* MatConstIterator::operator [](ptrdiff_t i) const
02018 { return *(*this + i); }
02019 
02020 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
02021 { return *(_Tp*)MatConstIterator::operator [](i); }
02022 
02023 template<typename _Tp> static inline MatIterator_<_Tp>
02024 operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
02025 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
02026 
02027 template<typename _Tp> static inline MatIterator_<_Tp>
02028 operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
02029 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
02030 
02031 template<typename _Tp> static inline MatIterator_<_Tp>
02032 operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
02033 { MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatIterator_<_Tp>&)t; }
02034 
02035 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
02036 { return *(*this + i); }
02037 
02038 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
02039 { return Mat::begin<_Tp>(); }
02040 
02041 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const
02042 { return Mat::end<_Tp>(); }
02043 
02044 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::begin()
02045 { return Mat::begin<_Tp>(); }
02046 
02047 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::end()
02048 { return Mat::end<_Tp>(); }
02049 
02050 template<typename _Tp> inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : it(_m) {}
02051 
02052 template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
02053 MatCommaInitializer_<_Tp>::operator , (T2 v)
02054 {
02055     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
02056     *this->it = _Tp(v); ++this->it;
02057     return *this;
02058 }
02059 
02060 template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
02061 {
02062     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
02063     return Mat_<_Tp>(*this->it.m);
02064 }
02065 
02066 template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
02067 {
02068     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
02069     return Mat_<_Tp>(*this->it.m);
02070 }
02071 
02072 template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
02073 operator << (const Mat_<_Tp>& m, T2 val)
02074 {
02075     MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
02076     return (commaInitializer, val);
02077 }
02078 
02080 
02081 inline SparseMat::SparseMat()
02082 : flags(MAGIC_VAL), hdr(0)
02083 {
02084 }
02085 
02086 inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
02087 : flags(MAGIC_VAL), hdr(0)
02088 {
02089     create(_dims, _sizes, _type);
02090 }
02091 
02092 inline SparseMat::SparseMat(const SparseMat& m)
02093 : flags(m.flags), hdr(m.hdr)
02094 {
02095     addref();
02096 }
02097 
02098 inline SparseMat::~SparseMat()
02099 {
02100     release();
02101 }
02102 
02103 inline SparseMat& SparseMat::operator = (const SparseMat& m)
02104 {
02105     if( this != &m )
02106     {
02107         if( m.hdr )
02108             CV_XADD(&m.hdr->refcount, 1);
02109         release();
02110         flags = m.flags;
02111         hdr = m.hdr;
02112     }
02113     return *this;
02114 }
02115 
02116 inline SparseMat& SparseMat::operator = (const Mat& m)
02117 { return (*this = SparseMat(m)); }
02118 
02119 inline SparseMat SparseMat::clone() const
02120 {
02121     SparseMat temp;
02122     this->copyTo(temp);
02123     return temp;
02124 }
02125 
02126 
02127 inline void SparseMat::assignTo( SparseMat& m, int _type ) const
02128 {
02129     if( _type < 0 )
02130         m = *this;
02131     else
02132         convertTo(m, _type);
02133 }
02134 
02135 inline void SparseMat::addref()
02136 { if( hdr ) CV_XADD(&hdr->refcount, 1); }
02137 
02138 inline void SparseMat::release()
02139 {
02140     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
02141         delete hdr;
02142     hdr = 0;
02143 }
02144 
02145 inline size_t SparseMat::elemSize() const
02146 { return CV_ELEM_SIZE(flags); }
02147 
02148 inline size_t SparseMat::elemSize1() const
02149 { return CV_ELEM_SIZE1(flags); }
02150 
02151 inline int SparseMat::type() const
02152 { return CV_MAT_TYPE(flags); }
02153 
02154 inline int SparseMat::depth() const
02155 { return CV_MAT_DEPTH(flags); }
02156 
02157 inline int SparseMat::channels() const
02158 { return CV_MAT_CN(flags); }
02159 
02160 inline const int* SparseMat::size() const
02161 {
02162     return hdr ? hdr->size : 0;
02163 }
02164 
02165 inline int SparseMat::size(int i) const
02166 {
02167     if( hdr )
02168     {
02169         CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
02170         return hdr->size[i];
02171     }
02172     return 0;
02173 }
02174 
02175 inline int SparseMat::dims() const
02176 {
02177     return hdr ? hdr->dims : 0;
02178 }
02179 
02180 inline size_t SparseMat::nzcount() const
02181 {
02182     return hdr ? hdr->nodeCount : 0;
02183 }
02184 
02185 inline size_t SparseMat::hash(int i0) const
02186 {
02187     return (size_t)i0;
02188 }
02189 
02190 inline size_t SparseMat::hash(int i0, int i1) const
02191 {
02192     return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1;
02193 }
02194 
02195 inline size_t SparseMat::hash(int i0, int i1, int i2) const
02196 {
02197     return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2;
02198 }
02199 
02200 inline size_t SparseMat::hash(const int* idx) const
02201 {
02202     size_t h = (unsigned)idx[0];
02203     if( !hdr )
02204         return 0;
02205     int i, d = hdr->dims;
02206     for( i = 1; i < d; i++ )
02207         h = h*HASH_SCALE + (unsigned)idx[i];
02208     return h;
02209 }
02210 
02211 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
02212 { return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
02213 
02214 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
02215 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
02216 
02217 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
02218 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
02219 
02220 template<typename _Tp> inline _Tp& SparseMat::ref(const int* idx, size_t* hashval)
02221 { return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
02222 
02223 template<typename _Tp> inline _Tp SparseMat::value(int i0, size_t* hashval) const
02224 {
02225     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
02226     return p ? *p : _Tp();
02227 }
02228 
02229 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
02230 {
02231     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
02232     return p ? *p : _Tp();
02233 }
02234 
02235 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
02236 {
02237     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
02238     return p ? *p : _Tp();
02239 }
02240 
02241 template<typename _Tp> inline _Tp SparseMat::value(const int* idx, size_t* hashval) const
02242 {
02243     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
02244     return p ? *p : _Tp();
02245 }
02246 
02247 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
02248 { return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); }
02249 
02250 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
02251 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); }
02252 
02253 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
02254 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); }
02255 
02256 template<typename _Tp> inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
02257 { return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); }
02258 
02259 template<typename _Tp> inline _Tp& SparseMat::value(Node* n)
02260 { return *(_Tp*)((uchar*)n + hdr->valueOffset); }
02261 
02262 template<typename _Tp> inline const _Tp& SparseMat::value(const Node* n) const
02263 { return *(const _Tp*)((const uchar*)n + hdr->valueOffset); }
02264 
02265 inline SparseMat::Node* SparseMat::node(size_t nidx)
02266 { return (Node*)&hdr->pool[nidx]; }
02267 
02268 inline const SparseMat::Node* SparseMat::node(size_t nidx) const
02269 { return (const Node*)&hdr->pool[nidx]; }
02270 
02271 inline SparseMatIterator SparseMat::begin()
02272 { return SparseMatIterator(this); }
02273 
02274 inline SparseMatConstIterator SparseMat::begin() const
02275 { return SparseMatConstIterator(this); }
02276 
02277 inline SparseMatIterator SparseMat::end()
02278 { SparseMatIterator it(this); it.seekEnd(); return it; }
02279 
02280 inline SparseMatConstIterator SparseMat::end() const
02281 { SparseMatConstIterator it(this); it.seekEnd(); return it; }
02282 
02283 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
02284 { return SparseMatIterator_<_Tp>(this); }
02285 
02286 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
02287 { return SparseMatConstIterator_<_Tp>(this); }
02288 
02289 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
02290 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
02291 
02292 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
02293 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
02294 
02295 
02296 inline SparseMatConstIterator::SparseMatConstIterator()
02297 : m(0), hashidx(0), ptr(0)
02298 {
02299 }
02300 
02301 inline SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
02302 : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
02303 {
02304 }
02305 
02306 static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
02307 { return it1.m == it2.m && it1.ptr == it2.ptr; }
02308 
02309 static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
02310 { return !(it1 == it2); }
02311 
02312 
02313 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
02314 {
02315     if( this != &it )
02316     {
02317         m = it.m;
02318         hashidx = it.hashidx;
02319         ptr = it.ptr;
02320     }
02321     return *this;
02322 }
02323 
02324 template<typename _Tp> inline const _Tp& SparseMatConstIterator::value() const
02325 { return *(_Tp*)ptr; }
02326 
02327 inline const SparseMat::Node* SparseMatConstIterator::node() const
02328 {
02329     return ptr && m && m->hdr ?
02330         (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0;
02331 }
02332 
02333 inline SparseMatConstIterator SparseMatConstIterator::operator ++(int)
02334 {
02335     SparseMatConstIterator it = *this;
02336     ++*this;
02337     return it;
02338 }
02339 
02340 
02341 inline void SparseMatConstIterator::seekEnd()
02342 {
02343     if( m && m->hdr )
02344     {
02345         hashidx = m->hdr->hashtab.size();
02346         ptr = 0;
02347     }
02348 }
02349 
02350 inline SparseMatIterator::SparseMatIterator()
02351 {}
02352 
02353 inline SparseMatIterator::SparseMatIterator(SparseMat* _m)
02354 : SparseMatConstIterator(_m)
02355 {}
02356 
02357 inline SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
02358 : SparseMatConstIterator(it)
02359 {
02360 }
02361 
02362 inline SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
02363 {
02364     (SparseMatConstIterator&)*this = it;
02365     return *this;
02366 }
02367 
02368 template<typename _Tp> inline _Tp& SparseMatIterator::value() const
02369 { return *(_Tp*)ptr; }
02370 
02371 inline SparseMat::Node* SparseMatIterator::node() const
02372 {
02373     return (SparseMat::Node*)SparseMatConstIterator::node();
02374 }
02375 
02376 inline SparseMatIterator& SparseMatIterator::operator ++()
02377 {
02378     SparseMatConstIterator::operator ++();
02379     return *this;
02380 }
02381 
02382 inline SparseMatIterator SparseMatIterator::operator ++(int)
02383 {
02384     SparseMatIterator it = *this;
02385     ++*this;
02386     return it;
02387 }
02388 
02389 
02390 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_()
02391 { flags = MAGIC_VAL | DataType<_Tp>::type; }
02392 
02393 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
02394 : SparseMat(_dims, _sizes, DataType<_Tp>::type)
02395 {}
02396 
02397 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
02398 {
02399     if( m.type() == DataType<_Tp>::type )
02400         *this = (const SparseMat_<_Tp>&)m;
02401     else
02402         m.convertTo(this, DataType<_Tp>::type);
02403 }
02404 
02405 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
02406 {
02407     this->flags = m.flags;
02408     this->hdr = m.hdr;
02409     if( this->hdr )
02410         CV_XADD(&this->hdr->refcount, 1);
02411 }
02412 
02413 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const Mat& m)
02414 {
02415     SparseMat sm(m);
02416     *this = sm;
02417 }
02418 
02419 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
02420 {
02421     SparseMat sm(m);
02422     *this = sm;
02423 }
02424 
02425 template<typename _Tp> inline SparseMat_<_Tp>&
02426 SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
02427 {
02428     if( this != &m )
02429     {
02430         if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
02431         release();
02432         flags = m.flags;
02433         hdr = m.hdr;
02434     }
02435     return *this;
02436 }
02437 
02438 template<typename _Tp> inline SparseMat_<_Tp>&
02439 SparseMat_<_Tp>::operator = (const SparseMat& m)
02440 {
02441     if( m.type() == DataType<_Tp>::type )
02442         return (*this = (const SparseMat_<_Tp>&)m);
02443     m.convertTo(*this, DataType<_Tp>::type);
02444     return *this;
02445 }
02446 
02447 template<typename _Tp> inline SparseMat_<_Tp>&
02448 SparseMat_<_Tp>::operator = (const Mat& m)
02449 { return (*this = SparseMat(m)); }
02450 
02451 template<typename _Tp> inline SparseMat_<_Tp>
02452 SparseMat_<_Tp>::clone() const
02453 {
02454     SparseMat_<_Tp> m;
02455     this->copyTo(m);
02456     return m;
02457 }
02458 
02459 template<typename _Tp> inline void
02460 SparseMat_<_Tp>::create(int _dims, const int* _sizes)
02461 {
02462     SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
02463 }
02464 
02465 template<typename _Tp> inline
02466 SparseMat_<_Tp>::operator CvSparseMat*() const
02467 {
02468     return SparseMat::operator CvSparseMat*();
02469 }
02470 
02471 template<typename _Tp> inline int SparseMat_<_Tp>::type() const
02472 { return DataType<_Tp>::type; }
02473 
02474 template<typename _Tp> inline int SparseMat_<_Tp>::depth() const
02475 { return DataType<_Tp>::depth; }
02476 
02477 template<typename _Tp> inline int SparseMat_<_Tp>::channels() const
02478 { return DataType<_Tp>::channels; }
02479 
02480 template<typename _Tp> inline _Tp&
02481 SparseMat_<_Tp>::ref(int i0, size_t* hashval)
02482 { return SparseMat::ref<_Tp>(i0, hashval); }
02483 
02484 template<typename _Tp> inline _Tp
02485 SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
02486 { return SparseMat::value<_Tp>(i0, hashval); }
02487 
02488 template<typename _Tp> inline _Tp&
02489 SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
02490 { return SparseMat::ref<_Tp>(i0, i1, hashval); }
02491 
02492 template<typename _Tp> inline _Tp
02493 SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
02494 { return SparseMat::value<_Tp>(i0, i1, hashval); }
02495 
02496 template<typename _Tp> inline _Tp&
02497 SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
02498 { return SparseMat::ref<_Tp>(i0, i1, i2, hashval); }
02499 
02500 template<typename _Tp> inline _Tp
02501 SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
02502 { return SparseMat::value<_Tp>(i0, i1, i2, hashval); }
02503 
02504 template<typename _Tp> inline _Tp&
02505 SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
02506 { return SparseMat::ref<_Tp>(idx, hashval); }
02507 
02508 template<typename _Tp> inline _Tp
02509 SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
02510 { return SparseMat::value<_Tp>(idx, hashval); }
02511 
02512 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
02513 { return SparseMatIterator_<_Tp>(this); }
02514 
02515 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
02516 { return SparseMatConstIterator_<_Tp>(this); }
02517 
02518 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
02519 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
02520 
02521 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
02522 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
02523 
02524 template<typename _Tp> inline
02525 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
02526 {}
02527 
02528 template<typename _Tp> inline
02529 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
02530 : SparseMatConstIterator(_m)
02531 {}
02532 
02533 template<typename _Tp> inline
02534 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
02535 : SparseMatConstIterator(it)
02536 {}
02537 
02538 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
02539 SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
02540 { return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
02541     (*reinterpret_cast<SparseMatConstIterator*>(this) =
02542      reinterpret_cast<const SparseMatConstIterator&>(it)); }
02543 
02544 template<typename _Tp> inline const _Tp&
02545 SparseMatConstIterator_<_Tp>::operator *() const
02546 { return *(const _Tp*)this->ptr; }
02547 
02548 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
02549 SparseMatConstIterator_<_Tp>::operator ++()
02550 {
02551     SparseMatConstIterator::operator ++();
02552     return *this;
02553 }
02554 
02555 template<typename _Tp> inline SparseMatConstIterator_<_Tp>
02556 SparseMatConstIterator_<_Tp>::operator ++(int)
02557 {
02558     SparseMatConstIterator it = *this;
02559     SparseMatConstIterator::operator ++();
02560     return it;
02561 }
02562 
02563 template<typename _Tp> inline
02564 SparseMatIterator_<_Tp>::SparseMatIterator_()
02565 {}
02566 
02567 template<typename _Tp> inline
02568 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
02569 : SparseMatConstIterator_<_Tp>(_m)
02570 {}
02571 
02572 template<typename _Tp> inline
02573 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
02574 : SparseMatConstIterator_<_Tp>(it)
02575 {}
02576 
02577 template<typename _Tp> inline SparseMatIterator_<_Tp>&
02578 SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
02579 { return reinterpret_cast<SparseMatIterator_<_Tp>&>
02580     (*reinterpret_cast<SparseMatConstIterator*>(this) =
02581      reinterpret_cast<const SparseMatConstIterator&>(it)); }
02582 
02583 template<typename _Tp> inline _Tp&
02584 SparseMatIterator_<_Tp>::operator *() const
02585 { return *(_Tp*)this->ptr; }
02586 
02587 template<typename _Tp> inline SparseMatIterator_<_Tp>&
02588 SparseMatIterator_<_Tp>::operator ++()
02589 {
02590     SparseMatConstIterator::operator ++();
02591     return *this;
02592 }
02593 
02594 template<typename _Tp> inline SparseMatIterator_<_Tp>
02595 SparseMatIterator_<_Tp>::operator ++(int)
02596 {
02597     SparseMatIterator it = *this;
02598     SparseMatConstIterator::operator ++();
02599     return it;
02600 }
02601 
02602 }
02603 
02604 #endif
02605 #endif