Renesas / opencv-lib

Dependents:   RZ_A2M_Mbed_samples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mat.inl.hpp Source File

mat.inl.hpp

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 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
00016 // Copyright (C) 2015, Itseez Inc., all rights reserved.
00017 // Third party copyrights are property of their respective owners.
00018 //
00019 // Redistribution and use in source and binary forms, with or without modification,
00020 // are permitted provided that the following conditions are met:
00021 //
00022 //   * Redistribution's of source code must retain the above copyright notice,
00023 //     this list of conditions and the following disclaimer.
00024 //
00025 //   * Redistribution's in binary form must reproduce the above copyright notice,
00026 //     this list of conditions and the following disclaimer in the documentation
00027 //     and/or other materials provided with the distribution.
00028 //
00029 //   * The name of the copyright holders may not be used to endorse or promote products
00030 //     derived from this software without specific prior written permission.
00031 //
00032 // This software is provided by the copyright holders and contributors "as is" and
00033 // any express or implied warranties, including, but not limited to, the implied
00034 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00035 // In no event shall the Intel Corporation or contributors be liable for any direct,
00036 // indirect, incidental, special, exemplary, or consequential damages
00037 // (including, but not limited to, procurement of substitute goods or services;
00038 // loss of use, data, or profits; or business interruption) however caused
00039 // and on any theory of liability, whether in contract, strict liability,
00040 // or tort (including negligence or otherwise) arising in any way out of
00041 // the use of this software, even if advised of the possibility of such damage.
00042 //
00043 //M*/
00044 
00045 #ifndef OPENCV_CORE_MATRIX_OPERATIONS_HPP
00046 #define OPENCV_CORE_MATRIX_OPERATIONS_HPP
00047 
00048 #ifndef __cplusplus
00049 #  error mat.inl.hpp header must be compiled as C++
00050 #endif
00051 
00052 namespace cv
00053 {
00054 
00055 //! @cond IGNORED
00056 
00057 //////////////////////// Input/Output Arrays ////////////////////////
00058 
00059 inline void _InputArray::init(int _flags, const void* _obj)
00060 { flags = _flags; obj = (void*)_obj; }
00061 
00062 inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
00063 { flags = _flags; obj = (void*)_obj; sz = _sz; }
00064 
00065 inline void* _InputArray::getObj() const { return obj; }
00066 inline int _InputArray::getFlags() const { return flags; }
00067 inline Size _InputArray::getSz() const { return sz; }
00068 
00069 inline _InputArray::_InputArray() { init(NONE, 0); }
00070 inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
00071 inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
00072 inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
00073 inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); }
00074 inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); }
00075 
00076 template<typename _Tp> inline
00077 _InputArray::_InputArray(const std::vector<_Tp>& vec)
00078 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
00079 
00080 inline
00081 _InputArray::_InputArray(const std::vector<bool>& vec)
00082 { init(FIXED_TYPE + STD_BOOL_VECTOR + DataType<bool>::type + ACCESS_READ, &vec); }
00083 
00084 template<typename _Tp> inline
00085 _InputArray::_InputArray(const std::vector<std::vector<_Tp> >& vec)
00086 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
00087 
00088 template<typename _Tp> inline
00089 _InputArray::_InputArray(const std::vector<Mat_<_Tp> >& vec)
00090 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_READ, &vec); }
00091 
00092 template<typename _Tp, int m, int n> inline
00093 _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
00094 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, &mtx, Size(n, m)); }
00095 
00096 template<typename _Tp> inline
00097 _InputArray::_InputArray(const _Tp* vec, int n)
00098 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, vec, Size(n, 1)); }
00099 
00100 template<typename _Tp> inline
00101 _InputArray::_InputArray(const Mat_<_Tp>& m)
00102 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_READ, &m); }
00103 
00104 inline _InputArray::_InputArray(const double& val)
00105 { init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); }
00106 
00107 inline _InputArray::_InputArray(const MatExpr& expr)
00108 { init(FIXED_TYPE + FIXED_SIZE + EXPR + ACCESS_READ, &expr); }
00109 
00110 inline _InputArray::_InputArray(const cuda::GpuMat& d_mat)
00111 { init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); }
00112 
00113 inline _InputArray::_InputArray(const std::vector<cuda::GpuMat>& d_mat)
00114 {   init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);}
00115 
00116 inline _InputArray::_InputArray(const ogl::Buffer& buf)
00117 { init(OPENGL_BUFFER + ACCESS_READ, &buf); }
00118 
00119 inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem)
00120 { init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); }
00121 
00122 inline _InputArray::~_InputArray() {}
00123 
00124 inline Mat _InputArray::getMat(int i) const
00125 {
00126     if( kind() == MAT && i < 0 )
00127         return *(const Mat*)obj;
00128     return getMat_(i);
00129 }
00130 
00131 inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }
00132 inline bool _InputArray::isUMat() const  { return kind() == _InputArray::UMAT; }
00133 inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
00134 inline bool _InputArray::isUMatVector() const  { return kind() == _InputArray::STD_VECTOR_UMAT; }
00135 inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; }
00136 inline bool _InputArray::isVector() const { return kind() == _InputArray::STD_VECTOR || kind() == _InputArray::STD_BOOL_VECTOR; }
00137 inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::STD_VECTOR_CUDA_GPU_MAT; }
00138 
00139 ////////////////////////////////////////////////////////////////////////////////////////
00140 
00141 inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
00142 inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
00143 inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
00144 inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
00145 inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
00146 inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
00147 
00148 template<typename _Tp> inline
00149 _OutputArray::_OutputArray(std::vector<_Tp>& vec)
00150 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00151 
00152 inline
00153 _OutputArray::_OutputArray(std::vector<bool>&)
00154 { CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an output array\n"); }
00155 
00156 template<typename _Tp> inline
00157 _OutputArray::_OutputArray(std::vector<std::vector<_Tp> >& vec)
00158 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00159 
00160 template<typename _Tp> inline
00161 _OutputArray::_OutputArray(std::vector<Mat_<_Tp> >& vec)
00162 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00163 
00164 template<typename _Tp> inline
00165 _OutputArray::_OutputArray(Mat_<_Tp>& m)
00166 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
00167 
00168 template<typename _Tp, int m, int n> inline
00169 _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
00170 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
00171 
00172 template<typename _Tp> inline
00173 _OutputArray::_OutputArray(_Tp* vec, int n)
00174 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
00175 
00176 template<typename _Tp> inline
00177 _OutputArray::_OutputArray(const std::vector<_Tp>& vec)
00178 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00179 
00180 template<typename _Tp> inline
00181 _OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
00182 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00183 
00184 template<typename _Tp> inline
00185 _OutputArray::_OutputArray(const std::vector<Mat_<_Tp> >& vec)
00186 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
00187 
00188 template<typename _Tp> inline
00189 _OutputArray::_OutputArray(const Mat_<_Tp>& m)
00190 { init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); }
00191 
00192 template<typename _Tp, int m, int n> inline
00193 _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
00194 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); }
00195 
00196 template<typename _Tp> inline
00197 _OutputArray::_OutputArray(const _Tp* vec, int n)
00198 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); }
00199 
00200 inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat)
00201 { init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
00202 
00203 inline _OutputArray::_OutputArray(std::vector<cuda::GpuMat>& d_mat)
00204 {   init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);}
00205 
00206 inline _OutputArray::_OutputArray(ogl::Buffer& buf)
00207 { init(OPENGL_BUFFER + ACCESS_WRITE, &buf); }
00208 
00209 inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem)
00210 { init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
00211 
00212 inline _OutputArray::_OutputArray(const Mat& m)
00213 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); }
00214 
00215 inline _OutputArray::_OutputArray(const std::vector<Mat>& vec)
00216 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
00217 
00218 inline _OutputArray::_OutputArray(const UMat& m)
00219 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); }
00220 
00221 inline _OutputArray::_OutputArray(const std::vector<UMat>& vec)
00222 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
00223 
00224 inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat)
00225 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); }
00226 
00227 
00228 inline _OutputArray::_OutputArray(const ogl::Buffer& buf)
00229 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); }
00230 
00231 inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem)
00232 { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); }
00233 
00234 ///////////////////////////////////////////////////////////////////////////////////////////
00235 
00236 inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
00237 inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
00238 inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
00239 inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
00240 inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
00241 inline _InputOutputArray::_InputOutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); }
00242 
00243 template<typename _Tp> inline
00244 _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
00245 { init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00246 
00247 inline _InputOutputArray::_InputOutputArray(std::vector<bool>&)
00248 { CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an input/output array\n"); }
00249 
00250 template<typename _Tp> inline
00251 _InputOutputArray::_InputOutputArray(std::vector<std::vector<_Tp> >& vec)
00252 { init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00253 
00254 template<typename _Tp> inline
00255 _InputOutputArray::_InputOutputArray(std::vector<Mat_<_Tp> >& vec)
00256 { init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
00257 
00258 template<typename _Tp> inline
00259 _InputOutputArray::_InputOutputArray(Mat_<_Tp>& m)
00260 { init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
00261 
00262 template<typename _Tp, int m, int n> inline
00263 _InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx)
00264 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
00265 
00266 template<typename _Tp> inline
00267 _InputOutputArray::_InputOutputArray(_Tp* vec, int n)
00268 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
00269 
00270 template<typename _Tp> inline
00271 _InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec)
00272 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00273 
00274 template<typename _Tp> inline
00275 _InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec)
00276 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
00277 
00278 template<typename _Tp> inline
00279 _InputOutputArray::_InputOutputArray(const std::vector<Mat_<_Tp> >& vec)
00280 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); }
00281 
00282 template<typename _Tp> inline
00283 _InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m)
00284 { init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); }
00285 
00286 template<typename _Tp, int m, int n> inline
00287 _InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx)
00288 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); }
00289 
00290 template<typename _Tp> inline
00291 _InputOutputArray::_InputOutputArray(const _Tp* vec, int n)
00292 { init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); }
00293 
00294 inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat)
00295 { init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
00296 
00297 inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf)
00298 { init(OPENGL_BUFFER + ACCESS_RW, &buf); }
00299 
00300 inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem)
00301 { init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
00302 
00303 inline _InputOutputArray::_InputOutputArray(const Mat& m)
00304 { init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); }
00305 
00306 inline _InputOutputArray::_InputOutputArray(const std::vector<Mat>& vec)
00307 { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); }
00308 
00309 inline _InputOutputArray::_InputOutputArray(const UMat& m)
00310 { init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); }
00311 
00312 inline _InputOutputArray::_InputOutputArray(const std::vector<UMat>& vec)
00313 { init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); }
00314 
00315 inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat)
00316 { init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); }
00317 
00318 inline _InputOutputArray::_InputOutputArray(const std::vector<cuda::GpuMat>& d_mat)
00319 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);}
00320 
00321 template<> inline _InputOutputArray::_InputOutputArray(std::vector<cuda::GpuMat>& d_mat)
00322 { init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);}
00323 
00324 inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf)
00325 { init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); }
00326 
00327 inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem)
00328 { init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); }
00329 
00330 //////////////////////////////////////////// Mat //////////////////////////////////////////
00331 
00332 inline
00333 Mat::Mat()
00334     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00335       datalimit(0), allocator(0), u(0), size(&rows)
00336 {}
00337 
00338 inline
00339 Mat::Mat(int _rows, int _cols, int _type)
00340     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00341       datalimit(0), allocator(0), u(0), size(&rows)
00342 {
00343     create(_rows, _cols, _type);
00344 }
00345 
00346 inline
00347 Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
00348     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00349       datalimit(0), allocator(0), u(0), size(&rows)
00350 {
00351     create(_rows, _cols, _type);
00352     *this = _s;
00353 }
00354 
00355 inline
00356 Mat::Mat(Size _sz, int _type)
00357     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00358       datalimit(0), allocator(0), u(0), size(&rows)
00359 {
00360     create( _sz.height, _sz.width, _type );
00361 }
00362 
00363 inline
00364 Mat::Mat(Size _sz, int _type, const Scalar& _s)
00365     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00366       datalimit(0), allocator(0), u(0), size(&rows)
00367 {
00368     create(_sz.height, _sz.width, _type);
00369     *this = _s;
00370 }
00371 
00372 inline
00373 Mat::Mat(int _dims, const int* _sz, int _type)
00374     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00375       datalimit(0), allocator(0), u(0), size(&rows)
00376 {
00377     create(_dims, _sz, _type);
00378 }
00379 
00380 inline
00381 Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
00382     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00383       datalimit(0), allocator(0), u(0), size(&rows)
00384 {
00385     create(_dims, _sz, _type);
00386     *this = _s;
00387 }
00388 
00389 inline
00390 Mat::Mat(const std::vector<int>& _sz, int _type)
00391     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00392       datalimit(0), allocator(0), u(0), size(&rows)
00393 {
00394     create(_sz, _type);
00395 }
00396 
00397 inline
00398 Mat::Mat(const std::vector<int>& _sz, int _type, const Scalar& _s)
00399     : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
00400       datalimit(0), allocator(0), u(0), size(&rows)
00401 {
00402     create(_sz, _type);
00403     *this = _s;
00404 }
00405 
00406 inline
00407 Mat::Mat(const Mat& m)
00408     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
00409       datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
00410       u(m.u), size(&rows)
00411 {
00412     if( u )
00413         CV_XADD(&u->refcount, 1);
00414     if( m.dims <= 2 )
00415     {
00416         step[0] = m.step[0]; step[1] = m.step[1];
00417     }
00418     else
00419     {
00420         dims = 0;
00421         copySize(m);
00422     }
00423 }
00424 
00425 inline
00426 Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
00427     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
00428       data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
00429       allocator(0), u(0), size(&rows)
00430 {
00431     CV_Assert(total() == 0 || data != NULL);
00432 
00433     size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
00434     size_t minstep = cols * esz;
00435     if( _step == AUTO_STEP )
00436     {
00437         _step = minstep;
00438         flags |= CONTINUOUS_FLAG;
00439     }
00440     else
00441     {
00442         if( rows == 1 ) _step = minstep;
00443         CV_DbgAssert( _step >= minstep );
00444 
00445         if (_step % esz1 != 0)
00446         {
00447             CV_Error(Error::BadStep, "Step must be a multiple of esz1");
00448         }
00449 
00450         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
00451     }
00452     step[0] = _step;
00453     step[1] = esz;
00454     datalimit = datastart + _step * rows;
00455     dataend = datalimit - _step + minstep;
00456 }
00457 
00458 inline
00459 Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
00460     : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
00461       data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
00462       allocator(0), u(0), size(&rows)
00463 {
00464     CV_Assert(total() == 0 || data != NULL);
00465 
00466     size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
00467     size_t minstep = cols*esz;
00468     if( _step == AUTO_STEP )
00469     {
00470         _step = minstep;
00471         flags |= CONTINUOUS_FLAG;
00472     }
00473     else
00474     {
00475         if( rows == 1 ) _step = minstep;
00476         CV_DbgAssert( _step >= minstep );
00477 
00478         if (_step % esz1 != 0)
00479         {
00480             CV_Error(Error::BadStep, "Step must be a multiple of esz1");
00481         }
00482 
00483         flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
00484     }
00485     step[0] = _step;
00486     step[1] = esz;
00487     datalimit = datastart + _step*rows;
00488     dataend = datalimit - _step + minstep;
00489 }
00490 
00491 template<typename _Tp> inline
00492 Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
00493     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
00494       cols(1), data(0), datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00495 {
00496     if(vec.empty())
00497         return;
00498     if( !copyData )
00499     {
00500         step[0] = step[1] = sizeof(_Tp);
00501         datastart = data = (uchar*)&vec[0];
00502         datalimit = dataend = datastart + rows * step[0];
00503     }
00504     else
00505         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
00506 }
00507 
00508 template<typename _Tp, int n> inline
00509 Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
00510     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
00511       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00512 {
00513     if( !copyData )
00514     {
00515         step[0] = step[1] = sizeof(_Tp);
00516         datastart = data = (uchar*)vec.val;
00517         datalimit = dataend = datastart + rows * step[0];
00518     }
00519     else
00520         Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
00521 }
00522 
00523 
00524 template<typename _Tp, int m, int n> inline
00525 Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
00526     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
00527       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00528 {
00529     if( !copyData )
00530     {
00531         step[0] = cols * sizeof(_Tp);
00532         step[1] = sizeof(_Tp);
00533         datastart = data = (uchar*)M.val;
00534         datalimit = dataend = datastart + rows * step[0];
00535     }
00536     else
00537         Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
00538 }
00539 
00540 template<typename _Tp> inline
00541 Mat::Mat(const Point_<_Tp>& pt, bool copyData)
00542     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
00543       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00544 {
00545     if( !copyData )
00546     {
00547         step[0] = step[1] = sizeof(_Tp);
00548         datastart = data = (uchar*)&pt.x;
00549         datalimit = dataend = datastart + rows * step[0];
00550     }
00551     else
00552     {
00553         create(2, 1, DataType<_Tp>::type);
00554         ((_Tp*)data)[0] = pt.x;
00555         ((_Tp*)data)[1] = pt.y;
00556     }
00557 }
00558 
00559 template<typename _Tp> inline
00560 Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
00561     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
00562       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00563 {
00564     if( !copyData )
00565     {
00566         step[0] = step[1] = sizeof(_Tp);
00567         datastart = data = (uchar*)&pt.x;
00568         datalimit = dataend = datastart + rows * step[0];
00569     }
00570     else
00571     {
00572         create(3, 1, DataType<_Tp>::type);
00573         ((_Tp*)data)[0] = pt.x;
00574         ((_Tp*)data)[1] = pt.y;
00575         ((_Tp*)data)[2] = pt.z;
00576     }
00577 }
00578 
00579 template<typename _Tp> inline
00580 Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
00581     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
00582       datastart(0), dataend(0), allocator(0), u(0), size(&rows)
00583 {
00584     *this = commaInitializer.operator Mat_<_Tp>();
00585 }
00586 
00587 inline
00588 Mat::~Mat()
00589 {
00590     release();
00591     if( step.p != step.buf )
00592         fastFree(step.p);
00593 }
00594 
00595 inline
00596 Mat& Mat::operator = (const Mat& m)
00597 {
00598     if( this != &m )
00599     {
00600         if( m.u )
00601             CV_XADD(&m.u->refcount, 1);
00602         release();
00603         flags  = m.flags;
00604         if( dims <= 2 && m.dims <= 2 )
00605         {
00606             dims = m.dims;
00607             rows = m.rows;
00608             cols = m.cols;
00609             step[0] = m.step[0];
00610             step[1] = m.step[1];
00611         }
00612         else
00613             copySize(m);
00614         data = m.data;
00615         datastart = m.datastart;
00616         dataend = m.dataend;
00617         datalimit = m.datalimit;
00618         allocator = m.allocator;
00619         u = m.u;
00620     }
00621     return *this;
00622 }
00623 
00624 inline
00625 Mat Mat::row(int y) const
00626 {
00627     return Mat(*this, Range(y, y + 1), Range::all());
00628 }
00629 
00630 inline
00631 Mat Mat::col(int x) const
00632 {
00633     return Mat(*this, Range::all(), Range(x, x + 1));
00634 }
00635 
00636 inline
00637 Mat Mat::rowRange(int startrow, int endrow) const
00638 {
00639     return Mat(*this, Range(startrow, endrow), Range::all());
00640 }
00641 
00642 inline
00643 Mat Mat::rowRange(const Range& r) const
00644 {
00645     return Mat(*this, r, Range::all());
00646 }
00647 
00648 inline
00649 Mat Mat::colRange(int startcol, int endcol) const
00650 {
00651     return Mat(*this, Range::all(), Range(startcol, endcol));
00652 }
00653 
00654 inline
00655 Mat Mat::colRange(const Range& r) const
00656 {
00657     return Mat(*this, Range::all(), r);
00658 }
00659 
00660 inline
00661 Mat Mat::clone() const
00662 {
00663     Mat m;
00664     copyTo(m);
00665     return m;
00666 }
00667 
00668 inline
00669 void Mat::assignTo( Mat& m, int _type ) const
00670 {
00671     if( _type < 0 )
00672         m = *this;
00673     else
00674         convertTo(m, _type);
00675 }
00676 
00677 inline
00678 void Mat::create(int _rows, int _cols, int _type)
00679 {
00680     _type &= TYPE_MASK;
00681     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
00682         return;
00683     int sz[] = {_rows, _cols};
00684     create(2, sz, _type);
00685 }
00686 
00687 inline
00688 void Mat::create(Size _sz, int _type)
00689 {
00690     create(_sz.height, _sz.width, _type);
00691 }
00692 
00693 inline
00694 void Mat::addref()
00695 {
00696     if( u )
00697         CV_XADD(&u->refcount, 1);
00698 }
00699 
00700 inline
00701 void Mat::release()
00702 {
00703     if( u && CV_XADD(&u->refcount, -1) == 1 )
00704         deallocate();
00705     u = NULL;
00706     datastart = dataend = datalimit = data = 0;
00707     for(int i = 0; i < dims; i++)
00708         size.p[i] = 0;
00709 #ifdef _DEBUG
00710     flags  = MAGIC_VAL;
00711     dims = rows = cols = 0;
00712     if(step.p != step.buf)
00713     {
00714         fastFree(step.p);
00715         step.p = step.buf;
00716         size.p = &rows;
00717     }
00718 #endif
00719 }
00720 
00721 inline
00722 Mat Mat::operator()( Range _rowRange, Range _colRange ) const
00723 {
00724     return Mat(*this, _rowRange, _colRange);
00725 }
00726 
00727 inline
00728 Mat Mat::operator()( const Rect& roi ) const
00729 {
00730     return Mat(*this, roi);
00731 }
00732 
00733 inline
00734 Mat Mat::operator()(const Range* ranges) const
00735 {
00736     return Mat(*this, ranges);
00737 }
00738 
00739 inline
00740 Mat Mat::operator()(const std::vector<Range>& ranges) const
00741 {
00742     return Mat(*this, ranges);
00743 }
00744 
00745 inline
00746 bool Mat::isContinuous() const
00747 {
00748     return (flags  & CONTINUOUS_FLAG) != 0;
00749 }
00750 
00751 inline
00752 bool Mat::isSubmatrix() const
00753 {
00754     return (flags  & SUBMATRIX_FLAG) != 0;
00755 }
00756 
00757 inline
00758 size_t Mat::elemSize() const
00759 {
00760     return dims > 0 ? step.p[dims - 1] : 0;
00761 }
00762 
00763 inline
00764 size_t Mat::elemSize1() const
00765 {
00766     return CV_ELEM_SIZE1(flags );
00767 }
00768 
00769 inline
00770 int Mat::type() const
00771 {
00772     return CV_MAT_TYPE(flags );
00773 }
00774 
00775 inline
00776 int Mat::depth() const
00777 {
00778     return CV_MAT_DEPTH(flags );
00779 }
00780 
00781 inline
00782 int Mat::channels() const
00783 {
00784     return CV_MAT_CN(flags );
00785 }
00786 
00787 inline
00788 size_t Mat::step1(int i) const
00789 {
00790     return step.p[i] / elemSize1();
00791 }
00792 
00793 inline
00794 bool Mat::empty() const
00795 {
00796     return data == 0 || total() == 0;
00797 }
00798 
00799 inline
00800 size_t Mat::total() const
00801 {
00802     if( dims <= 2 )
00803         return (size_t)rows * cols;
00804     size_t p = 1;
00805     for( int i = 0; i < dims; i++ )
00806         p *= size[i];
00807     return p;
00808 }
00809 
00810 inline
00811 uchar* Mat::ptr(int y)
00812 {
00813     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00814     return data + step.p[0] * y;
00815 }
00816 
00817 inline
00818 const uchar* Mat::ptr(int y) const
00819 {
00820     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00821     return data + step.p[0] * y;
00822 }
00823 
00824 template<typename _Tp> inline
00825 _Tp* Mat::ptr(int y)
00826 {
00827     CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
00828     return (_Tp*)(data + step.p[0] * y);
00829 }
00830 
00831 template<typename _Tp> inline
00832 const _Tp* Mat::ptr(int y) const
00833 {
00834     CV_DbgAssert( y == 0 || (data && dims >= 1 && data && (unsigned)y < (unsigned)size.p[0]) );
00835     return (const _Tp*)(data + step.p[0] * y);
00836 }
00837 
00838 inline
00839 uchar* Mat::ptr(int i0, int i1)
00840 {
00841     CV_DbgAssert(dims >= 2);
00842     CV_DbgAssert(data);
00843     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00844     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00845     return data + i0 * step.p[0] + i1 * step.p[1];
00846 }
00847 
00848 inline
00849 const uchar* Mat::ptr(int i0, int i1) const
00850 {
00851     CV_DbgAssert(dims >= 2);
00852     CV_DbgAssert(data);
00853     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00854     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00855     return data + i0 * step.p[0] + i1 * step.p[1];
00856 }
00857 
00858 template<typename _Tp> inline
00859 _Tp* Mat::ptr(int i0, int i1)
00860 {
00861     CV_DbgAssert(dims >= 2);
00862     CV_DbgAssert(data);
00863     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00864     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00865     return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
00866 }
00867 
00868 template<typename _Tp> inline
00869 const _Tp* Mat::ptr(int i0, int i1) const
00870 {
00871     CV_DbgAssert(dims >= 2);
00872     CV_DbgAssert(data);
00873     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00874     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00875     return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]);
00876 }
00877 
00878 inline
00879 uchar* Mat::ptr(int i0, int i1, int i2)
00880 {
00881     CV_DbgAssert(dims >= 3);
00882     CV_DbgAssert(data);
00883     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00884     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00885     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00886     return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
00887 }
00888 
00889 inline
00890 const uchar* Mat::ptr(int i0, int i1, int i2) const
00891 {
00892     CV_DbgAssert(dims >= 3);
00893     CV_DbgAssert(data);
00894     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00895     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00896     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00897     return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
00898 }
00899 
00900 template<typename _Tp> inline
00901 _Tp* Mat::ptr(int i0, int i1, int i2)
00902 {
00903     CV_DbgAssert(dims >= 3);
00904     CV_DbgAssert(data);
00905     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00906     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00907     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00908     return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
00909 }
00910 
00911 template<typename _Tp> inline
00912 const _Tp* Mat::ptr(int i0, int i1, int i2) const
00913 {
00914     CV_DbgAssert(dims >= 3);
00915     CV_DbgAssert(data);
00916     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00917     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
00918     CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
00919     return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]);
00920 }
00921 
00922 inline
00923 uchar* Mat::ptr(const int* idx)
00924 {
00925     int i, d = dims;
00926     uchar* p = data;
00927     CV_DbgAssert( d >= 1 && p );
00928     for( i = 0; i < d; i++ )
00929     {
00930         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
00931         p += idx[i] * step.p[i];
00932     }
00933     return p;
00934 }
00935 
00936 inline
00937 const uchar* Mat::ptr(const int* idx) const
00938 {
00939     int i, d = dims;
00940     uchar* p = data;
00941     CV_DbgAssert( d >= 1 && p );
00942     for( i = 0; i < d; i++ )
00943     {
00944         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
00945         p += idx[i] * step.p[i];
00946     }
00947     return p;
00948 }
00949 
00950 template<typename _Tp> inline
00951 _Tp& Mat::at(int i0, int i1)
00952 {
00953     CV_DbgAssert(dims <= 2);
00954     CV_DbgAssert(data);
00955     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00956     CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00957     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00958     return ((_Tp*)(data + step.p[0] * i0))[i1];
00959 }
00960 
00961 template<typename _Tp> inline
00962 const _Tp& Mat::at(int i0, int i1) const
00963 {
00964     CV_DbgAssert(dims <= 2);
00965     CV_DbgAssert(data);
00966     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
00967     CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00968     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00969     return ((const _Tp*)(data + step.p[0] * i0))[i1];
00970 }
00971 
00972 template<typename _Tp> inline
00973 _Tp& Mat::at(Point pt)
00974 {
00975     CV_DbgAssert(dims <= 2);
00976     CV_DbgAssert(data);
00977     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
00978     CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00979     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00980     return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
00981 }
00982 
00983 template<typename _Tp> inline
00984 const _Tp& Mat::at(Point pt) const
00985 {
00986     CV_DbgAssert(dims <= 2);
00987     CV_DbgAssert(data);
00988     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
00989     CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
00990     CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00991     return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
00992 }
00993 
00994 template<typename _Tp> inline
00995 _Tp& Mat::at(int i0)
00996 {
00997     CV_DbgAssert(dims <= 2);
00998     CV_DbgAssert(data);
00999     CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1]));
01000     CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type));
01001     if( isContinuous() || size.p[0] == 1 )
01002         return ((_Tp*)data)[i0];
01003     if( size.p[1] == 1 )
01004         return *(_Tp*)(data + step.p[0] * i0);
01005     int i = i0 / cols, j = i0 - i * cols;
01006     return ((_Tp*)(data + step.p[0] * i))[j];
01007 }
01008 
01009 template<typename _Tp> inline
01010 const _Tp& Mat::at(int i0) const
01011 {
01012     CV_DbgAssert(dims <= 2);
01013     CV_DbgAssert(data);
01014     CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1]));
01015     CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type));
01016     if( isContinuous() || size.p[0] == 1 )
01017         return ((const _Tp*)data)[i0];
01018     if( size.p[1] == 1 )
01019         return *(const _Tp*)(data + step.p[0] * i0);
01020     int i = i0 / cols, j = i0 - i * cols;
01021     return ((const _Tp*)(data + step.p[0] * i))[j];
01022 }
01023 
01024 template<typename _Tp> inline
01025 _Tp& Mat::at(int i0, int i1, int i2)
01026 {
01027     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01028     return *(_Tp*)ptr(i0, i1, i2);
01029 }
01030 
01031 template<typename _Tp> inline
01032 const _Tp& Mat::at(int i0, int i1, int i2) const
01033 {
01034     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01035     return *(const _Tp*)ptr(i0, i1, i2);
01036 }
01037 
01038 template<typename _Tp> inline
01039 _Tp& Mat::at(const int* idx)
01040 {
01041     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01042     return *(_Tp*)ptr(idx);
01043 }
01044 
01045 template<typename _Tp> inline
01046 const _Tp& Mat::at(const int* idx) const
01047 {
01048     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01049     return *(const _Tp*)ptr(idx);
01050 }
01051 
01052 template<typename _Tp, int n> inline
01053 _Tp& Mat::at(const Vec<int, n>& idx)
01054 {
01055     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01056     return *(_Tp*)ptr(idx.val);
01057 }
01058 
01059 template<typename _Tp, int n> inline
01060 const _Tp& Mat::at(const Vec<int, n>& idx) const
01061 {
01062     CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
01063     return *(const _Tp*)ptr(idx.val);
01064 }
01065 
01066 template<typename _Tp> inline
01067 MatConstIterator_<_Tp> Mat::begin() const
01068 {
01069     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01070     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
01071 }
01072 
01073 template<typename _Tp> inline
01074 MatConstIterator_<_Tp> Mat::end() const
01075 {
01076     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01077     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
01078     it += total();
01079     return it;
01080 }
01081 
01082 template<typename _Tp> inline
01083 MatIterator_<_Tp> Mat::begin()
01084 {
01085     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01086     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
01087 }
01088 
01089 template<typename _Tp> inline
01090 MatIterator_<_Tp> Mat::end()
01091 {
01092     CV_DbgAssert( elemSize() == sizeof(_Tp) );
01093     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
01094     it += total();
01095     return it;
01096 }
01097 
01098 template<typename _Tp, typename Functor> inline
01099 void Mat::forEach(const Functor& operation) {
01100     this->forEach_impl<_Tp>(operation);
01101 }
01102 
01103 template<typename _Tp, typename Functor> inline
01104 void Mat::forEach(const Functor& operation) const {
01105     // call as not const
01106     (const_cast<Mat*>(this))->forEach<const _Tp>(operation);
01107 }
01108 
01109 template<typename _Tp> inline
01110 Mat::operator std::vector<_Tp>() const
01111 {
01112     std::vector<_Tp> v;
01113     copyTo(v);
01114     return v;
01115 }
01116 
01117 template<typename _Tp, int n> inline
01118 Mat::operator Vec<_Tp, n>() const
01119 {
01120     CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
01121                rows + cols - 1 == n && channels() == 1 );
01122 
01123     if( isContinuous() && type() == DataType<_Tp>::type )
01124         return Vec<_Tp, n>((_Tp*)data);
01125     Vec<_Tp, n> v;
01126     Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
01127     convertTo(tmp, tmp.type());
01128     return v;
01129 }
01130 
01131 template<typename _Tp, int m, int n> inline
01132 Mat::operator Matx<_Tp, m, n>() const
01133 {
01134     CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
01135 
01136     if( isContinuous() && type() == DataType<_Tp>::type )
01137         return Matx<_Tp, m, n>((_Tp*)data);
01138     Matx<_Tp, m, n> mtx;
01139     Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
01140     convertTo(tmp, tmp.type());
01141     return mtx;
01142 }
01143 
01144 template<typename _Tp> inline
01145 void Mat::push_back(const _Tp& elem)
01146 {
01147     if( !data )
01148     {
01149         *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
01150         return;
01151     }
01152     CV_Assert(DataType<_Tp>::type == type() && cols == 1
01153               /* && dims == 2 (cols == 1 implies dims == 2) */);
01154     const uchar* tmp = dataend + step[0];
01155     if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
01156     {
01157         *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
01158         dataend = tmp;
01159     }
01160     else
01161         push_back_(&elem);
01162 }
01163 
01164 template<typename _Tp> inline
01165 void Mat::push_back(const Mat_<_Tp>& m)
01166 {
01167     push_back((const Mat&)m);
01168 }
01169 
01170 template<> inline
01171 void Mat::push_back(const MatExpr& expr)
01172 {
01173     push_back(static_cast<Mat>(expr));
01174 }
01175 
01176 #ifdef CV_CXX_MOVE_SEMANTICS
01177 
01178 inline
01179 Mat::Mat(Mat&& m)
01180     : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
01181       datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
01182       u(m.u), size(&rows)
01183 {
01184     if (m.dims <= 2)  // move new step/size info
01185     {
01186         step[0] = m.step[0];
01187         step[1] = m.step[1];
01188     }
01189     else
01190     {
01191         CV_DbgAssert(m.step.p != m.step.buf);
01192         step.p = m.step.p;
01193         size.p = m.size.p;
01194         m.step.p = m.step.buf;
01195         m.size.p = &m.rows;
01196     }
01197     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
01198     m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
01199     m.allocator = NULL;
01200     m.u = NULL;
01201 }
01202 
01203 inline
01204 Mat& Mat::operator = (Mat&& m)
01205 {
01206     if (this == &m)
01207       return *this;
01208 
01209     release();
01210     flags  = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; data = m.data;
01211     datastart = m.datastart; dataend = m.dataend; datalimit = m.datalimit; allocator = m.allocator;
01212     u = m.u;
01213     if (step.p != step.buf) // release self step/size
01214     {
01215         fastFree(step.p);
01216         step.p = step.buf;
01217         size.p = &rows;
01218     }
01219     if (m.dims <= 2) // move new step/size info
01220     {
01221         step[0] = m.step[0];
01222         step[1] = m.step[1];
01223     }
01224     else
01225     {
01226         CV_DbgAssert(m.step.p != m.step.buf);
01227         step.p = m.step.p;
01228         size.p = m.size.p;
01229         m.step.p = m.step.buf;
01230         m.size.p = &m.rows;
01231     }
01232     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
01233     m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
01234     m.allocator = NULL;
01235     m.u = NULL;
01236     return *this;
01237 }
01238 
01239 #endif
01240 
01241 
01242 ///////////////////////////// MatSize ////////////////////////////
01243 
01244 inline
01245 MatSize::MatSize(int* _p)
01246     : p(_p) {}
01247 
01248 inline
01249 Size MatSize::operator()() const
01250 {
01251     CV_DbgAssert(p[-1] <= 2);
01252     return Size(p[1], p[0]);
01253 }
01254 
01255 inline
01256 const int& MatSize::operator[](int i) const
01257 {
01258     return p[i];
01259 }
01260 
01261 inline
01262 int& MatSize::operator[](int i)
01263 {
01264     return p[i];
01265 }
01266 
01267 inline
01268 MatSize::operator const int*() const
01269 {
01270     return p;
01271 }
01272 
01273 inline
01274 bool MatSize::operator == (const MatSize& sz) const
01275 {
01276     int d = p[-1];
01277     int dsz = sz.p[-1];
01278     if( d != dsz )
01279         return false;
01280     if( d == 2 )
01281         return p[0] == sz.p[0] && p[1] == sz.p[1];
01282 
01283     for( int i = 0; i < d; i++ )
01284         if( p[i] != sz.p[i] )
01285             return false;
01286     return true;
01287 }
01288 
01289 inline
01290 bool MatSize::operator != (const MatSize& sz) const
01291 {
01292     return !(*this == sz);
01293 }
01294 
01295 
01296 
01297 ///////////////////////////// MatStep ////////////////////////////
01298 
01299 inline
01300 MatStep::MatStep()
01301 {
01302     p = buf; p[0] = p[1] = 0;
01303 }
01304 
01305 inline
01306 MatStep::MatStep(size_t s)
01307 {
01308     p = buf; p[0] = s; p[1] = 0;
01309 }
01310 
01311 inline
01312 const size_t& MatStep::operator[](int i) const
01313 {
01314     return p[i];
01315 }
01316 
01317 inline
01318 size_t& MatStep::operator[](int i)
01319 {
01320     return p[i];
01321 }
01322 
01323 inline MatStep::operator size_t() const
01324 {
01325     CV_DbgAssert( p == buf );
01326     return buf[0];
01327 }
01328 
01329 inline MatStep& MatStep::operator = (size_t s)
01330 {
01331     CV_DbgAssert( p == buf );
01332     buf[0] = s;
01333     return *this;
01334 }
01335 
01336 
01337 
01338 ////////////////////////////// Mat_<_Tp> ////////////////////////////
01339 
01340 template<typename _Tp> inline
01341 Mat_<_Tp>::Mat_()
01342     : Mat()
01343 {
01344     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01345 }
01346 
01347 template<typename _Tp> inline
01348 Mat_<_Tp>::Mat_(int _rows, int _cols)
01349     : Mat(_rows, _cols, DataType<_Tp>::type)
01350 {
01351 }
01352 
01353 template<typename _Tp> inline
01354 Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
01355     : Mat(_rows, _cols, DataType<_Tp>::type)
01356 {
01357     *this = value;
01358 }
01359 
01360 template<typename _Tp> inline
01361 Mat_<_Tp>::Mat_(Size _sz)
01362     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
01363 {}
01364 
01365 template<typename _Tp> inline
01366 Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
01367     : Mat(_sz.height, _sz.width, DataType<_Tp>::type)
01368 {
01369     *this = value;
01370 }
01371 
01372 template<typename _Tp> inline
01373 Mat_<_Tp>::Mat_(int _dims, const int* _sz)
01374     : Mat(_dims, _sz, DataType<_Tp>::type)
01375 {}
01376 
01377 template<typename _Tp> inline
01378 Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
01379     : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s))
01380 {}
01381 
01382 template<typename _Tp> inline
01383 Mat_<_Tp>::Mat_(int _dims, const int* _sz, _Tp* _data, const size_t* _steps)
01384     : Mat(_dims, _sz, DataType<_Tp>::type, _data, _steps)
01385 {}
01386 
01387 template<typename _Tp> inline
01388 Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
01389     : Mat(m, ranges)
01390 {}
01391 
01392 template<typename _Tp> inline
01393 Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const std::vector<Range>& ranges)
01394     : Mat(m, ranges)
01395 {}
01396 
01397 template<typename _Tp> inline
01398 Mat_<_Tp>::Mat_(const Mat& m)
01399     : Mat()
01400 {
01401     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01402     *this = m;
01403 }
01404 
01405 template<typename _Tp> inline
01406 Mat_<_Tp>::Mat_(const Mat_& m)
01407     : Mat(m)
01408 {}
01409 
01410 template<typename _Tp> inline
01411 Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
01412     : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps)
01413 {}
01414 
01415 template<typename _Tp> inline
01416 Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
01417     : Mat(m, _rowRange, _colRange)
01418 {}
01419 
01420 template<typename _Tp> inline
01421 Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
01422     : Mat(m, roi)
01423 {}
01424 
01425 template<typename _Tp> template<int n> inline
01426 Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
01427     : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
01428 {
01429     CV_Assert(n%DataType<_Tp>::channels == 0);
01430     if( copyData )
01431         *this = clone();
01432 }
01433 
01434 template<typename _Tp> template<int m, int n> inline
01435 Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& M, bool copyData)
01436     : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
01437 {
01438     CV_Assert(n % DataType<_Tp>::channels == 0);
01439     if( copyData )
01440         *this = clone();
01441 }
01442 
01443 template<typename _Tp> inline
01444 Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
01445     : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
01446 {
01447     CV_Assert(2 % DataType<_Tp>::channels == 0);
01448     if( copyData )
01449         *this = clone();
01450 }
01451 
01452 template<typename _Tp> inline
01453 Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
01454     : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
01455 {
01456     CV_Assert(3 % DataType<_Tp>::channels == 0);
01457     if( copyData )
01458         *this = clone();
01459 }
01460 
01461 template<typename _Tp> inline
01462 Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
01463     : Mat(commaInitializer)
01464 {}
01465 
01466 template<typename _Tp> inline
01467 Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
01468     : Mat(vec, copyData)
01469 {}
01470 
01471 template<typename _Tp> inline
01472 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
01473 {
01474     if( DataType<_Tp>::type == m.type() )
01475     {
01476         Mat::operator = (m);
01477         return *this;
01478     }
01479     if( DataType<_Tp>::depth == m.depth() )
01480     {
01481         return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
01482     }
01483     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
01484     m.convertTo(*this, type());
01485     return *this;
01486 }
01487 
01488 template<typename _Tp> inline
01489 Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
01490 {
01491     Mat::operator=(m);
01492     return *this;
01493 }
01494 
01495 template<typename _Tp> inline
01496 Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
01497 {
01498     typedef typename DataType<_Tp>::vec_type VT;
01499     Mat::operator=(Scalar((const VT&)s));
01500     return *this;
01501 }
01502 
01503 template<typename _Tp> inline
01504 void Mat_<_Tp>::create(int _rows, int _cols)
01505 {
01506     Mat::create(_rows, _cols, DataType<_Tp>::type);
01507 }
01508 
01509 template<typename _Tp> inline
01510 void Mat_<_Tp>::create(Size _sz)
01511 {
01512     Mat::create(_sz, DataType<_Tp>::type);
01513 }
01514 
01515 template<typename _Tp> inline
01516 void Mat_<_Tp>::create(int _dims, const int* _sz)
01517 {
01518     Mat::create(_dims, _sz, DataType<_Tp>::type);
01519 }
01520 
01521 template<typename _Tp> inline
01522 Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
01523 {
01524     return Mat_<_Tp>(Mat::cross(m));
01525 }
01526 
01527 template<typename _Tp> template<typename T2> inline
01528 Mat_<_Tp>::operator Mat_<T2>() const
01529 {
01530     return Mat_<T2>(*this);
01531 }
01532 
01533 template<typename _Tp> inline
01534 Mat_<_Tp> Mat_<_Tp>::row(int y) const
01535 {
01536     return Mat_(*this, Range(y, y+1), Range::all());
01537 }
01538 
01539 template<typename _Tp> inline
01540 Mat_<_Tp> Mat_<_Tp>::col(int x) const
01541 {
01542     return Mat_(*this, Range::all(), Range(x, x+1));
01543 }
01544 
01545 template<typename _Tp> inline
01546 Mat_<_Tp> Mat_<_Tp>::diag(int d) const
01547 {
01548     return Mat_(Mat::diag(d));
01549 }
01550 
01551 template<typename _Tp> inline
01552 Mat_<_Tp> Mat_<_Tp>::clone() const
01553 {
01554     return Mat_(Mat::clone());
01555 }
01556 
01557 template<typename _Tp> inline
01558 size_t Mat_<_Tp>::elemSize() const
01559 {
01560     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
01561     return sizeof(_Tp);
01562 }
01563 
01564 template<typename _Tp> inline
01565 size_t Mat_<_Tp>::elemSize1() const
01566 {
01567     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels );
01568     return sizeof(_Tp) / DataType<_Tp>::channels;
01569 }
01570 
01571 template<typename _Tp> inline
01572 int Mat_<_Tp>::type() const
01573 {
01574     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
01575     return DataType<_Tp>::type;
01576 }
01577 
01578 template<typename _Tp> inline
01579 int Mat_<_Tp>::depth() const
01580 {
01581     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
01582     return DataType<_Tp>::depth;
01583 }
01584 
01585 template<typename _Tp> inline
01586 int Mat_<_Tp>::channels() const
01587 {
01588     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
01589     return DataType<_Tp>::channels;
01590 }
01591 
01592 template<typename _Tp> inline
01593 size_t Mat_<_Tp>::stepT(int i) const
01594 {
01595     return step.p[i] / elemSize();
01596 }
01597 
01598 template<typename _Tp> inline
01599 size_t Mat_<_Tp>::step1(int i) const
01600 {
01601     return step.p[i] / elemSize1();
01602 }
01603 
01604 template<typename _Tp> inline
01605 Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
01606 {
01607     return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));
01608 }
01609 
01610 template<typename _Tp> inline
01611 Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
01612 {
01613     return Mat_<_Tp>(*this, _rowRange, _colRange);
01614 }
01615 
01616 template<typename _Tp> inline
01617 Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
01618 {
01619     return Mat_<_Tp>(*this, roi);
01620 }
01621 
01622 template<typename _Tp> inline
01623 Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
01624 {
01625     return Mat_<_Tp>(*this, ranges);
01626 }
01627 
01628 template<typename _Tp> inline
01629 Mat_<_Tp> Mat_<_Tp>::operator()(const std::vector<Range>& ranges) const
01630 {
01631     return Mat_<_Tp>(*this, ranges);
01632 }
01633 
01634 template<typename _Tp> inline
01635 _Tp* Mat_<_Tp>::operator [](int y)
01636 {
01637     CV_DbgAssert( 0 <= y && y < rows );
01638     return (_Tp*)(data + y*step.p[0]);
01639 }
01640 
01641 template<typename _Tp> inline
01642 const _Tp* Mat_<_Tp>::operator [](int y) const
01643 {
01644     CV_DbgAssert( 0 <= y && y < rows );
01645     return (const _Tp*)(data + y*step.p[0]);
01646 }
01647 
01648 template<typename _Tp> inline
01649 _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
01650 {
01651     CV_DbgAssert(dims <= 2);
01652     CV_DbgAssert(data);
01653     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
01654     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
01655     CV_DbgAssert(type() == DataType<_Tp>::type);
01656     return ((_Tp*)(data + step.p[0] * i0))[i1];
01657 }
01658 
01659 template<typename _Tp> inline
01660 const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
01661 {
01662     CV_DbgAssert(dims <= 2);
01663     CV_DbgAssert(data);
01664     CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
01665     CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
01666     CV_DbgAssert(type() == DataType<_Tp>::type);
01667     return ((const _Tp*)(data + step.p[0] * i0))[i1];
01668 }
01669 
01670 template<typename _Tp> inline
01671 _Tp& Mat_<_Tp>::operator ()(Point pt)
01672 {
01673     CV_DbgAssert(dims <= 2);
01674     CV_DbgAssert(data);
01675     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
01676     CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]);
01677     CV_DbgAssert(type() == DataType<_Tp>::type);
01678     return ((_Tp*)(data + step.p[0] * pt.y))[pt.x];
01679 }
01680 
01681 template<typename _Tp> inline
01682 const _Tp& Mat_<_Tp>::operator ()(Point pt) const
01683 {
01684     CV_DbgAssert(dims <= 2);
01685     CV_DbgAssert(data);
01686     CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]);
01687     CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]);
01688     CV_DbgAssert(type() == DataType<_Tp>::type);
01689     return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x];
01690 }
01691 
01692 template<typename _Tp> inline
01693 _Tp& Mat_<_Tp>::operator ()(const int* idx)
01694 {
01695     return Mat::at<_Tp>(idx);
01696 }
01697 
01698 template<typename _Tp> inline
01699 const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
01700 {
01701     return Mat::at<_Tp>(idx);
01702 }
01703 
01704 template<typename _Tp> template<int n> inline
01705 _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
01706 {
01707     return Mat::at<_Tp>(idx);
01708 }
01709 
01710 template<typename _Tp> template<int n> inline
01711 const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
01712 {
01713     return Mat::at<_Tp>(idx);
01714 }
01715 
01716 template<typename _Tp> inline
01717 _Tp& Mat_<_Tp>::operator ()(int i0)
01718 {
01719     return this->at<_Tp>(i0);
01720 }
01721 
01722 template<typename _Tp> inline
01723 const _Tp& Mat_<_Tp>::operator ()(int i0) const
01724 {
01725     return this->at<_Tp>(i0);
01726 }
01727 
01728 template<typename _Tp> inline
01729 _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
01730 {
01731     return this->at<_Tp>(i0, i1, i2);
01732 }
01733 
01734 template<typename _Tp> inline
01735 const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
01736 {
01737     return this->at<_Tp>(i0, i1, i2);
01738 }
01739 
01740 template<typename _Tp> inline
01741 Mat_<_Tp>::operator std::vector<_Tp>() const
01742 {
01743     std::vector<_Tp> v;
01744     copyTo(v);
01745     return v;
01746 }
01747 
01748 template<typename _Tp> template<int n> inline
01749 Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
01750 {
01751     CV_Assert(n % DataType<_Tp>::channels == 0);
01752 
01753 #if defined _MSC_VER
01754     const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround)
01755     return pMat->operator Vec<typename DataType<_Tp>::channel_type, n>();
01756 #else
01757     return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
01758 #endif
01759 }
01760 
01761 template<typename _Tp> template<int m, int n> inline
01762 Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
01763 {
01764     CV_Assert(n % DataType<_Tp>::channels == 0);
01765 
01766 #if defined _MSC_VER
01767     const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround)
01768     Matx<typename DataType<_Tp>::channel_type, m, n> res = pMat->operator Matx<typename DataType<_Tp>::channel_type, m, n>();
01769     return res;
01770 #else
01771     Matx<typename DataType<_Tp>::channel_type, m, n> res = this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
01772     return res;
01773 #endif
01774 }
01775 
01776 template<typename _Tp> inline
01777 MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
01778 {
01779     return Mat::begin<_Tp>();
01780 }
01781 
01782 template<typename _Tp> inline
01783 MatConstIterator_<_Tp> Mat_<_Tp>::end() const
01784 {
01785     return Mat::end<_Tp>();
01786 }
01787 
01788 template<typename _Tp> inline
01789 MatIterator_<_Tp> Mat_<_Tp>::begin()
01790 {
01791     return Mat::begin<_Tp>();
01792 }
01793 
01794 template<typename _Tp> inline
01795 MatIterator_<_Tp> Mat_<_Tp>::end()
01796 {
01797     return Mat::end<_Tp>();
01798 }
01799 
01800 template<typename _Tp> template<typename Functor> inline
01801 void Mat_<_Tp>::forEach(const Functor& operation) {
01802     Mat::forEach<_Tp, Functor>(operation);
01803 }
01804 
01805 template<typename _Tp> template<typename Functor> inline
01806 void Mat_<_Tp>::forEach(const Functor& operation) const {
01807     Mat::forEach<_Tp, Functor>(operation);
01808 }
01809 
01810 #ifdef CV_CXX_MOVE_SEMANTICS
01811 
01812 template<typename _Tp> inline
01813 Mat_<_Tp>::Mat_(Mat_&& m)
01814     : Mat(m)
01815 {
01816 }
01817 
01818 template<typename _Tp> inline
01819 Mat_<_Tp>& Mat_<_Tp>::operator = (Mat_&& m)
01820 {
01821     Mat::operator = (m);
01822     return *this;
01823 }
01824 
01825 template<typename _Tp> inline
01826 Mat_<_Tp>::Mat_(Mat&& m)
01827     : Mat()
01828 {
01829     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01830     *this = m;
01831 }
01832 
01833 template<typename _Tp> inline
01834 Mat_<_Tp>& Mat_<_Tp>::operator = (Mat&& m)
01835 {
01836     if( DataType<_Tp>::type == m.type() )
01837     {
01838         Mat::operator = ((Mat&&)m);
01839         return *this;
01840     }
01841     if( DataType<_Tp>::depth == m.depth() )
01842     {
01843         Mat::operator = ((Mat&&)m.reshape(DataType<_Tp>::channels, m.dims, 0));
01844         return *this;
01845     }
01846     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
01847     m.convertTo(*this, type());
01848     return *this;
01849 }
01850 
01851 template<typename _Tp> inline
01852 Mat_<_Tp>::Mat_(MatExpr&& e)
01853     : Mat()
01854 {
01855     flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
01856     *this = Mat(e);
01857 }
01858 
01859 #endif
01860 
01861 ///////////////////////////// SparseMat /////////////////////////////
01862 
01863 inline
01864 SparseMat::SparseMat()
01865     : flags(MAGIC_VAL), hdr(0)
01866 {}
01867 
01868 inline
01869 SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
01870     : flags(MAGIC_VAL), hdr(0)
01871 {
01872     create(_dims, _sizes, _type);
01873 }
01874 
01875 inline
01876 SparseMat::SparseMat(const SparseMat& m)
01877     : flags(m.flags), hdr(m.hdr)
01878 {
01879     addref();
01880 }
01881 
01882 inline
01883 SparseMat::~SparseMat()
01884 {
01885     release();
01886 }
01887 
01888 inline
01889 SparseMat& SparseMat::operator = (const SparseMat& m)
01890 {
01891     if( this != &m )
01892     {
01893         if( m.hdr )
01894             CV_XADD(&m.hdr->refcount, 1);
01895         release();
01896         flags = m.flags;
01897         hdr = m.hdr;
01898     }
01899     return *this;
01900 }
01901 
01902 inline
01903 SparseMat& SparseMat::operator = (const Mat& m)
01904 {
01905     return (*this = SparseMat(m));
01906 }
01907 
01908 inline
01909 SparseMat SparseMat::clone() const
01910 {
01911     SparseMat temp;
01912     this->copyTo(temp);
01913     return temp;
01914 }
01915 
01916 inline
01917 void SparseMat::assignTo( SparseMat& m, int _type ) const
01918 {
01919     if( _type < 0 )
01920         m = *this;
01921     else
01922         convertTo(m, _type);
01923 }
01924 
01925 inline
01926 void SparseMat::addref()
01927 {
01928     if( hdr )
01929         CV_XADD(&hdr->refcount, 1);
01930 }
01931 
01932 inline
01933 void SparseMat::release()
01934 {
01935     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
01936         delete hdr;
01937     hdr = 0;
01938 }
01939 
01940 inline
01941 size_t SparseMat::elemSize() const
01942 {
01943     return CV_ELEM_SIZE(flags);
01944 }
01945 
01946 inline
01947 size_t SparseMat::elemSize1() const
01948 {
01949     return CV_ELEM_SIZE1(flags);
01950 }
01951 
01952 inline
01953 int SparseMat::type() const
01954 {
01955     return CV_MAT_TYPE(flags);
01956 }
01957 
01958 inline
01959 int SparseMat::depth() const
01960 {
01961     return CV_MAT_DEPTH(flags);
01962 }
01963 
01964 inline
01965 int SparseMat::channels() const
01966 {
01967     return CV_MAT_CN(flags);
01968 }
01969 
01970 inline
01971 const int* SparseMat::size() const
01972 {
01973     return hdr ? hdr->size : 0;
01974 }
01975 
01976 inline
01977 int SparseMat::size(int i) const
01978 {
01979     if( hdr )
01980     {
01981         CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
01982         return hdr->size[i];
01983     }
01984     return 0;
01985 }
01986 
01987 inline
01988 int SparseMat::dims() const
01989 {
01990     return hdr ? hdr->dims : 0;
01991 }
01992 
01993 inline
01994 size_t SparseMat::nzcount() const
01995 {
01996     return hdr ? hdr->nodeCount : 0;
01997 }
01998 
01999 inline
02000 size_t SparseMat::hash(int i0) const
02001 {
02002     return (size_t)i0;
02003 }
02004 
02005 inline
02006 size_t SparseMat::hash(int i0, int i1) const
02007 {
02008     return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
02009 }
02010 
02011 inline
02012 size_t SparseMat::hash(int i0, int i1, int i2) const
02013 {
02014     return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
02015 }
02016 
02017 inline
02018 size_t SparseMat::hash(const int* idx) const
02019 {
02020     size_t h = (unsigned)idx[0];
02021     if( !hdr )
02022         return 0;
02023     int d = hdr->dims;
02024     for(int i = 1; i < d; i++ )
02025         h = h * HASH_SCALE + (unsigned)idx[i];
02026     return h;
02027 }
02028 
02029 template<typename _Tp> inline
02030 _Tp& SparseMat::ref(int i0, size_t* hashval)
02031 {
02032     return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval);
02033 }
02034 
02035 template<typename _Tp> inline
02036 _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
02037 {
02038     return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval);
02039 }
02040 
02041 template<typename _Tp> inline
02042 _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
02043 {
02044     return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval);
02045 }
02046 
02047 template<typename _Tp> inline
02048 _Tp& SparseMat::ref(const int* idx, size_t* hashval)
02049 {
02050     return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval);
02051 }
02052 
02053 template<typename _Tp> inline
02054 _Tp SparseMat::value(int i0, size_t* hashval) const
02055 {
02056     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
02057     return p ? *p : _Tp();
02058 }
02059 
02060 template<typename _Tp> inline
02061 _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
02062 {
02063     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
02064     return p ? *p : _Tp();
02065 }
02066 
02067 template<typename _Tp> inline
02068 _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
02069 {
02070     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
02071     return p ? *p : _Tp();
02072 }
02073 
02074 template<typename _Tp> inline
02075 _Tp SparseMat::value(const int* idx, size_t* hashval) const
02076 {
02077     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
02078     return p ? *p : _Tp();
02079 }
02080 
02081 template<typename _Tp> inline
02082 const _Tp* SparseMat::find(int i0, size_t* hashval) const
02083 {
02084     return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
02085 }
02086 
02087 template<typename _Tp> inline
02088 const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
02089 {
02090     return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
02091 }
02092 
02093 template<typename _Tp> inline
02094 const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
02095 {
02096     return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
02097 }
02098 
02099 template<typename _Tp> inline
02100 const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
02101 {
02102     return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
02103 }
02104 
02105 template<typename _Tp> inline
02106 _Tp& SparseMat::value(Node* n)
02107 {
02108     return *(_Tp*)((uchar*)n + hdr->valueOffset);
02109 }
02110 
02111 template<typename _Tp> inline
02112 const _Tp& SparseMat::value(const Node* n) const
02113 {
02114     return *(const _Tp*)((const uchar*)n + hdr->valueOffset);
02115 }
02116 
02117 inline
02118 SparseMat::Node* SparseMat::node(size_t nidx)
02119 {
02120     return (Node*)(void*)&hdr->pool[nidx];
02121 }
02122 
02123 inline
02124 const SparseMat::Node* SparseMat::node(size_t nidx) const
02125 {
02126     return (const Node*)(const void*)&hdr->pool[nidx];
02127 }
02128 
02129 inline
02130 SparseMatIterator SparseMat::begin()
02131 {
02132     return SparseMatIterator(this);
02133 }
02134 
02135 inline
02136 SparseMatConstIterator SparseMat::begin() const
02137 {
02138     return SparseMatConstIterator(this);
02139 }
02140 
02141 inline
02142 SparseMatIterator SparseMat::end()
02143 {
02144     SparseMatIterator it(this);
02145     it.seekEnd();
02146     return it;
02147 }
02148 
02149 inline
02150 SparseMatConstIterator SparseMat::end() const
02151 {
02152     SparseMatConstIterator it(this);
02153     it.seekEnd();
02154     return it;
02155 }
02156 
02157 template<typename _Tp> inline
02158 SparseMatIterator_<_Tp> SparseMat::begin()
02159 {
02160     return SparseMatIterator_<_Tp>(this);
02161 }
02162 
02163 template<typename _Tp> inline
02164 SparseMatConstIterator_<_Tp> SparseMat::begin() const
02165 {
02166     return SparseMatConstIterator_<_Tp>(this);
02167 }
02168 
02169 template<typename _Tp> inline
02170 SparseMatIterator_<_Tp> SparseMat::end()
02171 {
02172     SparseMatIterator_<_Tp> it(this);
02173     it.seekEnd();
02174     return it;
02175 }
02176 
02177 template<typename _Tp> inline
02178 SparseMatConstIterator_<_Tp> SparseMat::end() const
02179 {
02180     SparseMatConstIterator_<_Tp> it(this);
02181     it.seekEnd();
02182     return it;
02183 }
02184 
02185 
02186 
02187 ///////////////////////////// SparseMat_ ////////////////////////////
02188 
02189 template<typename _Tp> inline
02190 SparseMat_<_Tp>::SparseMat_()
02191 {
02192     flags = MAGIC_VAL | DataType<_Tp>::type;
02193 }
02194 
02195 template<typename _Tp> inline
02196 SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
02197     : SparseMat(_dims, _sizes, DataType<_Tp>::type)
02198 {}
02199 
02200 template<typename _Tp> inline
02201 SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
02202 {
02203     if( m.type() == DataType<_Tp>::type )
02204         *this = (const SparseMat_<_Tp>&)m;
02205     else
02206         m.convertTo(*this, DataType<_Tp>::type);
02207 }
02208 
02209 template<typename _Tp> inline
02210 SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
02211 {
02212     this->flags = m.flags;
02213     this->hdr = m.hdr;
02214     if( this->hdr )
02215         CV_XADD(&this->hdr->refcount, 1);
02216 }
02217 
02218 template<typename _Tp> inline
02219 SparseMat_<_Tp>::SparseMat_(const Mat& m)
02220 {
02221     SparseMat sm(m);
02222     *this = sm;
02223 }
02224 
02225 template<typename _Tp> inline
02226 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
02227 {
02228     if( this != &m )
02229     {
02230         if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
02231         release();
02232         flags = m.flags;
02233         hdr = m.hdr;
02234     }
02235     return *this;
02236 }
02237 
02238 template<typename _Tp> inline
02239 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m)
02240 {
02241     if( m.type() == DataType<_Tp>::type )
02242         return (*this = (const SparseMat_<_Tp>&)m);
02243     m.convertTo(*this, DataType<_Tp>::type);
02244     return *this;
02245 }
02246 
02247 template<typename _Tp> inline
02248 SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m)
02249 {
02250     return (*this = SparseMat(m));
02251 }
02252 
02253 template<typename _Tp> inline
02254 SparseMat_<_Tp> SparseMat_<_Tp>::clone() const
02255 {
02256     SparseMat_<_Tp> m;
02257     this->copyTo(m);
02258     return m;
02259 }
02260 
02261 template<typename _Tp> inline
02262 void SparseMat_<_Tp>::create(int _dims, const int* _sizes)
02263 {
02264     SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
02265 }
02266 
02267 template<typename _Tp> inline
02268 int SparseMat_<_Tp>::type() const
02269 {
02270     return DataType<_Tp>::type;
02271 }
02272 
02273 template<typename _Tp> inline
02274 int SparseMat_<_Tp>::depth() const
02275 {
02276     return DataType<_Tp>::depth;
02277 }
02278 
02279 template<typename _Tp> inline
02280 int SparseMat_<_Tp>::channels() const
02281 {
02282     return DataType<_Tp>::channels;
02283 }
02284 
02285 template<typename _Tp> inline
02286 _Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval)
02287 {
02288     return SparseMat::ref<_Tp>(i0, hashval);
02289 }
02290 
02291 template<typename _Tp> inline
02292 _Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
02293 {
02294     return SparseMat::value<_Tp>(i0, hashval);
02295 }
02296 
02297 template<typename _Tp> inline
02298 _Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
02299 {
02300     return SparseMat::ref<_Tp>(i0, i1, hashval);
02301 }
02302 
02303 template<typename _Tp> inline
02304 _Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
02305 {
02306     return SparseMat::value<_Tp>(i0, i1, hashval);
02307 }
02308 
02309 template<typename _Tp> inline
02310 _Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
02311 {
02312     return SparseMat::ref<_Tp>(i0, i1, i2, hashval);
02313 }
02314 
02315 template<typename _Tp> inline
02316 _Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
02317 {
02318     return SparseMat::value<_Tp>(i0, i1, i2, hashval);
02319 }
02320 
02321 template<typename _Tp> inline
02322 _Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
02323 {
02324     return SparseMat::ref<_Tp>(idx, hashval);
02325 }
02326 
02327 template<typename _Tp> inline
02328 _Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
02329 {
02330     return SparseMat::value<_Tp>(idx, hashval);
02331 }
02332 
02333 template<typename _Tp> inline
02334 SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
02335 {
02336     return SparseMatIterator_<_Tp>(this);
02337 }
02338 
02339 template<typename _Tp> inline
02340 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
02341 {
02342     return SparseMatConstIterator_<_Tp>(this);
02343 }
02344 
02345 template<typename _Tp> inline
02346 SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
02347 {
02348     SparseMatIterator_<_Tp> it(this);
02349     it.seekEnd();
02350     return it;
02351 }
02352 
02353 template<typename _Tp> inline
02354 SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
02355 {
02356     SparseMatConstIterator_<_Tp> it(this);
02357     it.seekEnd();
02358     return it;
02359 }
02360 
02361 
02362 
02363 ////////////////////////// MatConstIterator /////////////////////////
02364 
02365 inline
02366 MatConstIterator::MatConstIterator()
02367     : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0)
02368 {}
02369 
02370 inline
02371 MatConstIterator::MatConstIterator(const Mat* _m)
02372     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
02373 {
02374     if( m && m->isContinuous() )
02375     {
02376         sliceStart = m->ptr();
02377         sliceEnd = sliceStart + m->total()*elemSize;
02378     }
02379     seek((const int*)0);
02380 }
02381 
02382 inline
02383 MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
02384     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
02385 {
02386     CV_Assert(m && m->dims <= 2);
02387     if( m->isContinuous() )
02388     {
02389         sliceStart = m->ptr();
02390         sliceEnd = sliceStart + m->total()*elemSize;
02391     }
02392     int idx[] = {_row, _col};
02393     seek(idx);
02394 }
02395 
02396 inline
02397 MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
02398     : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
02399 {
02400     CV_Assert(m && m->dims <= 2);
02401     if( m->isContinuous() )
02402     {
02403         sliceStart = m->ptr();
02404         sliceEnd = sliceStart + m->total()*elemSize;
02405     }
02406     int idx[] = {_pt.y, _pt.x};
02407     seek(idx);
02408 }
02409 
02410 inline
02411 MatConstIterator::MatConstIterator(const MatConstIterator& it)
02412     : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
02413 {}
02414 
02415 inline
02416 MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
02417 {
02418     m = it.m; elemSize = it.elemSize; ptr = it.ptr;
02419     sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
02420     return *this;
02421 }
02422 
02423 inline
02424 const uchar* MatConstIterator::operator *() const
02425 {
02426     return ptr;
02427 }
02428 
02429 inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
02430 {
02431     if( !m || ofs == 0 )
02432         return *this;
02433     ptrdiff_t ofsb = ofs*elemSize;
02434     ptr += ofsb;
02435     if( ptr < sliceStart || sliceEnd <= ptr )
02436     {
02437         ptr -= ofsb;
02438         seek(ofs, true);
02439     }
02440     return *this;
02441 }
02442 
02443 inline
02444 MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
02445 {
02446     return (*this += -ofs);
02447 }
02448 
02449 inline
02450 MatConstIterator& MatConstIterator::operator --()
02451 {
02452     if( m && (ptr -= elemSize) < sliceStart )
02453     {
02454         ptr += elemSize;
02455         seek(-1, true);
02456     }
02457     return *this;
02458 }
02459 
02460 inline
02461 MatConstIterator MatConstIterator::operator --(int)
02462 {
02463     MatConstIterator b = *this;
02464     *this += -1;
02465     return b;
02466 }
02467 
02468 inline
02469 MatConstIterator& MatConstIterator::operator ++()
02470 {
02471     if( m && (ptr += elemSize) >= sliceEnd )
02472     {
02473         ptr -= elemSize;
02474         seek(1, true);
02475     }
02476     return *this;
02477 }
02478 
02479 inline MatConstIterator MatConstIterator::operator ++(int)
02480 {
02481     MatConstIterator b = *this;
02482     *this += 1;
02483     return b;
02484 }
02485 
02486 
02487 static inline
02488 bool operator == (const MatConstIterator& a, const MatConstIterator& b)
02489 {
02490     return a.m == b.m && a.ptr == b.ptr;
02491 }
02492 
02493 static inline
02494 bool operator != (const MatConstIterator& a, const MatConstIterator& b)
02495 {
02496     return !(a == b);
02497 }
02498 
02499 static inline
02500 bool operator < (const MatConstIterator& a, const MatConstIterator& b)
02501 {
02502     return a.ptr < b.ptr;
02503 }
02504 
02505 static inline
02506 bool operator > (const MatConstIterator& a, const MatConstIterator& b)
02507 {
02508     return a.ptr > b.ptr;
02509 }
02510 
02511 static inline
02512 bool operator <= (const MatConstIterator& a, const MatConstIterator& b)
02513 {
02514     return a.ptr <= b.ptr;
02515 }
02516 
02517 static inline
02518 bool operator >= (const MatConstIterator& a, const MatConstIterator& b)
02519 {
02520     return a.ptr >= b.ptr;
02521 }
02522 
02523 static inline
02524 ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
02525 {
02526     if( a.m != b.m )
02527         return ((size_t)(-1) >> 1);
02528     if( a.sliceEnd == b.sliceEnd )
02529         return (b.ptr - a.ptr)/static_cast<ptrdiff_t>(b.elemSize);
02530 
02531     return b.lpos() - a.lpos();
02532 }
02533 
02534 static inline
02535 MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
02536 {
02537     MatConstIterator b = a;
02538     return b += ofs;
02539 }
02540 
02541 static inline
02542 MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
02543 {
02544     MatConstIterator b = a;
02545     return b += ofs;
02546 }
02547 
02548 static inline
02549 MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
02550 {
02551     MatConstIterator b = a;
02552     return b += -ofs;
02553 }
02554 
02555 
02556 inline
02557 const uchar* MatConstIterator::operator [](ptrdiff_t i) const
02558 {
02559     return *(*this + i);
02560 }
02561 
02562 
02563 
02564 ///////////////////////// MatConstIterator_ /////////////////////////
02565 
02566 template<typename _Tp> inline
02567 MatConstIterator_<_Tp>::MatConstIterator_()
02568 {}
02569 
02570 template<typename _Tp> inline
02571 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
02572     : MatConstIterator(_m)
02573 {}
02574 
02575 template<typename _Tp> inline
02576 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
02577     : MatConstIterator(_m, _row, _col)
02578 {}
02579 
02580 template<typename _Tp> inline
02581 MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
02582     : MatConstIterator(_m, _pt)
02583 {}
02584 
02585 template<typename _Tp> inline
02586 MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it)
02587     : MatConstIterator(it)
02588 {}
02589 
02590 template<typename _Tp> inline
02591 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
02592 {
02593     MatConstIterator::operator = (it);
02594     return *this;
02595 }
02596 
02597 template<typename _Tp> inline
02598 const _Tp& MatConstIterator_<_Tp>::operator *() const
02599 {
02600     return *(_Tp*)(this->ptr);
02601 }
02602 
02603 template<typename _Tp> inline
02604 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
02605 {
02606     MatConstIterator::operator += (ofs);
02607     return *this;
02608 }
02609 
02610 template<typename _Tp> inline
02611 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
02612 {
02613     return (*this += -ofs);
02614 }
02615 
02616 template<typename _Tp> inline
02617 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
02618 {
02619     MatConstIterator::operator --();
02620     return *this;
02621 }
02622 
02623 template<typename _Tp> inline
02624 MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
02625 {
02626     MatConstIterator_ b = *this;
02627     MatConstIterator::operator --();
02628     return b;
02629 }
02630 
02631 template<typename _Tp> inline
02632 MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
02633 {
02634     MatConstIterator::operator ++();
02635     return *this;
02636 }
02637 
02638 template<typename _Tp> inline
02639 MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
02640 {
02641     MatConstIterator_ b = *this;
02642     MatConstIterator::operator ++();
02643     return b;
02644 }
02645 
02646 
02647 template<typename _Tp> inline
02648 Point MatConstIterator_<_Tp>::pos() const
02649 {
02650     if( !m )
02651         return Point();
02652     CV_DbgAssert( m->dims <= 2 );
02653     if( m->isContinuous() )
02654     {
02655         ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
02656         int y = (int)(ofs / m->cols);
02657         int x = (int)(ofs - (ptrdiff_t)y * m->cols);
02658         return Point(x, y);
02659     }
02660     else
02661     {
02662         ptrdiff_t ofs = (uchar*)ptr - m->data;
02663         int y = (int)(ofs / m->step);
02664         int x = (int)((ofs - y * m->step)/sizeof(_Tp));
02665         return Point(x, y);
02666     }
02667 }
02668 
02669 
02670 template<typename _Tp> static inline
02671 bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
02672 {
02673     return a.m == b.m && a.ptr == b.ptr;
02674 }
02675 
02676 template<typename _Tp> static inline
02677 bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
02678 {
02679     return a.m != b.m || a.ptr != b.ptr;
02680 }
02681 
02682 template<typename _Tp> static inline
02683 MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
02684 {
02685     MatConstIterator t = (const MatConstIterator&)a + ofs;
02686     return (MatConstIterator_<_Tp>&)t;
02687 }
02688 
02689 template<typename _Tp> static inline
02690 MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
02691 {
02692     MatConstIterator t = (const MatConstIterator&)a + ofs;
02693     return (MatConstIterator_<_Tp>&)t;
02694 }
02695 
02696 template<typename _Tp> static inline
02697 MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
02698 {
02699     MatConstIterator t = (const MatConstIterator&)a - ofs;
02700     return (MatConstIterator_<_Tp>&)t;
02701 }
02702 
02703 template<typename _Tp> inline
02704 const _Tp& MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
02705 {
02706     return *(_Tp*)MatConstIterator::operator [](i);
02707 }
02708 
02709 
02710 
02711 //////////////////////////// MatIterator_ ///////////////////////////
02712 
02713 template<typename _Tp> inline
02714 MatIterator_<_Tp>::MatIterator_()
02715     : MatConstIterator_<_Tp>()
02716 {}
02717 
02718 template<typename _Tp> inline
02719 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
02720     : MatConstIterator_<_Tp>(_m)
02721 {}
02722 
02723 template<typename _Tp> inline
02724 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
02725     : MatConstIterator_<_Tp>(_m, _row, _col)
02726 {}
02727 
02728 template<typename _Tp> inline
02729 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt)
02730     : MatConstIterator_<_Tp>(_m, _pt)
02731 {}
02732 
02733 template<typename _Tp> inline
02734 MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx)
02735     : MatConstIterator_<_Tp>(_m, _idx)
02736 {}
02737 
02738 template<typename _Tp> inline
02739 MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
02740     : MatConstIterator_<_Tp>(it)
02741 {}
02742 
02743 template<typename _Tp> inline
02744 MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
02745 {
02746     MatConstIterator::operator = (it);
02747     return *this;
02748 }
02749 
02750 template<typename _Tp> inline
02751 _Tp& MatIterator_<_Tp>::operator *() const
02752 {
02753     return *(_Tp*)(this->ptr);
02754 }
02755 
02756 template<typename _Tp> inline
02757 MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
02758 {
02759     MatConstIterator::operator += (ofs);
02760     return *this;
02761 }
02762 
02763 template<typename _Tp> inline
02764 MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
02765 {
02766     MatConstIterator::operator += (-ofs);
02767     return *this;
02768 }
02769 
02770 template<typename _Tp> inline
02771 MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
02772 {
02773     MatConstIterator::operator --();
02774     return *this;
02775 }
02776 
02777 template<typename _Tp> inline
02778 MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
02779 {
02780     MatIterator_ b = *this;
02781     MatConstIterator::operator --();
02782     return b;
02783 }
02784 
02785 template<typename _Tp> inline
02786 MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
02787 {
02788     MatConstIterator::operator ++();
02789     return *this;
02790 }
02791 
02792 template<typename _Tp> inline
02793 MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
02794 {
02795     MatIterator_ b = *this;
02796     MatConstIterator::operator ++();
02797     return b;
02798 }
02799 
02800 template<typename _Tp> inline
02801 _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
02802 {
02803     return *(*this + i);
02804 }
02805 
02806 
02807 template<typename _Tp> static inline
02808 bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
02809 {
02810     return a.m == b.m && a.ptr == b.ptr;
02811 }
02812 
02813 template<typename _Tp> static inline
02814 bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
02815 {
02816     return a.m != b.m || a.ptr != b.ptr;
02817 }
02818 
02819 template<typename _Tp> static inline
02820 MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
02821 {
02822     MatConstIterator t = (const MatConstIterator&)a + ofs;
02823     return (MatIterator_<_Tp>&)t;
02824 }
02825 
02826 template<typename _Tp> static inline
02827 MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
02828 {
02829     MatConstIterator t = (const MatConstIterator&)a + ofs;
02830     return (MatIterator_<_Tp>&)t;
02831 }
02832 
02833 template<typename _Tp> static inline
02834 MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
02835 {
02836     MatConstIterator t = (const MatConstIterator&)a - ofs;
02837     return (MatIterator_<_Tp>&)t;
02838 }
02839 
02840 
02841 
02842 /////////////////////// SparseMatConstIterator //////////////////////
02843 
02844 inline
02845 SparseMatConstIterator::SparseMatConstIterator()
02846     : m(0), hashidx(0), ptr(0)
02847 {}
02848 
02849 inline
02850 SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
02851     : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
02852 {}
02853 
02854 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
02855 {
02856     if( this != &it )
02857     {
02858         m = it.m;
02859         hashidx = it.hashidx;
02860         ptr = it.ptr;
02861     }
02862     return *this;
02863 }
02864 
02865 template<typename _Tp> inline
02866 const _Tp& SparseMatConstIterator::value() const
02867 {
02868     return *(const _Tp*)ptr;
02869 }
02870 
02871 inline
02872 const SparseMat::Node* SparseMatConstIterator::node() const
02873 {
02874     return (ptr && m && m->hdr) ? (const SparseMat::Node*)(const void*)(ptr - m->hdr->valueOffset) : 0;
02875 }
02876 
02877 inline
02878 SparseMatConstIterator SparseMatConstIterator::operator ++(int)
02879 {
02880     SparseMatConstIterator it = *this;
02881     ++*this;
02882     return it;
02883 }
02884 
02885 inline
02886 void SparseMatConstIterator::seekEnd()
02887 {
02888     if( m && m->hdr )
02889     {
02890         hashidx = m->hdr->hashtab.size();
02891         ptr = 0;
02892     }
02893 }
02894 
02895 
02896 static inline
02897 bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
02898 {
02899     return it1.m == it2.m && it1.ptr == it2.ptr;
02900 }
02901 
02902 static inline
02903 bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
02904 {
02905     return !(it1 == it2);
02906 }
02907 
02908 
02909 
02910 ///////////////////////// SparseMatIterator /////////////////////////
02911 
02912 inline
02913 SparseMatIterator::SparseMatIterator()
02914 {}
02915 
02916 inline
02917 SparseMatIterator::SparseMatIterator(SparseMat* _m)
02918     : SparseMatConstIterator(_m)
02919 {}
02920 
02921 inline
02922 SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
02923     : SparseMatConstIterator(it)
02924 {}
02925 
02926 inline
02927 SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
02928 {
02929     (SparseMatConstIterator&)*this = it;
02930     return *this;
02931 }
02932 
02933 template<typename _Tp> inline
02934 _Tp& SparseMatIterator::value() const
02935 {
02936     return *(_Tp*)ptr;
02937 }
02938 
02939 inline
02940 SparseMat::Node* SparseMatIterator::node() const
02941 {
02942     return (SparseMat::Node*)SparseMatConstIterator::node();
02943 }
02944 
02945 inline
02946 SparseMatIterator& SparseMatIterator::operator ++()
02947 {
02948     SparseMatConstIterator::operator ++();
02949     return *this;
02950 }
02951 
02952 inline
02953 SparseMatIterator SparseMatIterator::operator ++(int)
02954 {
02955     SparseMatIterator it = *this;
02956     ++*this;
02957     return it;
02958 }
02959 
02960 
02961 
02962 ////////////////////// SparseMatConstIterator_ //////////////////////
02963 
02964 template<typename _Tp> inline
02965 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
02966 {}
02967 
02968 template<typename _Tp> inline
02969 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
02970     : SparseMatConstIterator(_m)
02971 {}
02972 
02973 template<typename _Tp> inline
02974 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
02975     : SparseMatConstIterator(_m)
02976 {
02977     CV_Assert( _m->type() == DataType<_Tp>::type );
02978 }
02979 
02980 template<typename _Tp> inline
02981 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
02982     : SparseMatConstIterator(it)
02983 {}
02984 
02985 template<typename _Tp> inline
02986 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
02987 {
02988     return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
02989          (*reinterpret_cast<SparseMatConstIterator*>(this) =
02990            reinterpret_cast<const SparseMatConstIterator&>(it));
02991 }
02992 
02993 template<typename _Tp> inline
02994 const _Tp& SparseMatConstIterator_<_Tp>::operator *() const
02995 {
02996     return *(const _Tp*)this->ptr;
02997 }
02998 
02999 template<typename _Tp> inline
03000 SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
03001 {
03002     SparseMatConstIterator::operator ++();
03003     return *this;
03004 }
03005 
03006 template<typename _Tp> inline
03007 SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
03008 {
03009     SparseMatConstIterator_<_Tp> it = *this;
03010     SparseMatConstIterator::operator ++();
03011     return it;
03012 }
03013 
03014 
03015 
03016 ///////////////////////// SparseMatIterator_ ////////////////////////
03017 
03018 template<typename _Tp> inline
03019 SparseMatIterator_<_Tp>::SparseMatIterator_()
03020 {}
03021 
03022 template<typename _Tp> inline
03023 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
03024     : SparseMatConstIterator_<_Tp>(_m)
03025 {}
03026 
03027 template<typename _Tp> inline
03028 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
03029     : SparseMatConstIterator_<_Tp>(_m)
03030 {}
03031 
03032 template<typename _Tp> inline
03033 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
03034     : SparseMatConstIterator_<_Tp>(it)
03035 {}
03036 
03037 template<typename _Tp> inline
03038 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
03039 {
03040     return reinterpret_cast<SparseMatIterator_<_Tp>&>
03041          (*reinterpret_cast<SparseMatConstIterator*>(this) =
03042            reinterpret_cast<const SparseMatConstIterator&>(it));
03043 }
03044 
03045 template<typename _Tp> inline
03046 _Tp& SparseMatIterator_<_Tp>::operator *() const
03047 {
03048     return *(_Tp*)this->ptr;
03049 }
03050 
03051 template<typename _Tp> inline
03052 SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
03053 {
03054     SparseMatConstIterator::operator ++();
03055     return *this;
03056 }
03057 
03058 template<typename _Tp> inline
03059 SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
03060 {
03061     SparseMatIterator_<_Tp> it = *this;
03062     SparseMatConstIterator::operator ++();
03063     return it;
03064 }
03065 
03066 
03067 
03068 //////////////////////// MatCommaInitializer_ ///////////////////////
03069 
03070 template<typename _Tp> inline
03071 MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m)
03072     : it(_m)
03073 {}
03074 
03075 template<typename _Tp> template<typename T2> inline
03076 MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v)
03077 {
03078     CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
03079     *this->it = _Tp(v);
03080     ++this->it;
03081     return *this;
03082 }
03083 
03084 template<typename _Tp> inline
03085 MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
03086 {
03087     CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
03088     return Mat_<_Tp>(*this->it.m);
03089 }
03090 
03091 
03092 template<typename _Tp, typename T2> static inline
03093 MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val)
03094 {
03095     MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
03096     return (commaInitializer, val);
03097 }
03098 
03099 
03100 
03101 ///////////////////////// Matrix Expressions ////////////////////////
03102 
03103 inline
03104 Mat& Mat::operator = (const MatExpr& e)
03105 {
03106     e.op->assign(e, *this);
03107     return *this;
03108 }
03109 
03110 template<typename _Tp> inline
03111 Mat_<_Tp>::Mat_(const MatExpr& e)
03112 {
03113     e.op->assign(e, *this, DataType<_Tp>::type);
03114 }
03115 
03116 template<typename _Tp> inline
03117 Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
03118 {
03119     e.op->assign(e, *this, DataType<_Tp>::type);
03120     return *this;
03121 }
03122 
03123 template<typename _Tp> inline
03124 MatExpr Mat_<_Tp>::zeros(int rows, int cols)
03125 {
03126     return Mat::zeros(rows, cols, DataType<_Tp>::type);
03127 }
03128 
03129 template<typename _Tp> inline
03130 MatExpr Mat_<_Tp>::zeros(Size sz)
03131 {
03132     return Mat::zeros(sz, DataType<_Tp>::type);
03133 }
03134 
03135 template<typename _Tp> inline
03136 MatExpr Mat_<_Tp>::ones(int rows, int cols)
03137 {
03138     return Mat::ones(rows, cols, DataType<_Tp>::type);
03139 }
03140 
03141 template<typename _Tp> inline
03142 MatExpr Mat_<_Tp>::ones(Size sz)
03143 {
03144     return Mat::ones(sz, DataType<_Tp>::type);
03145 }
03146 
03147 template<typename _Tp> inline
03148 MatExpr Mat_<_Tp>::eye(int rows, int cols)
03149 {
03150     return Mat::eye(rows, cols, DataType<_Tp>::type);
03151 }
03152 
03153 template<typename _Tp> inline
03154 MatExpr Mat_<_Tp>::eye(Size sz)
03155 {
03156     return Mat::eye(sz, DataType<_Tp>::type);
03157 }
03158 
03159 inline
03160 MatExpr::MatExpr()
03161     : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s()
03162 {}
03163 
03164 inline
03165 MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b,
03166                  const Mat& _c, double _alpha, double _beta, const Scalar& _s)
03167     : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s)
03168 {}
03169 
03170 inline
03171 MatExpr::operator Mat() const
03172 {
03173     Mat m;
03174     op->assign(*this, m);
03175     return m;
03176 }
03177 
03178 template<typename _Tp> inline
03179 MatExpr::operator Mat_<_Tp>() const
03180 {
03181     Mat_<_Tp> m;
03182     op->assign(*this, m, DataType<_Tp>::type);
03183     return m;
03184 }
03185 
03186 
03187 template<typename _Tp> static inline
03188 MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
03189 {
03190     return cv::min((const Mat&)a, (const Mat&)b);
03191 }
03192 
03193 template<typename _Tp> static inline
03194 MatExpr min(const Mat_<_Tp>& a, double s)
03195 {
03196     return cv::min((const Mat&)a, s);
03197 }
03198 
03199 template<typename _Tp> static inline
03200 MatExpr min(double s, const Mat_<_Tp>& a)
03201 {
03202     return cv::min((const Mat&)a, s);
03203 }
03204 
03205 template<typename _Tp> static inline
03206 MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
03207 {
03208     return cv::max((const Mat&)a, (const Mat&)b);
03209 }
03210 
03211 template<typename _Tp> static inline
03212 MatExpr max(const Mat_<_Tp>& a, double s)
03213 {
03214     return cv::max((const Mat&)a, s);
03215 }
03216 
03217 template<typename _Tp> static inline
03218 MatExpr max(double s, const Mat_<_Tp>& a)
03219 {
03220     return cv::max((const Mat&)a, s);
03221 }
03222 
03223 template<typename _Tp> static inline
03224 MatExpr abs(const Mat_<_Tp>& m)
03225 {
03226     return cv::abs((const Mat&)m);
03227 }
03228 
03229 
03230 static inline
03231 Mat& operator += (Mat& a, const MatExpr& b)
03232 {
03233     b.op->augAssignAdd(b, a);
03234     return a;
03235 }
03236 
03237 static inline
03238 const Mat& operator += (const Mat& a, const MatExpr& b)
03239 {
03240     b.op->augAssignAdd(b, (Mat&)a);
03241     return a;
03242 }
03243 
03244 template<typename _Tp> static inline
03245 Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b)
03246 {
03247     b.op->augAssignAdd(b, a);
03248     return a;
03249 }
03250 
03251 template<typename _Tp> static inline
03252 const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
03253 {
03254     b.op->augAssignAdd(b, (Mat&)a);
03255     return a;
03256 }
03257 
03258 static inline
03259 Mat& operator -= (Mat& a, const MatExpr& b)
03260 {
03261     b.op->augAssignSubtract(b, a);
03262     return a;
03263 }
03264 
03265 static inline
03266 const Mat& operator -= (const Mat& a, const MatExpr& b)
03267 {
03268     b.op->augAssignSubtract(b, (Mat&)a);
03269     return a;
03270 }
03271 
03272 template<typename _Tp> static inline
03273 Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b)
03274 {
03275     b.op->augAssignSubtract(b, a);
03276     return a;
03277 }
03278 
03279 template<typename _Tp> static inline
03280 const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
03281 {
03282     b.op->augAssignSubtract(b, (Mat&)a);
03283     return a;
03284 }
03285 
03286 static inline
03287 Mat& operator *= (Mat& a, const MatExpr& b)
03288 {
03289     b.op->augAssignMultiply(b, a);
03290     return a;
03291 }
03292 
03293 static inline
03294 const Mat& operator *= (const Mat& a, const MatExpr& b)
03295 {
03296     b.op->augAssignMultiply(b, (Mat&)a);
03297     return a;
03298 }
03299 
03300 template<typename _Tp> static inline
03301 Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b)
03302 {
03303     b.op->augAssignMultiply(b, a);
03304     return a;
03305 }
03306 
03307 template<typename _Tp> static inline
03308 const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
03309 {
03310     b.op->augAssignMultiply(b, (Mat&)a);
03311     return a;
03312 }
03313 
03314 static inline
03315 Mat& operator /= (Mat& a, const MatExpr& b)
03316 {
03317     b.op->augAssignDivide(b, a);
03318     return a;
03319 }
03320 
03321 static inline
03322 const Mat& operator /= (const Mat& a, const MatExpr& b)
03323 {
03324     b.op->augAssignDivide(b, (Mat&)a);
03325     return a;
03326 }
03327 
03328 template<typename _Tp> static inline
03329 Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b)
03330 {
03331     b.op->augAssignDivide(b, a);
03332     return a;
03333 }
03334 
03335 template<typename _Tp> static inline
03336 const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
03337 {
03338     b.op->augAssignDivide(b, (Mat&)a);
03339     return a;
03340 }
03341 
03342 
03343 //////////////////////////////// UMat ////////////////////////////////
03344 
03345 inline
03346 UMat::UMat(UMatUsageFlags _usageFlags)
03347 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03348 {}
03349 
03350 inline
03351 UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
03352 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03353 {
03354     create(_rows, _cols, _type);
03355 }
03356 
03357 inline
03358 UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
03359 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03360 {
03361     create(_rows, _cols, _type);
03362     *this = _s;
03363 }
03364 
03365 inline
03366 UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
03367 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03368 {
03369     create( _sz.height, _sz.width, _type );
03370 }
03371 
03372 inline
03373 UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
03374 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03375 {
03376     create(_sz.height, _sz.width, _type);
03377     *this = _s;
03378 }
03379 
03380 inline
03381 UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
03382 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03383 {
03384     create(_dims, _sz, _type);
03385 }
03386 
03387 inline
03388 UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
03389 : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
03390 {
03391     create(_dims, _sz, _type);
03392     *this = _s;
03393 }
03394 
03395 inline
03396 UMat::UMat(const UMat& m)
03397 : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
03398   usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
03399 {
03400     addref();
03401     if( m.dims <= 2 )
03402     {
03403         step[0] = m.step[0]; step[1] = m.step[1];
03404     }
03405     else
03406     {
03407         dims = 0;
03408         copySize(m);
03409     }
03410 }
03411 
03412 
03413 template<typename _Tp> inline
03414 UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
03415 : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
03416 cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
03417 {
03418     if(vec.empty())
03419         return;
03420     if( !copyData )
03421     {
03422         // !!!TODO!!!
03423         CV_Error(Error::StsNotImplemented, "");
03424     }
03425     else
03426         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
03427 }
03428 
03429 
03430 inline
03431 UMat& UMat::operator = (const UMat& m)
03432 {
03433     if( this != &m )
03434     {
03435         const_cast<UMat&>(m).addref();
03436         release();
03437         flags  = m.flags;
03438         if( dims <= 2 && m.dims <= 2 )
03439         {
03440             dims = m.dims;
03441             rows = m.rows;
03442             cols = m.cols;
03443             step[0] = m.step[0];
03444             step[1] = m.step[1];
03445         }
03446         else
03447             copySize(m);
03448         allocator = m.allocator;
03449         if (usageFlags == USAGE_DEFAULT)
03450             usageFlags = m.usageFlags;
03451         u = m.u;
03452         offset = m.offset;
03453     }
03454     return *this;
03455 }
03456 
03457 inline
03458 UMat UMat::row(int y) const
03459 {
03460     return UMat(*this, Range(y, y + 1), Range::all());
03461 }
03462 
03463 inline
03464 UMat UMat::col(int x) const
03465 {
03466     return UMat(*this, Range::all(), Range(x, x + 1));
03467 }
03468 
03469 inline
03470 UMat UMat::rowRange(int startrow, int endrow) const
03471 {
03472     return UMat(*this, Range(startrow, endrow), Range::all());
03473 }
03474 
03475 inline
03476 UMat UMat::rowRange(const Range& r) const
03477 {
03478     return UMat(*this, r, Range::all());
03479 }
03480 
03481 inline
03482 UMat UMat::colRange(int startcol, int endcol) const
03483 {
03484     return UMat(*this, Range::all(), Range(startcol, endcol));
03485 }
03486 
03487 inline
03488 UMat UMat::colRange(const Range& r) const
03489 {
03490     return UMat(*this, Range::all(), r);
03491 }
03492 
03493 inline
03494 UMat UMat::clone() const
03495 {
03496     UMat m;
03497     copyTo(m);
03498     return m;
03499 }
03500 
03501 inline
03502 void UMat::assignTo( UMat& m, int _type ) const
03503 {
03504     if( _type < 0 )
03505         m = *this;
03506     else
03507         convertTo(m, _type);
03508 }
03509 
03510 inline
03511 void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
03512 {
03513     _type &= TYPE_MASK;
03514     if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u )
03515         return;
03516     int sz[] = {_rows, _cols};
03517     create(2, sz, _type, _usageFlags);
03518 }
03519 
03520 inline
03521 void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
03522 {
03523     create(_sz.height, _sz.width, _type, _usageFlags);
03524 }
03525 
03526 inline
03527 void UMat::addref()
03528 {
03529     if( u )
03530         CV_XADD(&(u->urefcount), 1);
03531 }
03532 
03533 inline void UMat::release()
03534 {
03535     if( u && CV_XADD(&(u->urefcount), -1) == 1 )
03536         deallocate();
03537     for(int i = 0; i < dims; i++)
03538         size.p[i] = 0;
03539     u = 0;
03540 }
03541 
03542 inline
03543 UMat UMat::operator()( Range _rowRange, Range _colRange ) const
03544 {
03545     return UMat(*this, _rowRange, _colRange);
03546 }
03547 
03548 inline
03549 UMat UMat::operator()( const Rect& roi ) const
03550 {
03551     return UMat(*this, roi);
03552 }
03553 
03554 inline
03555 UMat UMat::operator()(const Range* ranges) const
03556 {
03557     return UMat(*this, ranges);
03558 }
03559 
03560 inline
03561 UMat UMat::operator()(const std::vector<Range>& ranges) const
03562 {
03563     return UMat(*this, ranges);
03564 }
03565 
03566 inline
03567 bool UMat::isContinuous() const
03568 {
03569     return (flags  & CONTINUOUS_FLAG) != 0;
03570 }
03571 
03572 inline
03573 bool UMat::isSubmatrix() const
03574 {
03575     return (flags  & SUBMATRIX_FLAG) != 0;
03576 }
03577 
03578 inline
03579 size_t UMat::elemSize() const
03580 {
03581     return dims > 0 ? step.p[dims - 1] : 0;
03582 }
03583 
03584 inline
03585 size_t UMat::elemSize1() const
03586 {
03587     return CV_ELEM_SIZE1(flags );
03588 }
03589 
03590 inline
03591 int UMat::type() const
03592 {
03593     return CV_MAT_TYPE(flags );
03594 }
03595 
03596 inline
03597 int UMat::depth() const
03598 {
03599     return CV_MAT_DEPTH(flags );
03600 }
03601 
03602 inline
03603 int UMat::channels() const
03604 {
03605     return CV_MAT_CN(flags );
03606 }
03607 
03608 inline
03609 size_t UMat::step1(int i) const
03610 {
03611     return step.p[i] / elemSize1();
03612 }
03613 
03614 inline
03615 bool UMat::empty() const
03616 {
03617     return u == 0 || total() == 0;
03618 }
03619 
03620 inline
03621 size_t UMat::total() const
03622 {
03623     if( dims <= 2 )
03624         return (size_t)rows * cols;
03625     size_t p = 1;
03626     for( int i = 0; i < dims; i++ )
03627         p *= size[i];
03628     return p;
03629 }
03630 
03631 #ifdef CV_CXX_MOVE_SEMANTICS
03632 
03633 inline
03634 UMat::UMat(UMat&& m)
03635 : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
03636   usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
03637 {
03638     if (m.dims <= 2)  // move new step/size info
03639     {
03640         step[0] = m.step[0];
03641         step[1] = m.step[1];
03642     }
03643     else
03644     {
03645         CV_DbgAssert(m.step.p != m.step.buf);
03646         step.p = m.step.p;
03647         size.p = m.size.p;
03648         m.step.p = m.step.buf;
03649         m.size.p = &m.rows;
03650     }
03651     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
03652     m.allocator = NULL;
03653     m.u = NULL;
03654     m.offset = 0;
03655 }
03656 
03657 inline
03658 UMat& UMat::operator = (UMat&& m)
03659 {
03660     if (this == &m)
03661       return *this;
03662     release();
03663     flags  = m.flags; dims = m.dims; rows = m.rows; cols = m.cols;
03664     allocator = m.allocator; usageFlags = m.usageFlags;
03665     u = m.u;
03666     offset = m.offset;
03667     if (step.p != step.buf) // release self step/size
03668     {
03669         fastFree(step.p);
03670         step.p = step.buf;
03671         size.p = &rows;
03672     }
03673     if (m.dims <= 2) // move new step/size info
03674     {
03675         step[0] = m.step[0];
03676         step[1] = m.step[1];
03677     }
03678     else
03679     {
03680         CV_DbgAssert(m.step.p != m.step.buf);
03681         step.p = m.step.p;
03682         size.p = m.size.p;
03683         m.step.p = m.step.buf;
03684         m.size.p = &m.rows;
03685     }
03686     m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
03687     m.allocator = NULL;
03688     m.u = NULL;
03689     m.offset = 0;
03690     return *this;
03691 }
03692 
03693 #endif
03694 
03695 
03696 inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
03697 inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
03698 inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }
03699 inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; }
03700 inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; }
03701 inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; }
03702 
03703 inline void UMatData::markDeviceMemMapped(bool flag)
03704 {
03705   if(flag)
03706     flags |= DEVICE_MEM_MAPPED;
03707   else
03708     flags &= ~DEVICE_MEM_MAPPED;
03709 }
03710 
03711 inline void UMatData::markHostCopyObsolete(bool flag)
03712 {
03713     if(flag)
03714         flags |= HOST_COPY_OBSOLETE;
03715     else
03716         flags &= ~HOST_COPY_OBSOLETE;
03717 }
03718 inline void UMatData::markDeviceCopyObsolete(bool flag)
03719 {
03720     if(flag)
03721         flags |= DEVICE_COPY_OBSOLETE;
03722     else
03723         flags &= ~DEVICE_COPY_OBSOLETE;
03724 }
03725 
03726 inline UMatDataAutoLock::UMatDataAutoLock(UMatData* _u) : u(_u) { u->lock(); }
03727 inline UMatDataAutoLock::~UMatDataAutoLock() { u->unlock(); }
03728 
03729 //! @endcond
03730 
03731 } //cv
03732 
03733 #endif